b04cf1ab7f7db06f19aa5652ce8559402b5db674
[fur] / desugaring.py
1 import collections
2
3 import parsing
4
5 DesugaredBuiltinExpression = collections.namedtuple(
6     'DesugaredBuiltinExpression',
7     (
8         'metadata',
9         'symbol',
10     ),
11 )
12
13 DesugaredFunctionCallExpression = collections.namedtuple(
14     'DesugaredFunctionCallExpression',
15     (
16         'metadata',
17         'function',
18         'argument_list',
19     ),
20 )
21
22 DesugaredIfExpression = collections.namedtuple(
23     'DesugaredIfExpression',
24     (
25         'condition_expression',
26         'if_statement_list',
27         'else_statement_list',
28     ),
29 )
30
31 DesugaredIntegerLiteralExpression = collections.namedtuple(
32     'DesugaredIntegerLiteralExpression',
33     (
34         'integer',
35     ),
36 )
37
38 _DesugaredLambdaExpression = collections.namedtuple(
39     'DesugaredLambdaExpression',
40     (
41         'name',
42         'argument_name_list',
43         'statement_list',
44     ),
45 )
46
47 class DesugaredLambdaExpression(_DesugaredLambdaExpression):
48     def __new__(cls, *args, **kwargs):
49         if 'name' not in kwargs:
50             kwargs['name'] = None
51
52         return super(DesugaredLambdaExpression, cls).__new__(cls, *args, **kwargs)
53
54 DesugaredListLiteralExpression = collections.namedtuple(
55     'DesugaredListLiteralExpression',
56     (
57         'item_expression_list',
58     ),
59 )
60
61 DesugaredStringLiteralExpression = collections.namedtuple(
62     'DesugaredStringLiteralExpression',
63     (
64         'string',
65     ),
66 )
67
68 DesugaredSymbolExpressionPair = collections.namedtuple(
69     'DesugaredSymbolExpressionPair',
70     (
71         'symbol',
72         'expression',
73     ),
74 )
75
76 DesugaredStructureLiteralExpression = collections.namedtuple(
77     'DesugaredStructureLiteralExpression',
78     (
79         'fields',
80     ),
81 )
82
83 DesugaredSymbolExpression = collections.namedtuple(
84     'DesugaredSymbolExpression',
85     (
86         'metadata',
87         'symbol',
88     ),
89 )
90
91 DesugaredSymbolLiteralExpression = collections.namedtuple(
92     'DesugaredSymbolLiteralExpression',
93     (
94         'metadata',
95         'symbol',
96     ),
97 )
98
99 DesugaredAssignmentStatement = collections.namedtuple(
100     'DesugaredAssignmentStatement',
101     (
102         'target',
103         'expression',
104     ),
105 )
106
107 DesugaredExpressionStatement = collections.namedtuple(
108     'DesugaredExpressionStatement',
109     (
110         'expression',
111     ),
112 )
113
114 DesugaredProgram = collections.namedtuple(
115     'DesugaredProgram',
116     (
117         'statement_list',
118     ),
119 )
120
121 def desugar_function_call_expression(expression):
122     return DesugaredFunctionCallExpression(
123         metadata=expression.metadata,
124         function=desugar_expression(expression.function),
125         argument_list=tuple(desugar_expression(e) for e in expression.arguments),
126     )
127
128 def desugar_if_expression(expression):
129     return DesugaredIfExpression(
130         condition_expression=desugar_expression(expression.condition_expression),
131         if_statement_list=tuple(desugar_statement(s) for s in expression.if_statement_list),
132         else_statement_list=tuple(desugar_statement(s) for s in expression.else_statement_list),
133     )
134
135 def desugar_infix_expression(expression):
136     if expression.operator == 'and':
137         return DesugaredIfExpression(
138             condition_expression=desugar_expression(expression.left),
139             if_statement_list=(
140                 DesugaredExpressionStatement(expression=desugar_expression(expression.right)),
141             ),
142             else_statement_list=(
143                 DesugaredExpressionStatement(
144                     expression=DesugaredSymbolExpression(
145                         metadata=expression.metadata,
146                         symbol='false',
147                     ),
148                 ),
149             ),
150         )
151
152     if expression.operator == 'or':
153         return DesugaredIfExpression(
154             condition_expression=desugar_expression(expression.left),
155             if_statement_list=(
156                 DesugaredExpressionStatement(
157                     expression=DesugaredSymbolExpression(
158                         metadata=expression.metadata,
159                         symbol='true',
160                     ),
161                 ),
162             ),
163             else_statement_list=(
164                 DesugaredExpressionStatement(expression=desugar_expression(expression.right)),
165             ),
166         )
167
168     if expression.operator == '.':
169         return DesugaredFunctionCallExpression(
170             metadata=expression.metadata,
171             function=DesugaredSymbolExpression(
172                 metadata=expression.metadata,
173                 symbol='__field__',
174             ),
175             argument_list=(
176                 desugar_expression(expression.left),
177                 desugar_symbol_literal_expression(expression.right),
178             ),
179         )
180
181     function = {
182         '++': '__concat__',
183         '+': '__add__',
184         '-': '__subtract__',
185         '*': '__multiply__',
186         '//': '__integer_divide__',
187         '%': '__modular_divide__',
188         '<': '__lt__',
189         '>': '__gt__',
190         '<=': '__lte__',
191         '>=': '__gte__',
192         '==': '__eq__',
193         '!=': '__neq__',
194     }[expression.operator]
195
196     return DesugaredFunctionCallExpression(
197         metadata=expression.metadata,
198         function=DesugaredBuiltinExpression(
199             metadata=expression.metadata,
200             symbol=function,
201         ),
202         argument_list=(
203             desugar_expression(expression.left),
204             desugar_expression(expression.right),
205         ),
206     )
207
208 def desugar_integer_literal_expression(expression):
209     return DesugaredIntegerLiteralExpression(
210         integer=expression.integer,
211     )
212
213 def desugar_lambda_expression(expression):
214     return DesugaredLambdaExpression(
215         argument_name_list=expression.argument_name_list,
216         statement_list=tuple(desugar_statement(s) for s in expression.statement_list),
217     )
218
219 def desugar_list_item_expression(expression):
220     return DesugaredFunctionCallExpression(
221         metadata=expression.metadata,
222         function=DesugaredBuiltinExpression(
223             metadata=expression.metadata,
224             symbol='__get__',
225         ),
226         argument_list=(
227             desugar_expression(expression.list_expression),
228             desugar_expression(expression.index_expression),
229         ),
230     )
231
232 def desugar_list_literal_expression(expression):
233     return DesugaredListLiteralExpression(
234         item_expression_list=tuple(desugar_expression(i) for i in expression.item_expression_list),
235     )
236
237 def desugar_negation_expression(expression):
238     return DesugaredFunctionCallExpression(
239         metadata=expression.metadata,
240         function=DesugaredBuiltinExpression(
241             metadata=expression.metadata,
242             symbol='__negate__',
243         ),
244         argument_list=(
245             desugar_expression(expression.value),
246         ),
247     )
248
249 def desugar_string_literal_expression(expression):
250     return DesugaredStringLiteralExpression(
251         string=expression.string,
252     )
253
254 def desugar_structure_literal_expression(expression):
255     return DesugaredStructureLiteralExpression(
256         fields=tuple(
257             DesugaredSymbolExpressionPair(
258                 symbol=p.symbol,
259                 expression=desugar_expression(p.expression),
260             ) for p in expression.fields
261         ),
262     )
263
264 def desugar_symbol_expression(expression):
265     return DesugaredSymbolExpression(
266         metadata=expression.metadata,
267         symbol=expression.symbol,
268     )
269
270 def desugar_symbol_literal_expression(expression):
271     return DesugaredSymbolLiteralExpression(
272         metadata=expression.metadata,
273         symbol=expression.symbol,
274     )
275
276 def desugar_expression(expression):
277     return {
278         parsing.FurFunctionCallExpression: desugar_function_call_expression,
279         parsing.FurIfExpression: desugar_if_expression,
280         parsing.FurInfixExpression: desugar_infix_expression,
281         parsing.FurIntegerLiteralExpression: desugar_integer_literal_expression,
282         parsing.FurLambdaExpression: desugar_lambda_expression,
283         parsing.FurListItemExpression: desugar_list_item_expression,
284         parsing.FurListLiteralExpression: desugar_list_literal_expression,
285         parsing.FurNegationExpression: desugar_negation_expression,
286         parsing.FurStringLiteralExpression: desugar_string_literal_expression,
287         parsing.FurStructureLiteralExpression: desugar_structure_literal_expression,
288         parsing.FurSymbolExpression: desugar_symbol_expression,
289     }[type(expression)](expression)
290
291 def desugar_assignment_statement(statement):
292     return DesugaredAssignmentStatement(
293         target=statement.target,
294         expression=desugar_expression(statement.expression),
295     )
296
297 def desugar_expression_statement(statement):
298     return DesugaredExpressionStatement(
299         expression=desugar_expression(statement.expression),
300     )
301
302 def desugar_function_definition_statement(statement):
303     return DesugaredAssignmentStatement(
304         target=statement.name,
305         expression=DesugaredLambdaExpression(
306             name=statement.name,
307             argument_name_list=statement.argument_name_list,
308             statement_list=tuple(desugar_statement(s) for s in statement.statement_list),
309         ),
310     )
311
312 def desugar_statement(statement):
313     return {
314         parsing.FurAssignmentStatement: desugar_assignment_statement,
315         parsing.FurExpressionStatement: desugar_expression_statement,
316         parsing.FurFunctionDefinitionStatement: desugar_function_definition_statement,
317     }[type(statement)](statement)
318
319 def desugar(program):
320     return DesugaredProgram(
321         statement_list=[desugar_statement(s) for s in program.statement_list],
322     )