302 lines
8.2 KiB
Python
302 lines
8.2 KiB
Python
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)
|