def make_branch_func_int() -> Tuple[Function, Tuple[BasicBlock, ...]]: bb0 = BasicBlock("bb0") bb1 = BasicBlock("bb1") bb2 = BasicBlock("bb2") bb3 = BasicBlock("bb3") bb0.add_inst(bytecode.CopyInst(Var('v0'), NumLit(SNum(42)))) bb0.add_inst(bytecode.BrInst(Var('x'), bb1)) bb0.add_inst(bytecode.JmpInst(bb2)) bb1.add_inst( bytecode.BinopInst(Var('v0'), Binop.ADD, Var('v0'), NumLit(SNum(27)))) bb1.add_inst(bytecode.JmpInst(bb3)) bb2.add_inst( bytecode.BinopInst(Var('v0'), Binop.MUL, Var('v0'), NumLit(SNum(10)))) bb2.add_inst(bytecode.JmpInst(bb3)) bb3.add_inst(bytecode.ReturnInst(Var('v0'))) return Function([Var('x')], bb0), (bb0, bb1, bb2, bb3)
def make_func() -> Function: bb0 = BasicBlock("bb0") bb1 = BasicBlock("bb1") bb0.add_inst(bytecode.CopyInst(Var('v0'), NumLit(SNum(42)))) bb0.add_inst( bytecode.BinopInst(Var('v1'), Binop.ADD, Var('v0'), NumLit(SNum(69)))) bb0.add_inst(bytecode.JmpInst(bb1)) bb1.add_inst(bytecode.ReturnInst(Var('v1'))) return Function([], bb0)
def _add_arity_check( self, function_expr: bytecode.Parameter, add_to_block: bytecode.BasicBlock, arity: int) -> None: arity_var = bytecode.Var(next(self.var_names)) add_to_block.add_inst(bytecode.ArityInst(arity_var, function_expr)) correct_arity_var = bytecode.Var(next(self.var_names)) add_to_block.add_inst(bytecode.BinopInst( correct_arity_var, bytecode.Binop.NUM_EQ, arity_var, bytecode.NumLit(sexp.SNum(arity)) )) add_to_block.add_inst(bytecode.BrnInst(correct_arity_var, ARITY_TRAP))
def _add_is_function_check( self, function_expr: bytecode.Parameter, add_to_block: bytecode.BasicBlock) -> None: typeof_var = bytecode.Var(next(self.var_names)) typeof_instr = bytecode.TypeofInst( typeof_var, function_expr) is_function_var = bytecode.Var(next(self.var_names)) is_function_instr = bytecode.BinopInst( is_function_var, bytecode.Binop.SYM_EQ, typeof_var, bytecode.SymLit(sexp.SSym('function')) ) branch_instr = bytecode.BrnInst(is_function_var, IS_FUNCTION_TRAP) for instr in [typeof_instr, is_function_instr, branch_instr]: add_to_block.add_inst(instr)
def binop(name: SSym, op: Binop) -> SFunction: return inst_function( name, [Var('a'), Var('b')], result, bytecode.BinopInst(result, op, Var('a'), Var('b')))
def test_example_inlined(self) -> None: """ function list? (v0) entry=bb0 bb0: v1 = typeof v0 v2 = sym_eq v1 'vector brn v2 false v3 = length v0 v4 = num_eq v3 0 br v4 true v5 = num_eq v3 2 brn v5 false v0 = load v0 [1] jmp bb0 true: return 'true false: return 'false """ bb0 = bytecode.BasicBlock("bb0") true = bytecode.BasicBlock("true") false = bytecode.BasicBlock("false") is_list = bytecode.Function([Var("v0")], bb0) # These tests are just to test the API bb0.add_inst(bytecode.TypeofInst(Var("v1"), Var("v0"))) bb0.add_inst( bytecode.BinopInst(Var("v2"), Binop.SYM_EQ, Var("v1"), SymLit(SSym("vector")))) bb0.add_inst(bytecode.BrnInst(Var("v2"), false)) bb0.add_inst(bytecode.LengthInst(Var("v3"), Var("v0"))) bb0.add_inst( bytecode.BinopInst(Var("v4"), Binop.NUM_EQ, Var("v3"), NumLit(SNum(0)))) bb0.add_inst(bytecode.BrInst(Var("v4"), true)) bb0.add_inst( bytecode.BinopInst(Var("v5"), Binop.NUM_EQ, Var("v3"), NumLit(SNum(2)))) bb0.add_inst(bytecode.BrnInst(Var("v5"), false)) bb0.add_inst(bytecode.LoadInst(Var("v0"), Var("v0"), NumLit(SNum(1)))) bb0.add_inst(bytecode.JmpInst(bb0)) true.add_inst(bytecode.ReturnInst(BoolLit(SBool(True)))) false.add_inst(bytecode.ReturnInst(BoolLit(SBool(False)))) env = bytecode.EvalEnv(local_env={Var("v0"): SNum(42)}) gen = bytecode.ResultGenerator(is_list.run(env)) gen.run() self.assertEqual(gen.value, SBool(False)) env = bytecode.EvalEnv(local_env={ Var("v0"): SVect([SNum(42), SVect([SNum(69), SVect([])])]) }) gen = bytecode.ResultGenerator(is_list.run(env)) gen.run() self.assertEqual(gen.value, SBool(True))