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.
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.
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)
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.
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.
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