[PYTHON] Argument implementation (with code) in your own language

It's time for your own language.

Hi, this is dangomushi who wants to try M1 on a new Mac. This time, I implemented "scope" in my own language. Also, like machine language, if you read it yourself and don't understand it, you won't have any children, so we also emphasized readability. This article is a continuation of the previous Hello World in my own language. If you haven't seen it yet, please take a look.

How did you do it

As mentioned above, we have added arguments. The gimmick is simple. The dictionary is divided into the one for variables and the one for functions, and the one for variables is only reset when the function is called.

Sample code

First of all, the code that "converts the written file into virtual machine language".

main.py


#usr/bin/env python3

import sys, os, re, glob


#TODO:Main /kernel
class Main:
    def __init__(self):
        pass

    #TODO:data =All data
    def run(self, vald, lis):
        valts = []
        i = 2
        case = 0
        arg = ""

        name = sys.argv[1]
        file = open(name, encoding="utf-8")
        self.conf = open(name.split(".")[0]+".las", "a", encoding="utf_8")
        data = file.readlines()
        file.close()

        valts.append(data)
        valts = [e for inner_list in valts for e in inner_list]
        self.start(valts, i)

    def start(self, valts, i):
        for data in valts:
            data = data.replace("\n", "")

            if data.endswith("{") and data.startswith("fn"):
                data1 = data.split(" ")[1].replace(")", "").split("(")[0]
                arg = data.split("(")[1].split(")")[0]

                if data1 == "main():":
                    pass

                else:
                    data = data1.replace("{", "") + "({}):".format(arg)

                self.conf.write("\n{}".format(data))

            else:
                data = data.strip("    ").replace(";", "")
                data = data.split("//")[0]

                if data.startswith("if"):
                    if data.split(" ")[2] == "more_than":
                        self.conf.write("\n    jne {}, {}, _L{}".format(data.split(" ")[1], data.split(" ")[3],i))
                    
                    elif data.split(" ")[2] == "less_than":
                        self.conf.write("\n    ja {}, {}, _L{}".format(data.split(" ")[1], data.split(" ")[3],i))
                    
                    self.conf.write("\n    ret")
                    self.conf.write("\n_L{}:".format(i))
                    i += 1

                else:
                    if data.startswith("ret"):
                        rfun = data.split(" ")[1]
                        
                        try:
                            rarg = data.split(" ")[2]
                            self.conf.write("\n    mov {}, {}".format(rfun, rarg))
                        
                        except IndexError:
                            pass

                        self.conf.write("\n    ret")

                    elif data.startswith("use"):
                        try:
                            self.conf.write("\n    call {}{}".format(data.split(" ")[1].split("(")[0]+"(", data.split("(")[1]))
                        except KeyError:
                            self.conf.write("\n    call {}{}".format(data.split(" ")[1].split("(")[0]))

                        
                    elif "open" in data:
                            self.conf.write("\n    open:{}".format(data.split(":")[1]))#, data.split("=")[1]))

                    elif "make" in data:
                            self.conf.write("\n    {}, make".format(data.split(" ")[1]))
                        
                    elif data.endswith("close"):
                            self.conf.write("\n    {}, close".format(data.split(" ")[0]))
                        
                    elif "write" in data:
                            try:
                                self.conf.write("\n    write:{}".format(vald["".join(data.split(":")[1:])]))
                            except KeyError:
                                self.conf.write("\n    write:{}".format("".join(data.split(":")[1:])))


                    elif data.startswith("consolp:"):
                        self.conf.write("\n    msg {}".format(data.split("consolp:")[1]))

                    elif data.startswith("int"):
                        if "," in data:
                            datav = data.split("=")[0].split("int ")[1].replace(" ", "").split(",")
                            datanum = int(data.split("=")[1].replace(" ", "").split(","))
                            valdl = dict(zip(datav, datanum))
                            for datav in datav:
                                self.conf.write("\n    mov {}, {}".format(datav, valdl[datav]))
                        else:
                            datav = data.split(" ")[1]
                            datanum = int(data.split(" ")[3])
                            self.conf.write("\n    mov {}, {}".format(datav, datanum))
                    
                    elif data.startswith("str"):
                        if "," in data:
                            datav = data.split("=")[0].split("int ")[1].replace(" ", "").split(",")
                            datanum = data.split("=")[1].replace(" ", "").split(",")
                            valdl2 = dict(zip(datav, datanum))
                            for datav in datav:
                                self.conf.write("\n    mov {}, {}".format(datav, valdl[datav]))
                        else:
                            datav = data.split(" ")[1]
                            datanum = data.split(" ")[3]
                            self.conf.write("\n    mov {}, {}".format(datav, datanum))
                        try:
                            valdl.update(valdl2)
                        
                        except UnboundLocalError:
                            pass
                    #elif data.startswith("}"):
                    #    self.conf.write("\n    mov end")

                    elif data.startswith("while"):
                        c = data.split(" ")[1]
                        wc = 0
                        cou = 0
                        self.conf.write("\n    jmp _L{}, {}".format(i, c))
                        self.conf.write("\n    ret")
                        self.conf.write("\n_L{}, {}:".format(i, c))
                        wc = 2
                        if ">" in data or "<" in data:
                            self.conf.write("\n    cmp {}, {}".format(c, cou))
                            self.conf.write("\n    add {}, {}, 1".format("cou", "cou"))
                            wc = 1
                        i += 1

                    # add x, 10, 2
                    elif data.startswith("~") is False:
                        if "+" in data:
                            data = data.replace(" ", "")#.split(":")[1]
                            val = data.split("=")[0]
                            data2 = data.split("=")[1].split("+")[0]
                            data3 = data.split("=")[1].split("+")[1]
                            self.conf.write("\n    add {}, {}, {}".format(val, data2, data3))

                        elif "-" in data:
                            data = data.replace(" ", "")
                            val = data.split("=")[0]
                            data2 = data.split("=")[1].split("-")[0]
                            data3 = data.split("=")[1].split("-")[1]
                            self.conf.write("\n    sub {}, {}, {}".format(val, data2, data3))

                        elif "*" in data:
                            data = data.replace(" ", "")
                            val = data.split("=")[0]
                            data2 = data.split("=")[1].split("*")[0]
                            data3 = data.split("=")[1].split("*")[1]
                            self.conf.write("\n    mul {}, {}, {}".format(val, data2, data3))

                        elif "/" in data:
                            data = data.replace(" ", "")
                            val = data.split("=")[0]
                            data2 = data.split("=")[1].split("/")[0]
                            data3 = data.split("=")[1].split("/")[1]
                            self.conf.write("\n    div {}, {}, {}".format(val, data2, data3))
        self.conf.write("\ncall main()")

if __name__ == '__main__':
    file_list = glob.glob("*las")
    for file in file_list:
        os.remove(file)
    f = open(sys.argv[1].split(".")[0]+".las", "x", encoding="utf_8")
    f.close()
    vald = {}
    lis = []
    omega = Main()
    omega.run(vald, lis)
    

The following code is short because I wanted to make it as fast as possible at runtime. I would like to say that, in fact, this code has become longer. That's because there is dictionary processing. Next, launch the virtual machine and execute the machine language Part code.

runn.py


import sys

class Run:
    def __init__(self):
        self.wc = 0

    def run(self, i):
        file = open(sys.argv[1], encoding="utf-8")
        data2 = file.readlines()

        dick = {}
        lis = []
        lisf = []
        lisw = []
        wc = 0
        ji = 0
        vald = {}

        for data in data2:
            data = data.replace("\n", "")
            if data.startswith("    "):
                if wc == 1:
                    lisw.append(data.replace("    ", "") + ";")
                else:
                    lis.append("{};".format(data.replace("    ", "")))
            
            elif data.startswith("    ret"):
                break

            elif data.endswith(":"):
                if data.startswith("_"):
                    try:
                    
                        try:
                            ji = int(data.split(" ")[1].replace(":", ""))
                    
                        except IndexError:
                            pass
                    
                    except ValueError:
                        ji = "True"

                func = data.replace(":", "")
                lisf.append(func)

            elif data.startswith("call"):
                dick2 = dict(zip(lisf, "".join(lis).split("ret;")))
                dick.update(dick2)
                self.Main(dick, vald, data.split(" ")[1], i, ji)

        file.close()
    
    def Main(self, dick, vald, f, i, ji):
        lis = str(dick[f]).split(";")
        lisf = f
        for data in lis:
            data = data.split(";")
            data = [a for a in data if a != '']

            for data in data:
                if data.endswith(")") and data.startswith("call") is False:
                    val = data.split("msg ")[1].split("(")[0]+"("+data.split("(")[1]
                    if '"' in val:
                        print(val.replace('"', ""))

                    else:
                        self.Main(dick, vald, val, i, ji)
                        print(dick[val])

                else:
                    data = str(data)
                    if data.startswith("mov"):
                        if data.split(" ")[1] == "end":
                            break
                        else:
                            val = data.split(", ")[1]
                            arg = data.split(", ")[0].split(" ")[1]
                            vald[arg] = val

                    elif data.startswith("strf"):
                        dick[data.split(", ")[0].split(" ")[1]] = data.split(", ")[1]

                    elif "open" in data:
                        name = "".join(data.split(":")[1:]).replace(" ", "").split(",")
                        opf = open(dick[name[0]], name[1], encoding=name[2])
                        
                    elif data.endswith("close"):
                        opf.close()
                        
                    elif data.endswith("make"):
                        file = data.split(" ")[1]
                        with open(file.replace(",", ""), "w", encoding="utf_8") as opf:
                            pass
                    
                    elif "write" in data:
                        opf.write("".join(data.split(":")[1]))

                    elif data.startswith("call"):
                        func = data.split(" ")[1]
                        if func.endswith("()"):
                            pass
                        else:
                            argn = func.split("(")[1].replace(")", "")
                            arg = vald[argn]
                            vald = {}
                            vald[argn] = arg
                        self.Main(dick, vald, func, i, ji)

                    elif data.startswith("msg"):
                        if ' "' in data.split("msg")[1]:
                            print(data.split("msg")[1].replace(' "', "").replace('"', ""))
                        else:
                            dick2 = {}
                            try:
                                dick2["1"] = vald[data.split("msg ")[1]]
                            except KeyError:
                                print("Variable name'{}'Cannot be found. Finished.".format(data.split("msg ")[1]))
                                sys.exit()
                            self.Main(dick2, vald, "1", i, ji)
                            if str(vald[data.split("msg ")[1]]).startswith("open"):
                                pass
                            else:
                                print(vald[data.split("msg ")[1]])

                    elif data.startswith("add"):
                        formula = data.split(",")[1].replace(" ", "")
                        formula2 = data.split(",")[2].replace(" ", "")
                        val = data.split(",")[0].split(" ")[1]
                        try:
                            vald[val] = int(vald[formula]) + int(vald[formula2])

                        except KeyError:

                            try:
                                vald[val] = int(vald[formula2]) + int(formula)
                            except KeyError:
                                vald[val] = int(formula) + int(formula2)

                    elif data.startswith("sub"):
                        formula = data.split(",")[1].replace(" ", "")
                        formula2 = data.split(",")[2].replace(" ", "")
                        val = data.split(",")[0].split(" ")[1]
                        try:
                            vald[val] = int(vald[formula]) - int(vald[formula2])

                        except KeyError:

                            try:
                                vald[val] = int(vald[formula]) - int(formula2)

                            except KeyError:
                                vald[val] = int(formula) - int(formula2)

                    elif data.startswith("mul"):
                        formula = data.split(",")[1].replace(" ", "")
                        formula2 = data.split(",")[2].replace(" ", "")
                        val = data.split(",")[0].split(" ")[1]
                        try:
                            vald[val] = int(vald[formula]) * int(vald[formula2])

                        except KeyError:

                            try:
                                vald[val] = int(formula) * int(vald[formula2])

                            except KeyError:
                                vald[val] = int(formula) * int(formula2)

                    elif data.startswith("div"):
                        formula = data.split(",")[1].replace(" ", "")
                        formula2 = data.split(",")[2].replace(" ", "")
                        val = data.split(",")[0].split(" ")[1]
                        try:
                            vald[val] = int(vald[formula]) / int(vald[formula2])

                        except KeyError:

                            try:
                                vald[val] = int(formula) / int(vald[formula])

                            except KeyError:
                                vald[val] = int(formula) / int(formula2)
                    
                    elif data == "break":
                        break

                    elif data.startswith("jmp"):
                        jmp = data.replace("jmp ", "")
                        try:
                            if ji == "True":
                                while True:
                                    self.Main(dick, vald, jmp, i, "True")

                            else:
                                for dan in range(ji):
                                    self.Main(dick, vald, jmp, i, 0)
                                break
                        except KeyError:
                            pass

                    elif data.startswith("jne"):
                        data = data.replace(",", "").split(" ")
                        func = data[3]
                        try:
                            if int(vald[data[1]]) > int(vald[data[2]]):
                                self.Main(dick, vald, func, i, ji)
                            
                            else:
                                break

                        except KeyError:
                            try:
                                if int(vald[data[1]]) > int(data[2]):
                                    self.Main(dick, vald, func, i, ji)
                                else:
                                    break

                            except KeyError:#TODO
                                if int(data[1]) > int(vald[data[2]]):
                                    self.Main(dick, vald, func, i, ji)
                                else:
                                    break
                    
                    elif data.startswith("ja"):
                        data = data.replace(",", "").split(" ")
                        func = data[3]
                        try:
                            if int(vald[data[1]]) < int(vald[data[2]]):
                                self.Main(dick, func, i, ji)
                            
                            else:
                                break

                        except KeyError:
                            try:
                                if int(vald[data[1]]) < int(data[2]):
                                    self.Main(dick, vald, func, i, ji)
                                else:
                                    break

                            except KeyError:
                                if int(data[1]) < int(data[2]):
                                    self.Main(dick, vald, func, i, ji)
                                else:
                                    break


if __name__ == '__main__':
    Run().run(0)

Sample code

For example, lapis lazuli can execute code like this:

main.la


fn iffunc(x) {
    if x more_than 3 {
        x = x + 1;
    }
    
    ret func(x) x;
}

fn main() {
    int x = 6;
    use iffunc(x);
    consolp:x;
    ret main() 0;
}

Click here for las bytecode.

main.las


iffunc(x):
    jne x, 3, _L2
    ret
_L2:
    add x, x, 1
    mov func(x), x
    ret
main():
    mov x, 6
    call iffunc(x)
    msg x
    mov main(), 0
    ret
call main()

result


7

I wanted to study English, so I used more_than and less_tahan instead of> or <. (more_than => / less_than = <) The function definition is "fn", longing for Rust. I like the Rust syntax quite a bit. I. Continuing from the previous time, the main () function is called first, so it is the same as C or so, and the first process is written there. Is that much commentary? If you have any questions, please come to I'm with you.

contacting

Right now, dangomushi is looking for "friends" who can share information in their own language. If you are interested and would like to share information, please do not hesitate to contact us.

Summary

This time, I made a language that can do "if statement, while statement, function/variable definition, scope" with only two files. When I implemented the scope and arguments, it was impressive that the dictionary type was awkward. The challenge is

--Bugs irregularly without exception when executing if statement --Slow execution speed --The way to execute a function

I think there are three. Next time I will improve it. See you in the next article !! goodbye!

Recommended Posts

Argument implementation (with code) in your own language
Try HeloWorld in your own language (with How to & code)
Try sorting your own objects with priority queue in Python
Let's make a number guessing game in your own language!
[Python] logging in your own module
Solve your own maze with Q-learning
Train UGATIT with your own dataset
Segfault with 16 characters in C language
Solve your own maze with DQN
Specify your own class in class argument and return type annotation in Python
View the implementation source code in iPython
Your own Twitter client made with Django
Create your own Linux commands in Python
[Reinforcement learning] DQN with your own library
[LLDB] Create your own command in Python
Easily use your own functions in Python
Create your own DNS server with Twisted
Put your own image data in Deep Learning and play with it
Create your own Composite Value with SQLAlchemy
Pass PYTHONPATH in 1 minute with VS Code
To import your own module with jupyter
Publish your own Python library with Homebrew
Analyze the source code of your own simple search engine written in Python with the code visualization tool "SOURCE TRAIL"
Get your own IP address in Python
Try to make your own AWS-SDK with bash
Let's find "T" in your work with us! !! !!
How to define your own target in Sage
Make your own module quickly with setuptools (python)
Tools that fit in your hand (programming language)
Import your own modules in Grasshopper's Python development
Use Python in Anaconda environment with VS Code
Train Stanford NER Tagger with your own data
Make your own music player with Bottle0.13 + jPlayer2.5!
Make your Python environment "easy" with VS Code
Steps to install your own library with pip
Memo to create your own Box with Pepper's Python
Call your own C library with Go using cgo
Specific sample code for working with SQLite3 in Python
Create your own Random Dot Stereogram (RDS) in Python.
Try to improve your own intro quiz in Python
Write your own activation function with Pytorch (hard sigmoid)
Let's call your own C ++ library with Python (Preferences)
Allow real-time code checking in Python development with VS Code
VS Code settings for developing in Python with completion
Define your own distance function with k-means of scikit-learn
Revive symbol search in Python workspace with VS Code
Use the CASA Toolkit in your own Python environment
Try to put LED in your own PC (slightly)
Quickly list multiple lines of text in your code
Visualize fluctuations in numbers on your website with Datadog
[Road to intermediate Python] Define in in your own class