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;
75 size_t referenceCount;
77 EnvironmentNode* root;
80 Environment* Environment_construct(Environment* parent)
82 Environment* result = malloc(sizeof(Environment));
83 result->referenceCount = 1;
84 result->parent = parent;
89 void Environment_destruct(Environment* self)
91 self->referenceCount--;
93 if(self->referenceCount == 0)
95 EnvironmentNode* next;
96 for(EnvironmentNode* node = self->root; node != NULL; node = next)
98 // No objects are allocated on the heap (yet!) so we don't need to free anything else
106 // This need not be thread safe because environments exist on one thread only
107 void Environment_set(Environment* self, const char* const key, Object value)
109 EnvironmentNode* node = malloc(sizeof(EnvironmentNode));
112 node->next = self->root;
116 Object Environment_get(Environment* self, const char* const symbol)
118 for(EnvironmentNode* node = self->root; node != NULL; node = node->next)
120 // We can compare pointers because pointers are unique in the SYMBOL_LIST
121 if(node->key == symbol)
127 if(self->parent != NULL)
129 return Environment_get(self->parent, symbol);
132 // TODO Handle symbol errors
136 Object integerLiteral(int32_t literal)
139 result.type = INTEGER;
140 result.instance.integer = literal;
144 Object stringLiteral(const char* literal)
147 result.type = STRING;
148 result.instance.string = literal;
152 // TODO Make this conditionally added
153 Object operator$negate(Object input)
155 assert(input.type == INTEGER);
158 result.type = INTEGER;
159 result.instance.integer = -input.instance.integer;
163 Object operator$add(Object left, Object right)
165 assert(left.type == INTEGER);
166 assert(right.type == INTEGER);
169 result.type = INTEGER;
170 result.instance.integer = left.instance.integer + right.instance.integer;
174 Object operator$subtract(Object left, Object right)
176 assert(left.type == INTEGER);
177 assert(right.type == INTEGER);
180 result.type = INTEGER;
181 result.instance.integer = left.instance.integer - right.instance.integer;
185 Object operator$multiply(Object left, Object right)
187 assert(left.type == INTEGER);
188 assert(right.type == INTEGER);
191 result.type = INTEGER;
192 result.instance.integer = left.instance.integer * right.instance.integer;
196 Object operator$integerDivide(Object left, Object right)
198 assert(left.type == INTEGER);
199 assert(right.type == INTEGER);
202 result.type = INTEGER;
203 result.instance.integer = left.instance.integer / right.instance.integer;
207 Object operator$modularDivide(Object left, Object right)
209 assert(left.type == INTEGER);
210 assert(right.type == INTEGER);
213 result.type = INTEGER;
214 result.instance.integer = left.instance.integer % right.instance.integer;
218 Object operator$equals(Object left, Object right)
220 assert(left.type == INTEGER);
221 assert(right.type == INTEGER);
223 Object result = { BOOLEAN, { left.instance.integer == right.instance.integer } };
227 Object operator$notEquals(Object left, Object right)
229 assert(left.type == INTEGER);
230 assert(right.type == INTEGER);
232 Object result = { BOOLEAN, { left.instance.integer != right.instance.integer } };
236 Object operator$greaterThan(Object left, Object right)
238 assert(left.type == INTEGER);
239 assert(right.type == INTEGER);
241 Object result = { BOOLEAN, { left.instance.integer > right.instance.integer } };
245 Object operator$lessThan(Object left, Object right)
247 assert(left.type == INTEGER);
248 assert(right.type == INTEGER);
250 Object result = { BOOLEAN, { left.instance.integer < right.instance.integer } };
254 Object operator$greaterThanOrEqual(Object left, Object right)
256 assert(left.type == INTEGER);
257 assert(right.type == INTEGER);
259 Object result = { BOOLEAN, { left.instance.integer >= right.instance.integer } };
263 Object operator$lessThanOrEqual(Object left, Object right)
265 assert(left.type == INTEGER);
266 assert(right.type == INTEGER);
268 Object result = { BOOLEAN, { left.instance.integer <= right.instance.integer } };
272 Object operator$and(Object left, Object right)
274 assert(left.type == BOOLEAN);
275 assert(right.type == BOOLEAN);
277 Object result = { BOOLEAN, { left.instance.boolean && right.instance.boolean } };
281 Object operator$or(Object left, Object right)
283 assert(left.type == BOOLEAN);
284 assert(right.type == BOOLEAN);
286 Object result = { BOOLEAN, { left.instance.boolean || right.instance.boolean } };
290 {% if 'pow' in builtins %}
291 Object builtin$pow$implementation(Environment* parent, size_t argc, Object* args)
295 Object base = args[0];
296 Object exponent = args[1];
298 assert(base.type == INTEGER);
299 assert(exponent.type == INTEGER);
302 result.type = INTEGER;
303 result.instance.integer = pow(base.instance.integer, exponent.instance.integer);
307 Object builtin$pow = { CLOSURE, (Instance)builtin$pow$implementation };
310 {% if 'print' in builtins %}
311 Object builtin$print$implementation(Environment* parent, size_t argc, Object* args)
313 for(size_t i = 0; i < argc; i++)
315 Object output = args[i];
319 fputs(output.instance.boolean ? "true" : "false", stdout);
323 printf("%" PRId32, output.instance.integer);
327 // Using fwrite instead of printf to handle size_t length
328 printf("%s", output.instance.string);
336 // TODO Return something better
340 Object builtin$print = { CLOSURE, (Instance)builtin$print$implementation };
343 {% for function_definition in function_definition_list %}
344 Object user${{function_definition.name}}$implementation(Environment* parent, size_t argc, Object* args)
346 Environment* environment = Environment_construct(parent);
348 {% for statement in function_definition.statement_list[:-1] %}
349 {{ generate_statement(statement) }}
352 Object result = {{ generate_statement(function_definition.statement_list[-1]) }}
353 Environment_destruct(environment);
357 Object user${{function_definition.name}} = { CLOSURE, (Instance)user${{function_definition.name}}$implementation };
360 int main(int argc, char** argv)
362 Environment* environment = Environment_construct(NULL);
364 // TODO Use the symbol from SYMBOL_LIST
365 {% for builtin in builtins %}
366 Environment_set(environment, "{{ builtin }}", builtin${{ builtin }});
369 {% for statement in statements %}
370 {{ generate_statement(statement) }}
373 Environment_destruct(environment);