Kaydet (Commit) 8af25700 authored tarafından Batuhan Taşkaya's avatar Batuhan Taşkaya

(Literal | Symbol) vs (Literal | Symbol) comparsion

üst 43c1caf8
...@@ -8,22 +8,19 @@ from arkhe.debugger import ADB ...@@ -8,22 +8,19 @@ from arkhe.debugger import ADB
from itertools import chain from itertools import chain
from textwrap import dedent from textwrap import dedent
def arkhe_int(value): def arkhe_int(value):
dc = (value >> 8) dc = value >> 8
do = value - (dc << 8) do = value - (dc << 8)
return dc, do return dc, do
def name(value): def name(value):
return list(map(ord, value)) return list(map(ord, value))
COMP_MAP = {
"==": "eq", COMP_MAP = {"==": "eq", "!=": "ne", ">": "gt", "<": "lt", ">=": "ge", "<=": "le"}
"!=": "ne",
">": "gt",
"<": "lt",
">=": "ge",
"<=": "le"
}
""" """
Register Reserves; Register Reserves;
0, 1 => LOAD 0, 1 => LOAD
...@@ -32,76 +29,107 @@ Register Reserves; ...@@ -32,76 +29,107 @@ Register Reserves;
0..31 => SYMREAD 0..31 => SYMREAD
""" """
class Compiler(Transformer): class Compiler(Transformer):
def main(self, tokens): def main(self, tokens):
return list(chain.from_iterable(filter(lambda token: token, tokens))) return list(chain.from_iterable(filter(lambda token: token, tokens)))
def symset(self, tokens): def symset(self, tokens):
sym, val = tokens sym, val = tokens
value = literal_eval(val) ops = self.load_value(val)
if val.type == 'INT':
ops = arkhe_int(value) loads = [
elif val.type == 'STR': *create_instr("load", 0, *name(sym), TypeTable.STR.value),
ops = list(map(ord, value)) *create_instr("load", 1, *ops),
ops.append(TypeTable.STR.value) ]
elif val.type == 'BYT':
ops = list(map(ord, value.decode('utf8')))
ops.append(TypeTable.BYT.value)
loads = [*create_instr("load", 0, *name(sym), TypeTable.STR.value),
*create_instr("load", 1, *ops)]
return [*loads, *create_instr("symset", 0, 1)] return [*loads, *create_instr("symset", 0, 1)]
def comp(self, tokens): def comp(self, tokens):
op1, comp, op2 = tokens comp = COMP_MAP.get(tokens.pop(1).children[0].value, "eq")
comp = COMP_MAP.get(comp.children[0].value, "eq")
read, regs = self.symread(op1, op2) inst = []
return [*read, *create_instr(comp, *regs)] regs = []
for operand in tokens:
if operand.type == 'SYM':
read, reg = self.symread(str(operand))
inst.extend(read)
regs.extend(reg)
elif operand.type == 'STR' or operand.type == 'INT':
read, reg = self.load_value(operand), max(regs, default=0) + 1
inst.extend(create_instr("load", reg, *read))
regs.append(reg)
return [*inst, *create_instr(comp, *regs)]
def symread(self, *syms): def symread(self, *syms):
loads = [create_instr("load", n, *name(item), TypeTable.STR.value) for n, item in enumerate(syms)] loads = [
create_instr("load", n, *name(item), TypeTable.STR.value)
for n, item in enumerate(syms)
]
symreads = [create_instr("symread", n, n) for n in range(len(syms))] symreads = [create_instr("symread", n, n) for n in range(len(syms))]
return list(chain.from_iterable([*loads, *symreads])), list(range(len(syms))) return list(chain.from_iterable([*loads, *symreads])), list(range(len(syms)))
def if_stmt(self, tokens): def if_stmt(self, tokens):
if len(tokens) == 3: if len(tokens) == 3:
comp, suite, suite_else = tokens comp, suite, suite_else = tokens
loads = [*create_instr("load", 29, *arkhe_int(len(suite))), loads = [
*create_instr("load", 30, *arkhe_int(len(suite_else))), *create_instr("load", 29, *arkhe_int(len(suite))),
*create_instr("load", 31, *arkhe_int(0))] *create_instr("load", 30, *arkhe_int(len(suite_else))),
*create_instr("load", 31, *arkhe_int(0)),
]
code = [ code = [
*loads, *loads,
*comp, *comp,
*create_instr('jfe', 31), # No jump *create_instr("jfe", 31), # No jump
*create_instr('jfn', 29), # Jump amount of suite *create_instr("jfn", 29), # Jump amount of suite
*suite, *suite,
*create_instr('jfn', 31), *create_instr("jfn", 31),
*create_instr('jfe', 30), *create_instr("jfe", 30),
*suite_else *suite_else,
] ]
else: else:
comp, suite = tokens comp, suite = tokens
loads = [*create_instr("load", 29, *arkhe_int(len(suite))), loads = [
*create_instr("load", 30, *arkhe_int(0))] *create_instr("load", 29, *arkhe_int(len(suite))),
*create_instr("load", 30, *arkhe_int(0)),
]
code = [ code = [
*loads, *loads,
*comp, *comp,
*create_instr('jfe', 30), # No jump *create_instr("jfe", 30), # No jump
*create_instr('jfn', 29), # Jump amount of suite *create_instr("jfn", 29), # Jump amount of suite
*suite, *suite,
] ]
return code return code
def suite(self, tokens): def suite(self, tokens):
return list(chain.from_iterable(tokens)) return list(chain.from_iterable(tokens))
def load_value(self, val):
value = literal_eval(val)
if val.type == "INT":
ops = arkhe_int(value)
elif val.type == "STR":
ops = list(map(ord, value))
ops.append(TypeTable.STR.value)
elif val.type == "BYT":
ops = list(map(ord, value.decode("utf8")))
ops.append(TypeTable.BYT.value)
return ops
def ccall(self, tokens): def ccall(self, tokens):
func, *args = tokens func, *args = tokens
args, args_regs = self.symread(*args) args, args_regs = self.symread(*args)
return [*args, *create_instr("load", 27, *name(str(func)), TypeTable.STR.value), *create_instr("ccall", 27, *args_regs, 28)] return [
*args,
*create_instr("load", 27, *name(str(func)), TypeTable.STR.value),
*create_instr("ccall", 27, *args_regs, 28),
]
...@@ -5,11 +5,17 @@ if_stmt: "if" comp ":" suite ["else" ":" suite] ...@@ -5,11 +5,17 @@ if_stmt: "if" comp ":" suite ["else" ":" suite]
suite: _NEWLINE _INDENT expr+ _DEDENT suite: _NEWLINE _INDENT expr+ _DEDENT
?expr: (symset | comp | ccall) _NEWLINE ?expr: (symset | comp | ccall) _NEWLINE
symset: SYM "=" (INT | STR)
comp: SYM op SYM symset: SYM "=" (INT | STR | arith)
ccall: SYM "(" SYM? ("," SYM)* ")" comp: (INT | STR | SYM) op (INT | STR | SYM)
arith: (INT | STR | SYM) fact (INT | STR | SYM)
call: SYM "(" SYM? ("," SYM)* ")"
ccall: "!" SYM "(" SYM? ("," SYM)* ")"
!op: "<" | ">" | "=" | ">=" | "<=" | "!=" !op: "<" | ">" | "=" | ">=" | "<=" | "!="
!fact: "+" | "-" | "*" | "/"
COMMENT: /#[^\n]*/ COMMENT: /#[^\n]*/
_NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ _NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment