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