from dataclasses import dataclass from parser import Tree from lexer import Identifier, Punctuator, IntegerConstant import identifier_substitution @dataclass class CTX: identifiers: set def argument_list(ctx, tree): yield from generate(ctx, tree.children[0]) yield ", " yield from generate(ctx, tree.children[1]) def _is_new_temporary(ctx, tree): return ( type(tree) is Identifier and tree.token not in identifier_substitution.mapping and tree.token not in ctx.identifiers ) def assignment(ctx, tree): lhs = tree.children[0] rhs = tree.children[1] if _is_new_temporary(ctx, lhs): ctx.identifiers.add(lhs.token) yield "int64_t " yield from generate(ctx, tree.children[0]) yield " = " yield from generate(ctx, tree.children[1]) def bit_extraction(ctx, tree): yield "bit_extract(" yield from generate(ctx, tree.children[0]) yield ", " yield from generate(ctx, tree.children[1]) yield ")" def bitwise_and(ctx, tree): yield from generate(ctx, tree.children[0]) yield " & " yield from generate(ctx, tree.children[1]) def bitwise_or(ctx, tree): yield from generate(ctx, tree.children[0]) yield " | " yield from generate(ctx, tree.children[1]) def bitwise_xor(ctx, tree): yield from generate(ctx, tree.children[0]) yield " ^ " yield from generate(ctx, tree.children[1]) def block_item_list(ctx, tree): yield from generate(ctx, tree.children[0]) yield from generate(ctx, tree.children[1]) def compound_statement(ctx, tree): yield "\n{\n" if tree.children: yield from generate(ctx, tree.children[0]) yield "}\n" def expression_statement(ctx, tree): yield from generate(ctx, tree.children[0]) yield ";\n" def for_expression(ctx, tree): yield from generate(ctx, tree.children[0]) yield ", " if len(tree.children) > 1: yield from generate(ctx, tree.children[1]) else: yield "1" def helper_arguments(tree): if type(tree.children[0]) is not Identifier: return name = tree.children[0].token mapping = { "IsDelaySlot": "state", "SLEEP": "state", "OCBP" : "state", "WriteMemory8" : "map", "WriteMemory16": "map", "WriteMemory32": "map", "ReadMemory8" : "map", "ReadMemory16" : "map", "ReadMemory32" : "map", } return mapping.get(name, None) def function_call(ctx, tree): yield from generate(ctx, tree.children[0]) yield "(" if len(tree.children) >= 2: if helper_arguments(tree): yield helper_arguments(tree) yield ", " yield from generate(ctx, tree.children[1]) else: if helper_arguments(tree): yield helper_arguments(tree) yield ")" def grouping(ctx, tree): yield "(" yield from generate(ctx, tree.children[0]) yield ")" def _if(ctx, tree): yield "if (" yield from generate(ctx, tree.children[0]) yield ") " yield from generate(ctx, tree.children[1]) def if_else(ctx, tree): yield "if (" yield from generate(ctx, tree.children[0]) yield ") " yield from generate(ctx, tree.children[1]) yield "else " yield from generate(ctx, tree.children[2]) def logical_and(ctx, tree): yield from generate(ctx, tree.children[0]) yield " && " yield from generate(ctx, tree.children[1]) def logical_or(ctx, tree): yield from generate(ctx, tree.children[0]) yield " || " yield from generate(ctx, tree.children[1]) def member(ctx, tree): yield from generate(ctx, tree.children[0]) yield "." yield from generate(ctx, tree.children[1]) def subscript(ctx, tree): yield from generate(ctx, tree.children[0]) yield "[" yield from generate(ctx, tree.children[1]) yield "]" def throw(ctx, tree): yield "return " yield from generate(ctx, tree.children[0]) yield "(state);\n" def throw_arg(ctx, tree): yield "return " yield from generate(ctx, tree.children[0]) yield "(state, " yield from generate(ctx, tree.children[1]) yield ");\n" def unary_complement(ctx, tree): yield from "~" yield from generate(ctx, tree.children[0]) def unary_int(ctx, tree): yield "unary_int(" yield from generate(ctx, tree.children[0]) yield ")" def unary_negation(ctx, tree): yield "-" yield from generate(ctx, tree.children[0]) def unary_not(ctx, tree): yield "!" yield from generate(ctx, tree.children[0]) # def addition(ctx, tree): yield from generate(ctx, tree.children[0]) yield " + " yield from generate(ctx, tree.children[1]) def division(ctx, tree): yield from generate(ctx, tree.children[0]) yield " / " yield from generate(ctx, tree.children[1]) def equality_equal(ctx, tree): yield from generate(ctx, tree.children[0]) yield " == " yield from generate(ctx, tree.children[1]) def equality_not_equal(ctx, tree): yield from generate(ctx, tree.children[0]) yield " != " yield from generate(ctx, tree.children[1]) def greater_than(ctx, tree): yield from generate(ctx, tree.children[0]) yield " > " yield from generate(ctx, tree.children[1]) def greater_than_equal(ctx, tree): yield from generate(ctx, tree.children[0]) yield " >= " yield from generate(ctx, tree.children[1]) def left_shift(ctx, tree): yield from generate(ctx, tree.children[0]) # hack for left shift by LHS constant if type(tree.children[0]) is IntegerConstant: yield "LL" yield " << " yield from generate(ctx, tree.children[1]) def less_than(ctx, tree): yield from generate(ctx, tree.children[0]) yield " < " yield from generate(ctx, tree.children[1]) def less_than_equal(ctx, tree): yield from generate(ctx, tree.children[0]) yield " <= " yield from generate(ctx, tree.children[1]) def multiplication(ctx, tree): yield from generate(ctx, tree.children[0]) yield " * " yield from generate(ctx, tree.children[1]) def right_shift(ctx, tree): yield from generate(ctx, tree.children[0]) yield " >> " yield from generate(ctx, tree.children[1]) def subtraction(ctx, tree): yield from generate(ctx, tree.children[0]) yield " - " yield from generate(ctx, tree.children[1]) def identifier(ctx, token): if token.token in identifier_substitution.mapping: yield identifier_substitution.mapping[token.token] else: assert token.token.lower() == token.token, token if token.token not in {'m', 'n', 'i', 'd'}: assert token.token in ctx.identifiers, (token, ctx.identifiers) yield token.token def constant(ctx, elem): yield elem.token.lower() def generate(ctx, elem): mapping = { "argument_list": argument_list, "assignment": assignment, "bit_extraction": bit_extraction, "bitwise_and": bitwise_and, "bitwise_or": bitwise_or, "bitwise_xor": bitwise_xor, "block_item_list": block_item_list, "compound_statement": compound_statement, "expression_statement": expression_statement, "for_expression": for_expression, "function_call": function_call, "grouping": grouping, "if": _if, "if_else": if_else, "logical_and": logical_and, "logical_or": logical_or, "member": member, "subscript": subscript, "throw": throw, "throw_arg": throw_arg, "unary_complement": unary_complement, "unary_int": unary_int, "unary_negation": unary_negation, "unary_not": unary_not, # "addition": addition, "division": division, "equality_equal": equality_equal, "equality_not_equal": equality_not_equal, "greater_than": greater_than, "greater_than_equal": greater_than_equal, "left_shift": left_shift, "less_than": less_than, "less_than_equal": less_than_equal, "multiplication": multiplication, "right_shift": right_shift, "subtraction": subtraction, # } if type(elem) is Tree: yield from mapping[elem.operation](ctx, elem) elif type(elem) is Identifier: yield from identifier(ctx, elem) elif type(elem) is IntegerConstant: yield from constant(ctx, elem) else: assert False, type(elem)