Fix/simplify the generation of if/else statements
[fur] / conversion.py
1 import collections
2
3 import normalization
4
5 CPSFunctionCallExpression = collections.namedtuple(
6     'CPSFunctionCallExpression',
7     (
8         'metadata',
9         'function_expression',
10         'argument_count',
11     ),
12 )
13
14 CPSIntegerLiteralExpression = collections.namedtuple(
15     'CPSIntegerLiteralExpression',
16     (
17         'integer',
18     ),
19 )
20
21 CPSLambdaExpression = collections.namedtuple(
22     'CPSLambdaExpression',
23     (
24         'name',
25         'argument_name_list',
26         'statement_list',
27     ),
28 )
29
30 CPSListConstructExpression = collections.namedtuple(
31     'CPSListConstructExpression',
32     (
33         'allocate',
34     ),
35 )
36
37 CPSStringLiteralExpression = collections.namedtuple(
38     'CPSStringLiteralExpression',
39     (
40         'string',
41     ),
42 )
43
44 CPSStructureLiteralExpression = collections.namedtuple(
45     'CPSStructureLiteralExpression',
46     (
47         'field_count',
48         'symbol_list_variable',
49         'value_list_variable',
50     ),
51 )
52
53 CPSSymbolExpression = collections.namedtuple(
54     'CPSSymbolExpression',
55     (
56         'symbol',
57     ),
58 )
59
60 CPSVariableExpression = collections.namedtuple(
61     'CPSVariableExpression',
62     (
63         'variable',
64     ),
65 )
66
67 CPSArrayVariableInitializationStatement = collections.namedtuple(
68     'CPSArrayVariableInitializationStatement',
69     (
70         'variable',
71         'items',
72     ),
73 )
74
75 CPSAssignmentStatement = collections.namedtuple(
76     'CPSAssignmentStatement',
77     (
78         'target',
79         'expression',
80     ),
81 )
82
83 CPSExpressionStatement = collections.namedtuple(
84     'CPSExpressionStatement',
85     (
86         'expression',
87     ),
88 )
89
90 CPSIfElseExpression = collections.namedtuple(
91     'CPSIfElseExpression',
92     (
93         'condition_expression',
94         'if_statement_list',
95         'else_statement_list',
96     ),
97 )
98
99 CPSListAppendStatement = collections.namedtuple(
100     'CPSListAppendStatement',
101     (
102         'list_expression',
103         'item_expression',
104     ),
105 )
106
107 CPSPushStatement = collections.namedtuple(
108     'CPSPushStatement',
109     (
110         'expression',
111     ),
112 )
113
114 CPSVariableInitializationStatement = collections.namedtuple(
115     'CPSVariableInitializationStatement',
116     (
117         'variable',
118         'expression',
119     ),
120 )
121
122 CPSSymbolArrayVariableInitializationStatement = collections.namedtuple(
123     'CPSSymbolArrayVariableInitializationStatement',
124     (
125         'variable',
126         'symbol_list',
127     ),
128 )
129
130 CPSProgram = collections.namedtuple(
131     'CPSProgram',
132     (
133         'statement_list',
134     ),
135 )
136
137 def convert_function_call_expression(expression):
138     return CPSFunctionCallExpression(
139         metadata=expression.metadata,
140         function_expression=convert_expression(expression.function_expression),
141         argument_count=expression.argument_count,
142     )
143
144 def convert_integer_literal_expression(expression):
145     return CPSIntegerLiteralExpression(integer=expression.integer)
146
147 def convert_lambda_expression(expression):
148     return CPSLambdaExpression(
149         name=expression.name,
150         argument_name_list=expression.argument_name_list,
151         statement_list=tuple(convert_statement(s) for s in expression.statement_list),
152     )
153
154 def convert_list_construct_expression(expression):
155     return CPSListConstructExpression(allocate=expression.allocate)
156
157 def convert_string_literal_expression(expression):
158     return CPSStringLiteralExpression(string=expression.string)
159
160 def convert_structure_literal_expression(expression):
161     return CPSStructureLiteralExpression(
162         field_count=expression.field_count,
163         symbol_list_variable=expression.symbol_list_variable,
164         value_list_variable=expression.value_list_variable,
165     )
166
167 def convert_symbol_expression(expression):
168     return CPSSymbolExpression(symbol=expression.symbol)
169
170 def convert_variable_expression(expression):
171     return CPSVariableExpression(variable=expression.variable)
172
173 def convert_expression(expression):
174     return {
175         normalization.NormalFunctionCallExpression: convert_function_call_expression,
176         normalization.NormalIfElseExpression: convert_if_else_expression,
177         normalization.NormalIntegerLiteralExpression: convert_integer_literal_expression,
178         normalization.NormalLambdaExpression: convert_lambda_expression,
179         normalization.NormalListConstructExpression: convert_list_construct_expression,
180         normalization.NormalStringLiteralExpression: convert_string_literal_expression,
181         normalization.NormalStructureLiteralExpression: convert_structure_literal_expression,
182         normalization.NormalSymbolExpression: convert_symbol_expression,
183         normalization.NormalVariableExpression: convert_variable_expression,
184     }[type(expression)](expression)
185
186 def convert_array_variable_initialization_statement(statement):
187     return CPSArrayVariableInitializationStatement(
188         variable=statement.variable,
189         items=tuple(convert_expression(e) for e in statement.items),
190     )
191
192 def convert_assignment_statement(statement):
193     return CPSAssignmentStatement(
194         target=statement.target,
195         expression=convert_expression(statement.expression),
196     )
197
198 def convert_expression_statement(statement):
199     return CPSExpressionStatement(
200         expression=convert_expression(statement.expression),
201     )
202
203 def convert_if_else_expression(statement):
204     if_statement_list=tuple(convert_statement(s) for s in statement.if_statement_list)
205     else_statement_list=tuple(convert_statement(s) for s in statement.else_statement_list)
206
207     return CPSIfElseExpression(
208         condition_expression=convert_expression(statement.condition_expression),
209         if_statement_list=if_statement_list,
210         else_statement_list=else_statement_list,
211     )
212
213 def convert_list_append_statement(statement):
214     return CPSListAppendStatement(
215         list_expression=convert_expression(statement.list_expression),
216         item_expression=convert_expression(statement.item_expression),
217     )
218
219
220 def convert_push_statement(statement):
221     return CPSPushStatement(
222         expression=convert_expression(statement.expression),
223     )
224
225 def convert_variable_initialization_statement(statement):
226     return CPSVariableInitializationStatement(
227         variable=statement.variable,
228         expression=convert_expression(statement.expression),
229     )
230
231 def convert_symbol_array_variable_initialization_statement(statement):
232     return CPSSymbolArrayVariableInitializationStatement(
233         variable=statement.variable,
234         symbol_list=statement.symbol_list,
235     )
236
237 def convert_statement(statement):
238     return {
239         normalization.NormalArrayVariableInitializationStatement: convert_array_variable_initialization_statement,
240         normalization.NormalAssignmentStatement: convert_assignment_statement,
241         normalization.NormalExpressionStatement: convert_expression_statement,
242         normalization.NormalListAppendStatement: convert_list_append_statement,
243         normalization.NormalPushStatement: convert_push_statement,
244         normalization.NormalVariableInitializationStatement: convert_variable_initialization_statement,
245         normalization.NormalSymbolArrayVariableInitializationStatement: convert_symbol_array_variable_initialization_statement,
246     }[type(statement)](statement)
247
248 def convert_statement_list(statement_list):
249     return tuple(convert_statement(s) for s in statement_list)
250
251
252 def convert(program):
253     return CPSProgram(
254         statement_list=convert_statement_list(program.statement_list),
255     )