Implemented integer comparison
[fur] / c_generation.py
1 import os
2
3 import jinja2
4
5 import crossplatform_ir_generation
6
7 TEMPLATE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')
8
9 def separate_labels_and_instructions(entry_list):
10     labels_to_instruction_indices = {}
11     instruction_list = []
12
13     for entry in entry_list:
14         if isinstance(entry, crossplatform_ir_generation.CIRInstruction):
15             instruction_list.append(entry)
16         elif isinstance(entry, crossplatform_ir_generation.CIRLabel):
17             labels_to_instruction_indices[entry.label] = len(instruction_list)
18
19     return labels_to_instruction_indices, tuple(instruction_list)
20
21 def generate_integer_argument(argument):
22     assert isinstance(argument, int)
23     return '(int32_t){}'.format(argument)
24
25 def generate_null_argument(argument):
26     assert argument is None
27     return 'NULL'
28
29 def generate_null_argument_from(argument_count):
30     def generator(argument):
31         assert isinstance(argument, int)
32         assert argument == argument_count
33         return 'NULL'
34     return generator
35
36 def generate_size_t_argument(argument):
37     assert isinstance(argument, int)
38     return '(size_t){}'.format(argument)
39
40 def generate_string_argument(argument):
41     return argument
42
43 def generate_symbol_argument(argument):
44     assert argument.startswith('sym(') and argument.endswith(')')
45     return '"{}"'.format(argument[4:-1])
46
47 def generate_argument(instruction):
48     try:
49         return {
50             'add': generate_null_argument_from(2),
51             'call': generate_size_t_argument,
52             'drop': generate_null_argument,
53             'end': generate_null_argument,
54             'eq': generate_null_argument_from(2),
55             'gt': generate_null_argument_from(2),
56             'gte': generate_null_argument_from(2),
57             'idiv': generate_null_argument_from(2),
58             'lt': generate_null_argument_from(2),
59             'lte': generate_null_argument_from(2),
60             'mod': generate_null_argument_from(2),
61             'mul': generate_null_argument_from(2),
62             'neg': generate_null_argument_from(1),
63             'neq': generate_null_argument_from(2),
64             'pop': generate_symbol_argument,
65             'push': generate_symbol_argument,
66             'push_integer': generate_integer_argument,
67             'push_string': generate_string_argument,
68             'sub': generate_null_argument_from(2),
69         }[instruction.instruction](instruction.argument)
70
71     except KeyError:
72         import ipdb; ipdb.set_trace()
73
74 def generate(ir):
75     environment = jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_PATH))
76     template = environment.get_template('program2.c')
77
78     labels_to_instruction_indices, instruction_list = separate_labels_and_instructions(
79         ir.entry_list,
80     )
81
82     return template.render(
83         labels_to_instruction_indices=labels_to_instruction_indices,
84         instruction_list=instruction_list,
85         generate_argument=generate_argument,
86     )