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