Minor refactor
[fur] / normalization.py
1 import collections
2
3 import parsing
4
5 NormalVariableExpression = collections.namedtuple(
6     'NormalVariableExpression',
7     [
8         'variable',
9     ],
10 )
11
12 NormalVariableAssignmentStatement = collections.namedtuple(
13     'NormalVariableAssignmentStatement',
14     [
15         'variable',
16         'expression',
17     ],
18 )
19
20 NormalFunctionCallExpression = collections.namedtuple(
21     'NormalFunctionCallExpression',
22     [
23         'function',
24         'arguments',
25     ],
26 )
27
28 NormalExpressionStatement = collections.namedtuple(
29     'NormalExpressionStatement',
30     [
31         'expression',
32     ],
33 )
34
35 NormalProgram = collections.namedtuple(
36     'NormalProgram',
37     [
38         'statement_list',
39     ],
40 )
41
42 def fake_normalization(counter, thing):
43     return (counter, (), thing)
44
45 def normalize_function_call_expression(counter, expression):
46     prestatements = []
47     arguments = []
48
49     for argument in expression.arguments:
50         variable = '${}'.format(counter)
51         prestatements.append(NormalVariableAssignmentStatement(
52             variable=variable,
53             expression=argument, # TODO Normalize each argument
54         ))
55         arguments.append(NormalVariableExpression(
56             variable=variable,
57         ))
58         counter += 1
59
60     return (
61         counter,
62         tuple(prestatements),
63         NormalFunctionCallExpression(
64             expression.function, # TODO Normalize the function
65             arguments=tuple(arguments),
66         ),
67     )
68
69 def normalize_expression_statement(counter, statement):
70     counter, prestatements, normalized = {
71         parsing.FurFunctionCallExpression: normalize_function_call_expression,
72     }[type(statement.expression)](counter, statement.expression)
73
74     return (
75         counter,
76         prestatements,
77         NormalExpressionStatement(expression=normalized),
78     )
79
80 def normalize_statement(counter, statement):
81     return {
82         parsing.FurExpressionStatement: normalize_expression_statement,
83         parsing.FurAssignmentStatement: fake_normalization,
84     }[type(statement)](counter, statement)
85
86 def normalize(program):
87     counter = 0
88     statement_list = []
89
90     for statement in program.statement_list:
91         counter, prestatements, normalized = normalize_statement(counter, statement)
92         for s in prestatements:
93             statement_list.append(s)
94         statement_list.append(normalized)
95
96     return NormalProgram(
97         statement_list=statement_list,
98     )