X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=c_generation.py;fp=c_generation.py;h=6dd455123c12cfdab2c71d66114e68f7d16733c3;hp=0000000000000000000000000000000000000000;hb=c45c61444aae3df328e4dc84acf7e31e58a1f64e;hpb=268127b1e817f0dfe298d66e6cacdb0bb83139fb diff --git a/c_generation.py b/c_generation.py new file mode 100644 index 0000000..6dd4551 --- /dev/null +++ b/c_generation.py @@ -0,0 +1,66 @@ +import os + +import jinja2 + +import crossplatform_ir_generation + +TEMPLATE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates') + +def separate_labels_and_instructions(entry_list): + labels_to_instruction_indices = {} + instruction_list = [] + + for entry in entry_list: + if isinstance(entry, crossplatform_ir_generation.CIRInstruction): + instruction_list.append(entry) + elif isinstance(entry, crossplatform_ir_generation.CIRLabel): + labels_to_instruction_indices[entry.label] = len(instruction_list) + + return labels_to_instruction_indices, tuple(instruction_list) + +def generate_integer_argument(argument): + assert isinstance(argument, int) + return '(int32_t){}'.format(argument) + +def generate_null_argument(argument): + assert argument is None + return 'NULL' + +def generate_size_t_argument(argument): + assert isinstance(argument, int) + return '(size_t){}'.format(argument) + +def generate_string_argument(argument): + return argument + +def generate_symbol_argument(argument): + assert argument.startswith('sym(') and argument.endswith(')') + return '"{}"'.format(argument[4:-1]) + +def generate_argument(instruction): + try: + return { + 'drop': generate_null_argument, + 'end': generate_null_argument, + 'call': generate_size_t_argument, + 'push': generate_symbol_argument, + 'push_integer': generate_integer_argument, + 'push_string': generate_string_argument, + }[instruction.instruction](instruction.argument) + + except KeyError: + import ipdb; ipdb.set_trace() + +def generate(ir): + environment = jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_PATH)) + template = environment.get_template('program2.c') + + labels_to_instruction_indices, instruction_list = separate_labels_and_instructions( + ir.entry_list, + ) + + return template.render( + labels_to_instruction_indices=labels_to_instruction_indices, + instruction_list=instruction_list, + generate_argument=generate_argument, + )