Add basic math
[fur] / transformation.py
1 import collections
2
3 import parsing
4
5 CIntegerLiteral = collections.namedtuple(
6     'CIntegerLiteral',
7     [
8         'value',
9     ],
10 )
11
12 CStringLiteral = collections.namedtuple(
13     'CStringLiteral',
14     [
15         'value',
16     ],
17 )
18
19 CAdditionExpression = collections.namedtuple(
20     'CAdditionExpression',
21     [
22         'left',
23         'right',
24     ],
25 )
26
27 CSubtractionExpression = collections.namedtuple(
28     'CSubtractionExpression',
29     [
30         'left',
31         'right',
32     ],
33 )
34
35 CMultiplicationExpression = collections.namedtuple(
36     'CMultiplicationExpression',
37     [
38         'left',
39         'right',
40     ],
41 )
42
43 CIntegerDivisionExpression = collections.namedtuple(
44     'CIntegerDivisionExpression',
45     [
46         'left',
47         'right',
48     ],
49 )
50
51 CModularDivisionExpression = collections.namedtuple(
52     'CModularDivisionExpression',
53     [
54         'left',
55         'right',
56     ],
57 )
58
59 CFunctionCallStatement = collections.namedtuple(
60     'CFunctionCallStatement',
61     [
62         'name',
63         'arguments',
64     ],
65 )
66
67 CProgram = collections.namedtuple(
68     'CProgram',
69     [
70         'builtins',
71         'statements',
72         'standard_libraries',
73     ],
74 )
75
76 BUILTINS = {
77     'print': ['stdio.h.'],
78 }
79
80 def transform_expression(builtin_dependencies, expression):
81
82     LITERAL_TYPE_MAPPING = {
83         parsing.FurIntegerLiteralExpression: CIntegerLiteral,
84         parsing.FurStringLiteralExpression: CStringLiteral,
85     }
86
87     if type(expression) in LITERAL_TYPE_MAPPING:
88         return LITERAL_TYPE_MAPPING[type(expression)](value=expression.value)
89
90     INFIX_TYPE_MAPPING = {
91         parsing.FurAdditionExpression: CAdditionExpression,
92         parsing.FurSubtractionExpression: CSubtractionExpression,
93         parsing.FurMultiplicationExpression: CMultiplicationExpression,
94         parsing.FurIntegerDivisionExpression: CIntegerDivisionExpression,
95         parsing.FurModularDivisionExpression: CModularDivisionExpression,
96     }
97
98     return INFIX_TYPE_MAPPING[type(expression)](
99         left=transform_expression(builtin_dependencies, expression.left),
100         right=transform_expression(builtin_dependencies, expression.right),
101     )
102
103 def transform_function_call_statement(builtin_dependencies, function_call):
104     if function_call.name in BUILTINS.keys():
105         builtin_dependencies.add(function_call.name)
106
107         return CFunctionCallStatement(
108             name='builtin$' + function_call.name,
109             arguments=tuple(transform_expression(builtin_dependencies, arg) for arg in function_call.arguments),
110         )
111
112     raise Exception()
113
114 def transform(program):
115     builtins = set()
116
117     c_statements = [
118         transform_function_call_statement(builtins, statement) for statement in program.statement_list
119     ]
120
121     standard_libraries = set()
122     for builtin in builtins:
123         for standard_library in BUILTINS[builtin]:
124             standard_libraries.add(standard_library)
125
126     return CProgram(
127         builtins=builtins,
128         statements=c_statements,
129         standard_libraries=standard_libraries,
130     )
131
132
133 if __name__ == '__main__':
134     import unittest
135
136     unittest.main()