7 {% for standard_library in standard_libraries %}
8 #include <{{standard_library}}>
12 typedef enum Type Type;
14 typedef union Instance Instance;
16 typedef struct Object Object;
17 struct EnvironmentNode;
18 typedef struct EnvironmentNode EnvironmentNode;
20 typedef struct Environment Environment;
22 const char* const STRING_LITERAL_LIST[] = {
23 {% for string_literal in string_literal_list %}
24 "{{ string_literal }}",
28 const char* const SYMBOL_LIST[] = {
29 {% for symbol in symbol_list %}
45 Object (*closure)(Environment*, size_t, Object*);
61 const Object FALSE = {
66 struct EnvironmentNode
70 EnvironmentNode* next;
76 EnvironmentNode* root;
79 void Environment_initialize(Environment* self, Environment* parent)
81 self->parent = parent;
85 void Environment_deinitialize(Environment* self)
87 EnvironmentNode* next;
88 for(EnvironmentNode* node = self->root; node != NULL; node = next)
90 // No objects are allocated on the heap (yet!) so we don't need to free anything else
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)
99 EnvironmentNode* node = malloc(sizeof(EnvironmentNode));
102 node->next = self->root;
106 Object Environment_get(Environment* self, const char* const symbol)
108 for(EnvironmentNode* node = self->root; node != NULL; node = node->next)
110 // We can compare pointers because pointers are unique in the SYMBOL_LIST
111 if(node->key == symbol)
117 if(self->parent != NULL)
119 return Environment_get(self->parent, symbol);
122 // TODO Handle symbol errors
126 Object integerLiteral(int32_t literal)
129 result.type = INTEGER;
130 result.instance.integer = literal;
134 Object stringLiteral(const char* literal)
137 result.type = STRING;
138 result.instance.string = literal;
142 // TODO Make this conditionally added
143 Object operator$negate(Object input)
145 assert(input.type == INTEGER);
148 result.type = INTEGER;
149 result.instance.integer = -input.instance.integer;
153 Object operator$add(Object left, Object right)
155 assert(left.type == INTEGER);
156 assert(right.type == INTEGER);
159 result.type = INTEGER;
160 result.instance.integer = left.instance.integer + right.instance.integer;
164 Object operator$subtract(Object left, Object right)
166 assert(left.type == INTEGER);
167 assert(right.type == INTEGER);
170 result.type = INTEGER;
171 result.instance.integer = left.instance.integer - right.instance.integer;
175 Object operator$multiply(Object left, Object right)
177 assert(left.type == INTEGER);
178 assert(right.type == INTEGER);
181 result.type = INTEGER;
182 result.instance.integer = left.instance.integer * right.instance.integer;
186 Object operator$integerDivide(Object left, Object right)
188 assert(left.type == INTEGER);
189 assert(right.type == INTEGER);
192 result.type = INTEGER;
193 result.instance.integer = left.instance.integer / right.instance.integer;
197 Object operator$modularDivide(Object left, Object right)
199 assert(left.type == INTEGER);
200 assert(right.type == INTEGER);
203 result.type = INTEGER;
204 result.instance.integer = left.instance.integer % right.instance.integer;
208 Object operator$equals(Object left, Object right)
210 assert(left.type == INTEGER);
211 assert(right.type == INTEGER);
213 Object result = { BOOLEAN, left.instance.integer == right.instance.integer };
217 Object operator$notEquals(Object left, Object right)
219 assert(left.type == INTEGER);
220 assert(right.type == INTEGER);
222 Object result = { BOOLEAN, left.instance.integer != right.instance.integer };
226 Object operator$greaterThan(Object left, Object right)
228 assert(left.type == INTEGER);
229 assert(right.type == INTEGER);
231 Object result = { BOOLEAN, left.instance.integer > right.instance.integer };
235 Object operator$lessThan(Object left, Object right)
237 assert(left.type == INTEGER);
238 assert(right.type == INTEGER);
240 Object result = { BOOLEAN, left.instance.integer < right.instance.integer };
244 Object operator$greaterThanOrEqual(Object left, Object right)
246 assert(left.type == INTEGER);
247 assert(right.type == INTEGER);
249 Object result = { BOOLEAN, left.instance.integer >= right.instance.integer };
253 Object operator$lessThanOrEqual(Object left, Object right)
255 assert(left.type == INTEGER);
256 assert(right.type == INTEGER);
258 Object result = { BOOLEAN, left.instance.integer <= right.instance.integer };
262 Object operator$and(Object left, Object right)
264 assert(left.type == BOOLEAN);
265 assert(right.type == BOOLEAN);
267 Object result = { BOOLEAN, left.instance.boolean && right.instance.boolean };
271 Object operator$or(Object left, Object right)
273 assert(left.type == BOOLEAN);
274 assert(right.type == BOOLEAN);
276 Object result = { BOOLEAN, left.instance.boolean || right.instance.boolean };
280 {% if 'pow' in builtins %}
281 Object builtin$pow$implementation(Environment* parent, size_t argc, Object* args)
285 Object base = args[0];
286 Object exponent = args[1];
288 assert(base.type == INTEGER);
289 assert(exponent.type == INTEGER);
292 result.type = INTEGER;
293 result.instance.integer = pow(base.instance.integer, exponent.instance.integer);
297 Object builtin$pow = { CLOSURE, (Instance)builtin$pow$implementation };
300 {% if 'print' in builtins %}
301 Object builtin$print$implementation(Environment* parent, size_t argc, Object* args)
303 for(size_t i = 0; i < argc; i++)
305 Object output = args[i];
309 fputs(output.instance.boolean ? "true" : "false", stdout);
313 printf("%" PRId32, output.instance.integer);
317 // Using fwrite instead of printf to handle size_t length
318 printf("%s", output.instance.string);
326 // TODO Return something better
330 Object builtin$print = { CLOSURE, (Instance)builtin$print$implementation };
333 {% for function_definition in function_definition_list %}
334 Object user${{function_definition.name}}$implementation(Environment* parent, size_t argc, Object* args)
336 Environment* environment = malloc(sizeof(Environment));;
337 Environment_initialize(environment, parent);
339 {% for statement in function_definition.statement_list[:-1] %}
340 {{ generate_statement(statement) }}
343 Object result = {{ generate_statement(function_definition.statement_list[-1]) }}
344 Environment_deinitialize(environment);
348 Object user${{function_definition.name}} = { CLOSURE, (Instance)user${{function_definition.name}}$implementation };
351 int main(int argc, char** argv)
353 Environment* environment = malloc(sizeof(Environment));
354 Environment_initialize(environment, NULL);
356 // TODO Use the symbol from SYMBOL_LIST
357 {% for builtin in builtins %}
358 Environment_set(environment, "{{ builtin }}", builtin${{ builtin }});
361 {% for statement in statements %}
362 {{ generate_statement(statement) }}
365 Environment_deinitialize(environment);