sh-dis/ast_to_c_source.py
Zack Buhman 7299da7bdb add support for non-FPU/UBC/MMU/cache SH4 instructions
Previously, ast transformations were performed informally as ad-hoc
modifications to the generated C source code. In this commit, the
same transformations are performed by rewriting the ast prior to code
generation time.

The most significant new transformer is transform_assignment_list.
This transforms assignments such as:

  a, b, c = f(b, c, d)

To:

  a = f(&b, &c, d)

The former syntax is used frequently in the manual's description of
FPU-related instructions.
2024-04-22 20:53:36 +08:00

286 lines
7.2 KiB
Python

from dataclasses import dataclass
from parser import Tree
from lexer import Identifier, Punctuator, IntegerConstant
import identifier_substitution
def argument_list(tree):
yield from generate(tree.children[0])
yield ", "
yield from generate(tree.children[1])
def _is_new_temporary(tree):
return (
type(tree) is Identifier
and tree.token not in identifier_substitution.mapping
and tree.token not in ctx.identifiers
)
def assignment_list(tree):
yield from generate(tree.children[0])
yield ", "
yield from generate(tree.children[1])
def assignment(tree):
yield from generate(tree.children[0])
yield " = "
yield from generate(tree.children[1])
def bit_extraction(tree):
yield "bit_extract("
yield from generate(tree.children[0])
yield ", "
yield from generate(tree.children[1])
yield ")"
def bitwise_and(tree):
yield from generate(tree.children[0])
yield " & "
yield from generate(tree.children[1])
def bitwise_or(tree):
yield from generate(tree.children[0])
yield " | "
yield from generate(tree.children[1])
def bitwise_xor(tree):
yield from generate(tree.children[0])
yield " ^ "
yield from generate(tree.children[1])
def block_item_list(tree):
yield from generate(tree.children[0])
yield from generate(tree.children[1])
def compound_statement(tree):
yield "\n{\n"
if tree.children:
yield from generate(tree.children[0])
yield "}\n"
def expression_statement(tree):
yield from generate(tree.children[0])
yield ";\n"
def for_expression(tree):
yield from generate(tree.children[0])
yield ", "
if len(tree.children) > 1:
yield from generate(tree.children[1])
else:
yield "1"
def function_call(tree):
assert len(tree.children) in {1, 2}
yield from generate(tree.children[0])
yield "("
if len(tree.children) == 2:
yield from generate(tree.children[1])
yield ")"
def grouping(tree):
yield "("
yield from generate(tree.children[0])
yield ")"
def _if(tree):
yield "if ("
yield from generate(tree.children[0])
yield ") "
yield from generate(tree.children[1])
def if_else(tree):
yield "if ("
yield from generate(tree.children[0])
yield ") "
yield from generate(tree.children[1])
yield "else "
yield from generate(tree.children[2])
def logical_and(tree):
yield from generate(tree.children[0])
yield " && "
yield from generate(tree.children[1])
def logical_or(tree):
yield from generate(tree.children[0])
yield " || "
yield from generate(tree.children[1])
def member(tree):
yield from generate(tree.children[0])
yield "."
yield from generate(tree.children[1])
def subscript(tree):
yield from generate(tree.children[0])
yield "["
yield from generate(tree.children[1])
yield "]"
def throw(tree):
yield "return "
yield from generate(tree.children[0])
yield "(state);\n"
def throw_arg(tree):
yield "return "
yield from generate(tree.children[0])
yield "(state, "
yield from generate(tree.children[1])
yield ");\n"
def unary_complement(tree):
yield from "~"
yield from generate(tree.children[0])
def unary_int(tree):
yield "unary_int("
yield from generate(tree.children[0])
yield ")"
def unary_negation(tree):
yield "-"
yield from generate(tree.children[0])
def unary_not(tree):
yield "!"
yield from generate(tree.children[0])
#
def addition(tree):
yield from generate(tree.children[0])
yield " + "
yield from generate(tree.children[1])
def division(tree):
yield from generate(tree.children[0])
yield " / "
yield from generate(tree.children[1])
def equality_equal(tree):
yield from generate(tree.children[0])
yield " == "
yield from generate(tree.children[1])
def equality_not_equal(tree):
yield from generate(tree.children[0])
yield " != "
yield from generate(tree.children[1])
def greater_than(tree):
yield from generate(tree.children[0])
yield " > "
yield from generate(tree.children[1])
def greater_than_equal(tree):
yield from generate(tree.children[0])
yield " >= "
yield from generate(tree.children[1])
def left_shift(tree):
yield from generate(tree.children[0])
# hack for left shift by LHS constant
if type(tree.children[0]) is IntegerConstant:
yield "LL"
yield " << "
yield from generate(tree.children[1])
def less_than(tree):
yield from generate(tree.children[0])
yield " < "
yield from generate(tree.children[1])
def less_than_equal(tree):
yield from generate(tree.children[0])
yield " <= "
yield from generate(tree.children[1])
def multiplication(tree):
yield from generate(tree.children[0])
yield " * "
yield from generate(tree.children[1])
def right_shift(tree):
yield from generate(tree.children[0])
yield " >> "
yield from generate(tree.children[1])
def subtraction(tree):
yield from generate(tree.children[0])
yield " - "
yield from generate(tree.children[1])
def declaration(tree):
assert len(tree.children) >= 2, tree
yield from generate(tree.children[0])
yield " "
for child in tree.children[1:-1]:
yield from generate(child)
yield ", "
yield from generate(tree.children[-1])
def unary_reference(tree):
yield "&"
assert len(tree.children) == 1
yield from generate(tree.children[0])
def identifier(token):
yield token.token
def constant(elem):
yield elem.token.lower()
def generate(elem):
mapping = {
"argument_list": argument_list,
"assignment_list": assignment_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,
#
"declaration": declaration,
"unary_reference": unary_reference,
}
if type(elem) is Tree:
yield from mapping[elem.operation](elem)
elif type(elem) is Identifier:
yield from identifier(elem)
elif type(elem) is IntegerConstant:
yield from constant(elem)
else:
assert False, type(elem)