Go back to allocating environments on the heap
[fur] / templates / program.c
1 #include <assert.h>
2 #include <inttypes.h>
3 #include <stdbool.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 {% for standard_library in standard_libraries %}
8 #include <{{standard_library}}>
9 {% endfor %}
10
11 enum Type;
12 typedef enum Type Type;
13 union Instance;
14 typedef union Instance Instance;
15 struct Object;
16 typedef struct Object Object;
17 struct EnvironmentNode;
18 typedef struct EnvironmentNode EnvironmentNode;
19 struct Environment;
20 typedef struct Environment Environment;
21
22 const char* const STRING_LITERAL_LIST[] = {
23 {% for string_literal in string_literal_list %}
24   "{{ string_literal }}",
25 {% endfor %}
26 };
27
28 const char* const SYMBOL_LIST[] = {
29 {% for symbol in symbol_list %}
30   "{{ symbol }}",
31 {% endfor %}
32 };
33
34 enum Type
35 {
36   BOOLEAN,
37   CLOSURE,
38   INTEGER,
39   STRING
40 };
41
42 union Instance
43 {
44   bool boolean;
45   Object (*closure)(Environment*, size_t, Object*);
46   int32_t integer;
47   const char* string;
48 };
49
50 struct Object
51 {
52   Type type;
53   Instance instance;
54 };
55
56 const Object TRUE = {
57   BOOLEAN,
58   true
59 };
60
61 const Object FALSE = {
62   BOOLEAN,
63   false
64 };
65
66 struct EnvironmentNode
67 {
68   const char* key;
69   Object value;
70   EnvironmentNode* next;
71 };
72
73 struct Environment
74 {
75   Environment* parent;
76   EnvironmentNode* root;
77 };
78
79 void Environment_initialize(Environment* self, Environment* parent)
80 {
81   self->parent = parent;
82   self->root = NULL;
83 }
84
85 void Environment_deinitialize(Environment* self)
86 {
87   EnvironmentNode* next;
88   for(EnvironmentNode* node = self->root; node != NULL; node = next)
89   {
90     // No objects are allocated on the heap (yet!) so we don't need to free anything else
91     next = node->next;
92     free(node);
93   }
94 }
95
96 // This need not be thread safe because environments exist on one thread only
97 void Environment_set(Environment* self, const char* const key, Object value)
98 {
99   EnvironmentNode* node = malloc(sizeof(EnvironmentNode));
100   node->key = key;
101   node->value = value;
102   node->next = self->root;
103   self->root = node;
104 }
105
106 Object Environment_get(Environment* self, const char* const symbol)
107 {
108   for(EnvironmentNode* node = self->root; node != NULL; node = node->next)
109   {
110     // We can compare pointers because pointers are unique in the SYMBOL_LIST
111     if(node->key == symbol)
112     {
113       return node->value;
114     }
115   }
116
117   if(self->parent != NULL)
118   {
119     return Environment_get(self->parent, symbol);
120   }
121
122   // TODO Handle symbol errors
123   assert(false);
124 }
125
126 Object integerLiteral(int32_t literal)
127 {
128   Object result;
129   result.type = INTEGER;
130   result.instance.integer = literal;
131   return result;
132 }
133
134 Object stringLiteral(const char* literal)
135 {
136   Object result;
137   result.type = STRING;
138   result.instance.string = literal;
139   return result;
140 }
141
142 // TODO Make this conditionally added
143 Object operator$negate(Object input)
144 {
145   assert(input.type == INTEGER);
146
147   Object result;
148   result.type = INTEGER;
149   result.instance.integer = -input.instance.integer;
150   return result;
151 }
152
153 Object operator$add(Object left, Object right)
154 {
155   assert(left.type == INTEGER);
156   assert(right.type == INTEGER);
157
158   Object result;
159   result.type = INTEGER;
160   result.instance.integer = left.instance.integer + right.instance.integer;
161   return result;
162 }
163
164 Object operator$subtract(Object left, Object right)
165 {
166   assert(left.type == INTEGER);
167   assert(right.type == INTEGER);
168
169   Object result;
170   result.type = INTEGER;
171   result.instance.integer = left.instance.integer - right.instance.integer;
172   return result;
173 }
174
175 Object operator$multiply(Object left, Object right)
176 {
177   assert(left.type == INTEGER);
178   assert(right.type == INTEGER);
179
180   Object result;
181   result.type = INTEGER;
182   result.instance.integer = left.instance.integer * right.instance.integer;
183   return result;
184 }
185
186 Object operator$integerDivide(Object left, Object right)
187 {
188   assert(left.type == INTEGER);
189   assert(right.type == INTEGER);
190
191   Object result;
192   result.type = INTEGER;
193   result.instance.integer = left.instance.integer / right.instance.integer;
194   return result;
195 }
196
197 Object operator$modularDivide(Object left, Object right)
198 {
199   assert(left.type == INTEGER);
200   assert(right.type == INTEGER);
201
202   Object result;
203   result.type = INTEGER;
204   result.instance.integer = left.instance.integer % right.instance.integer;
205   return result;
206 }
207
208 Object operator$equals(Object left, Object right)
209 {
210   assert(left.type == INTEGER);
211   assert(right.type == INTEGER);
212
213   Object result = { BOOLEAN, left.instance.integer == right.instance.integer };
214   return result;
215 }
216
217 Object operator$notEquals(Object left, Object right)
218 {
219   assert(left.type == INTEGER);
220   assert(right.type == INTEGER);
221
222   Object result = { BOOLEAN, left.instance.integer != right.instance.integer };
223   return result;
224 }
225
226 Object operator$greaterThan(Object left, Object right)
227 {
228   assert(left.type == INTEGER);
229   assert(right.type == INTEGER);
230
231   Object result = { BOOLEAN, left.instance.integer > right.instance.integer };
232   return result;
233 }
234
235 Object operator$lessThan(Object left, Object right)
236 {
237   assert(left.type == INTEGER);
238   assert(right.type == INTEGER);
239
240   Object result = { BOOLEAN, left.instance.integer < right.instance.integer };
241   return result;
242 }
243
244 Object operator$greaterThanOrEqual(Object left, Object right)
245 {
246   assert(left.type == INTEGER);
247   assert(right.type == INTEGER);
248
249   Object result = { BOOLEAN, left.instance.integer >= right.instance.integer };
250   return result;
251 }
252
253 Object operator$lessThanOrEqual(Object left, Object right)
254 {
255   assert(left.type == INTEGER);
256   assert(right.type == INTEGER);
257
258   Object result = { BOOLEAN, left.instance.integer <= right.instance.integer };
259   return result;
260 }
261
262 Object operator$and(Object left, Object right)
263 {
264   assert(left.type == BOOLEAN);
265   assert(right.type == BOOLEAN);
266
267   Object result = { BOOLEAN, left.instance.boolean && right.instance.boolean };
268   return result;
269 }
270
271 Object operator$or(Object left, Object right)
272 {
273   assert(left.type == BOOLEAN);
274   assert(right.type == BOOLEAN);
275
276   Object result = { BOOLEAN, left.instance.boolean || right.instance.boolean };
277   return result;
278 }
279
280 {% if 'pow' in builtins %}
281 Object builtin$pow$implementation(Environment* parent, size_t argc, Object* args)
282 {
283   assert(argc == 2);
284
285   Object base = args[0];
286   Object exponent = args[1];
287
288   assert(base.type == INTEGER);
289   assert(exponent.type == INTEGER);
290
291   Object result;
292   result.type = INTEGER;
293   result.instance.integer = pow(base.instance.integer, exponent.instance.integer);
294   return result;
295 }
296
297 Object builtin$pow = { CLOSURE, (Instance)builtin$pow$implementation };
298 {% endif %}
299
300 {% if 'print' in builtins %}
301 Object builtin$print$implementation(Environment* parent, size_t argc, Object* args)
302 {
303   for(size_t i = 0; i < argc; i++)
304   {
305     Object output = args[i];
306     switch(output.type)
307     {
308       case BOOLEAN:
309         fputs(output.instance.boolean ? "true" : "false", stdout);
310         break;
311
312       case INTEGER:
313         printf("%" PRId32, output.instance.integer);
314         break;
315
316       case STRING:
317         // Using fwrite instead of printf to handle size_t length
318         printf("%s", output.instance.string);
319         break;
320
321       default:
322         assert(false);
323     }
324   }
325
326   // TODO Return something better
327   return FALSE;
328 }
329
330 Object builtin$print = { CLOSURE, (Instance)builtin$print$implementation };
331 {% endif %}
332
333 {% for function_definition in function_definition_list %}
334 Object user${{function_definition.name}}$implementation(Environment* parent, size_t argc, Object* args)
335 {
336   Environment* environment = malloc(sizeof(Environment));;
337   Environment_initialize(environment, parent);
338
339   {% for statement in function_definition.statement_list[:-1] %}
340   {{ generate_statement(statement) }}
341   {% endfor %}
342
343   Object result = {{ generate_statement(function_definition.statement_list[-1]) }}
344   Environment_deinitialize(environment);
345   return result;
346 }
347
348 Object user${{function_definition.name}} = { CLOSURE, (Instance)user${{function_definition.name}}$implementation };
349 {% endfor %}
350
351 int main(int argc, char** argv)
352 {
353   Environment* environment = malloc(sizeof(Environment));
354   Environment_initialize(environment, NULL);
355
356   // TODO Use the symbol from SYMBOL_LIST
357   {% for builtin in builtins %}
358   Environment_set(environment, "{{ builtin }}", builtin${{ builtin }});
359   {% endfor %}
360
361   {% for statement in statements %}
362   {{ generate_statement(statement) }}
363   {% endfor %}
364
365   Environment_deinitialize(environment);
366   free(environment);
367
368   return 0;
369 }