diff --git a/sleepy/asmik/emit.py b/sleepy/asmik/emit.py index 12ac94a..eae1276 100644 --- a/sleepy/asmik/emit.py +++ b/sleepy/asmik/emit.py @@ -1,6 +1,6 @@ from typing import override -import sleepy.tafka.representation as tafka +import sleepy.tafka.representation as taf from sleepy.tafka.walker import TafkaWalker from .argument import Immediate, Integer, Unassigned @@ -32,7 +32,7 @@ def __init__(self) -> None: self.sequence = (VirtReg(n) for n in range(10000)) self.binded: dict[str, Reg] = {} - def binded_to(self, var: tafka.Var) -> Reg: + def binded_to(self, var: taf.Var) -> Reg: var_repr = repr(var) if var_repr not in self.binded: self.binded[var_repr] = self.temporary() @@ -50,7 +50,7 @@ def __init__(self) -> None: self.resolved: dict[str, int] = {} @override - def enter_procedure(self, procedure: tafka.Procedure) -> None: + def enter_procedure(self, procedure: taf.Procedure) -> None: addr = self.memory.data_put(IntegerData(self.next_instr_addr)) self.resolved[repr(procedure.const)] = addr for i, param in enumerate(procedure.parameters): @@ -58,40 +58,40 @@ def enter_procedure(self, procedure: tafka.Procedure) -> None: self.emit(mov(register, PhysReg.arg(i + 1))) @override - def exit_procedure(self, procedure: tafka.Procedure) -> None: + def exit_procedure(self, procedure: taf.Procedure) -> None: pass @override - def enter_block(self, block: tafka.Block) -> None: + def enter_block(self, block: taf.Block) -> None: self.resolved[repr(block.label)] = self.next_instr_addr @override - def exit_block(self, block: tafka.Block) -> None: + def exit_block(self, block: taf.Block) -> None: pass @override - def enter_statement(self, statement: tafka.Statement) -> None: + def enter_statement(self, statement: taf.Statement) -> None: pass @override - def exit_statement(self, statement: tafka.Statement) -> None: + def exit_statement(self, statement: taf.Statement) -> None: pass @override - def on_return(self, ret: tafka.Return) -> None: + def on_return(self, ret: taf.Return) -> None: retr = self.registers.binded_to(ret.value) self.emit(mov(Reg.a1(), retr)) self.emit(Brn(Reg.ze(), Reg.ra())) @override - def on_goto(self, goto: tafka.Goto) -> None: + def on_goto(self, goto: taf.Goto) -> None: block_label = repr(goto.block.label) label = self.registers.temporary() self.emit(movi(label, Unassigned(block_label))) self.emit(Brn(Reg.ze(), label)) @override - def on_conditional(self, conditional: tafka.Conditional) -> None: + def on_conditional(self, conditional: taf.Conditional) -> None: else_label = repr(conditional.else_branch.label) condition = self.registers.binded_to(conditional.condition) else_address = self.registers.temporary() @@ -101,8 +101,8 @@ def on_conditional(self, conditional: tafka.Conditional) -> None: @override def on_invokation( self, - target: tafka.Var, - source: tafka.Invokation, + target: taf.Var, + source: taf.Invokation, ) -> None: for i, arg in enumerate(source.args): arg_reg = self.registers.binded_to(arg) @@ -121,36 +121,36 @@ def on_invokation( self.emit(mov(Reg.ra(), prev_ra)) @override - def on_load(self, target: tafka.Var, source: tafka.Load) -> None: + def on_load(self, target: taf.Var, source: taf.Load) -> None: dst = self.registers.binded_to(target) addr = self.addr_of(source.constant) self.emit(Addim(dst, Reg.ze(), addr)) self.emit(Load(dst, dst)) @override - def on_copy(self, target: tafka.Var, source: tafka.Copy) -> None: + def on_copy(self, target: taf.Var, source: taf.Copy) -> None: dst = self.registers.binded_to(target) src = self.registers.binded_to(source.argument) self.emit(mov(dst, src)) @override - def on_sum(self, target: tafka.Var, source: tafka.Sum) -> None: + def on_sum(self, target: taf.Var, source: taf.Sum) -> None: self.on_trivial_binary_operation(target, source) @override - def on_mul(self, target: tafka.Var, source: tafka.Mul) -> None: + def on_mul(self, target: taf.Var, source: taf.Mul) -> None: self.on_trivial_binary_operation(target, source) @override - def on_div(self, target: tafka.Var, source: tafka.Div) -> None: + def on_div(self, target: taf.Var, source: taf.Div) -> None: self.on_trivial_binary_operation(target, source) @override - def on_rem(self, target: tafka.Var, source: tafka.Rem) -> None: + def on_rem(self, target: taf.Var, source: taf.Rem) -> None: self.on_trivial_binary_operation(target, source) @override - def on_eq(self, target: tafka.Var, source: tafka.Eq) -> None: + def on_eq(self, target: taf.Var, source: taf.Eq) -> None: dstr = self.registers.binded_to(target) lhsr = self.registers.binded_to(source.left) rhsr = self.registers.binded_to(source.right) @@ -166,21 +166,21 @@ def on_eq(self, target: tafka.Var, source: tafka.Eq) -> None: self.emit(Xorb(dstr, orb, neg)) @override - def on_lt(self, target: tafka.Var, source: tafka.Lt) -> None: + def on_lt(self, target: taf.Var, source: taf.Lt) -> None: self.on_trivial_binary_operation(target, source) @override - def on_and(self, target: tafka.Var, source: tafka.And) -> None: + def on_and(self, target: taf.Var, source: taf.And) -> None: self.on_trivial_binary_operation(target, source) @override - def on_or(self, target: tafka.Var, source: tafka.Or) -> None: + def on_or(self, target: taf.Var, source: taf.Or) -> None: self.on_trivial_binary_operation(target, source) def on_trivial_binary_operation( self, - target: tafka.Var, - source: tafka.BinaryOperator, + target: taf.Var, + source: taf.BinaryOperator, ) -> None: dstr = self.registers.binded_to(target) lhsr = self.registers.binded_to(source.left) @@ -188,19 +188,19 @@ def on_trivial_binary_operation( instruction: Instruction match source: - case tafka.Sum(): + case taf.Sum(): instruction = Addi(dstr, lhsr, rhsr) - case tafka.Mul(): + case taf.Mul(): instruction = Muli(dstr, lhsr, rhsr) - case tafka.Div(): + case taf.Div(): instruction = Divi(dstr, lhsr, rhsr) - case tafka.Rem(): + case taf.Rem(): instruction = Remi(dstr, lhsr, rhsr) - case tafka.Lt(): + case taf.Lt(): instruction = Slti(dstr, lhsr, rhsr) - case tafka.And(): + case taf.And(): instruction = Andb(dstr, lhsr, rhsr) - case tafka.Or(): + case taf.Or(): instruction = Orb(dstr, lhsr, rhsr) self.emit(instruction) @@ -208,13 +208,13 @@ def on_trivial_binary_operation( def emit(self, instr: Instruction) -> None: self.memory.instr.append(instr) - def addr_of(self, cnst: tafka.Const) -> Immediate: + def addr_of(self, cnst: taf.Const) -> Immediate: match cnst.kind: - case tafka.Int(): + case taf.Int(): data = IntegerData(int(cnst.name)) addr = self.memory.data_put(data) return Integer(addr) - case tafka.Signature(): + case taf.Signature(): return Unassigned(repr(cnst)) case _: raise NotImplementedError diff --git a/sleepy/tafka/emit.py b/sleepy/tafka/emit.py index edd072d..19ecf94 100644 --- a/sleepy/tafka/emit.py +++ b/sleepy/tafka/emit.py @@ -1,115 +1,80 @@ -from typing import TYPE_CHECKING, override - -from sleepy.program import ( - Application, - Closure, - Conditional, - Definition, - Integer, - Intrinsic, - Kind, - Program, - ProgramVisitor, - Symbol, -) +from typing import override + +import sleepy.tafka.representation as taf +from sleepy import program +from sleepy.core import MetaTable +from sleepy.program import ProgramVisitor from sleepy.program.unit import ProgramUnit -from sleepy.tafka.representation import ( - Block, - Const, - Copy, - Div, - Eq, - Goto, - Int, - Label, - Load, - Lt, - Mul, - Procedure, - Rem, - Return, - RValue, - Set, - Statement, - Sum, - Var, -) -from sleepy.tafka.representation import Conditional as TafConditional -from sleepy.tafka.representation import Kind as TafKind -from sleepy.tafka.representation.rvalue import And, Invokation, Or - -if TYPE_CHECKING: - from sleepy.core import UID class TafkaEmitVisitor(ProgramVisitor[None]): def __init__(self, unit: ProgramUnit) -> None: self.unit = unit - self.main = Block(Label("main"), []) + self.main = taf.Block(taf.Label("main"), []) + self.procedures: list[taf.Procedure] = [] self.var_names = map(str, range(10000000)) self.lbl_names = map(str, range(10000000)) - self.vars: dict[UID, Var] = {} - self.procedures: list[Procedure] = [] + self.vars = MetaTable[taf.Var]() self.current_block = self.main - self.last_result = Var("0", Int()) + self.last_result = taf.Var("0", taf.Int()) @override - def visit_program(self, tree: Program) -> None: + def visit_program(self, tree: program.Program) -> None: for statement in tree.statements: self.visit_expression(statement) - self.emit_statement(Return(self.last_result)) + self.emit_statement(taf.Return(self.last_result)) @override - def visit_conditional(self, tree: Conditional) -> None: - then_blk = Block(self.next_lbl(), []) - else_blk = Block(self.next_lbl(), []) - next_blk = Block(self.next_lbl(), []) + def visit_conditional(self, tree: program.Conditional) -> None: + then_blk = taf.Block(self.next_lbl(), []) + else_blk = taf.Block(self.next_lbl(), []) + next_blk = taf.Block(self.next_lbl(), []) self.visit_expression(tree.condition) condition = self.last_result - br = TafConditional(condition, then_blk, else_blk, next_blk) + br = taf.Conditional(condition, then_blk, else_blk, next_blk) self.emit_statement(br) self.current_block = then_blk self.visit_expression(tree.then_branch) then_result = self.last_result - self.emit_statement(Goto(next_blk)) + self.emit_statement(taf.Goto(next_blk)) self.current_block = else_blk self.visit_expression(tree.else_branch) - self.emit_statement(Set(then_result, Copy(self.last_result))) - self.emit_statement(Goto(next_blk)) + self.emit_statement(taf.Set(then_result, taf.Copy(self.last_result))) + self.emit_statement(taf.Goto(next_blk)) self.current_block = next_blk @override - def visit_application(self, tree: Application) -> None: + def visit_application(self, tree: program.Application) -> None: args = [] for arg in tree.args: self.visit_expression(arg) args.append(self.last_result) match tree.invokable: - case Symbol() as symbol: + case program.Symbol() as symbol: invokable = self.unit.bindings.resolve(symbol) match invokable: - case Intrinsic() as intrinsic: + case program.Intrinsic() as intrinsic: self.visit_application_intrinsic( intrinsic, args, ) - case Closure() as closure: + case program.Closure() as closure: self.visit_symbol(symbol) self.visit_application_variable( self.last_result, args, ) - case Closure() as closure: + case program.Closure() as closure: self.visit_lambda(closure) self.visit_application_variable( self.last_result, @@ -118,96 +83,98 @@ def visit_application(self, tree: Application) -> None: def visit_application_intrinsic( self, - intrinsic: Intrinsic, - args: list[Var], + intrinsic: program.Intrinsic, + args: list[taf.Var], ) -> None: + rvalue: taf.RValue match intrinsic.name.name: case "sum": - self.emit_intermidiate(Sum(args[0], args[1])) + rvalue = taf.Sum(args[0], args[1]) case "div": - self.emit_intermidiate(Div(args[0], args[1])) + rvalue = taf.Div(args[0], args[1]) case "rem": - self.emit_intermidiate(Rem(args[0], args[1])) + rvalue = taf.Rem(args[0], args[1]) case "mul": - self.emit_intermidiate(Mul(args[0], args[1])) + rvalue = taf.Mul(args[0], args[1]) case "eq": - self.emit_intermidiate(Eq(args[0], args[1])) + rvalue = taf.Eq(args[0], args[1]) case "lt": - self.emit_intermidiate(Lt(args[0], args[1])) + rvalue = taf.Lt(args[0], args[1]) case "and": - self.emit_intermidiate(And(args[0], args[1])) + rvalue = taf.And(args[0], args[1]) case "or": - self.emit_intermidiate(Or(args[0], args[1])) + rvalue = taf.Or(args[0], args[1]) case _: raise NotImplementedError(str(intrinsic)) + self.emit_intermidiate(rvalue) def visit_application_variable( self, - invokable: Var, - args: list[Var], + invokable: taf.Var, + args: list[taf.Var], ) -> None: - self.emit_intermidiate(Invokation(invokable, args)) + self.emit_intermidiate(taf.Invokation(invokable, args)) @override - def visit_lambda(self, tree: Closure) -> None: + def visit_lambda(self, tree: program.Closure) -> None: current_block = self.current_block label = self.next_lbl() params = [ - self.next_var(TafKind.from_sleepy(param.kind)) + self.next_var(taf.Kind.from_sleepy(param.kind)) for param in tree.parameters ] for param, var in zip(tree.parameters, params, strict=True): - self.vars[param.name.uid] = var + self.vars[param.name] = var - body = Block(label, statements=[]) + body = taf.Block(label, statements=[]) self.current_block = body for statement in tree.statements: self.visit_expression(statement) - self.emit_statement(Return(self.last_result)) + self.emit_statement(taf.Return(self.last_result)) value = self.last_result.kind self.current_block = current_block - procedure = Procedure(label.name, body, params, value) + procedure = taf.Procedure(label.name, body, params, value) self.procedures.append(procedure) self.emit_intermidiate( - Load(Const(label.name, procedure.signature)), + taf.Load(taf.Const(label.name, procedure.signature)), ) @override - def visit_symbol(self, tree: Symbol) -> None: - self.last_result = self.vars[tree.uid] + def visit_symbol(self, tree: program.Symbol) -> None: + self.last_result = self.vars[tree] @override - def visit_kind(self, tree: Kind) -> None: + def visit_kind(self, tree: program.Kind) -> None: raise NotImplementedError @override - def visit_integer(self, tree: Integer) -> None: - self.emit_intermidiate(Load(Const(str(tree.value), Int()))) + def visit_integer(self, tree: program.Integer) -> None: + self.emit_intermidiate(taf.Load(taf.Const(str(tree.value), taf.Int()))) @override - def visit_definition(self, tree: Definition) -> None: + def visit_definition(self, tree: program.Definition) -> None: self.visit_expression(tree.expression) - self.vars[tree.symbol.uid] = self.last_result + self.vars[tree.symbol] = self.last_result - def emit_statement(self, statement: Statement) -> None: - if isinstance(statement, Set): + def emit_statement(self, statement: taf.Statement) -> None: + if isinstance(statement, taf.Set): self.last_result = statement.target self.current_block.statements.append(statement) - def emit_intermidiate(self, rvalue: RValue) -> None: - self.emit_statement(Set(self.next_var(rvalue.value), rvalue)) + def emit_intermidiate(self, rvalue: taf.RValue) -> None: + self.emit_statement(taf.Set(self.next_var(rvalue.value), rvalue)) - def next_var(self, kind: TafKind) -> Var: - return Var(next(self.var_names), kind) + def next_var(self, kind: taf.Kind) -> taf.Var: + return taf.Var(next(self.var_names), kind) - def next_lbl(self) -> Label: - return Label(next(self.lbl_names)) + def next_lbl(self) -> taf.Label: + return taf.Label(next(self.lbl_names))