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;
18 const char* const STRING_LITERAL_LIST[] = {
19 {% for string_literal in string_literal_list %}
20 "{{ string_literal }}",
24 const char* const SYMBOL_LIST[] = {
25 {% for symbol in symbol_list %}
41 Object (*closure)(size_t, Object*);
57 const Object FALSE = {
62 struct EnvironmentNode;
63 typedef struct EnvironmentNode EnvironmentNode;
64 struct EnvironmentNode
68 EnvironmentNode* next;
72 typedef struct Environment Environment;
75 EnvironmentNode* root;
78 Environment* Environment_construct()
80 // TODO Handle malloc returning NULL
81 Environment* result = malloc(sizeof(Environment));
86 void Environment_destruct(Environment* self)
88 EnvironmentNode* next;
89 for(EnvironmentNode* node = self->root; node != NULL; node = next)
91 // No objects are allocated on the heap (yet!) so we don't need to free anything else
97 // This need not be thread safe because environments exist on one thread only
98 void Environment_set(Environment* self, const char* const key, Object value)
100 EnvironmentNode* node = malloc(sizeof(EnvironmentNode));
103 node->next = self->root;
107 Object Environment_get(Environment* self, const char* const symbol)
109 for(EnvironmentNode* node = self->root; node != NULL; node = node->next)
111 // We can compare pointers because pointers are unique in the SYMBOL_LIST
112 if(node->key == symbol)
118 // TODO Handle symbol errors
122 Object integerLiteral(int32_t literal)
125 result.type = INTEGER;
126 result.instance.integer = literal;
130 Object stringLiteral(const char* literal)
133 result.type = STRING;
134 result.instance.string = literal;
138 // TODO Make this conditionally added
139 Object operator$negate(Object input)
141 assert(input.type == INTEGER);
144 result.type = INTEGER;
145 result.instance.integer = -input.instance.integer;
149 Object operator$add(Object left, Object right)
151 assert(left.type == INTEGER);
152 assert(right.type == INTEGER);
155 result.type = INTEGER;
156 result.instance.integer = left.instance.integer + right.instance.integer;
160 Object operator$subtract(Object left, Object right)
162 assert(left.type == INTEGER);
163 assert(right.type == INTEGER);
166 result.type = INTEGER;
167 result.instance.integer = left.instance.integer - right.instance.integer;
171 Object operator$multiply(Object left, Object right)
173 assert(left.type == INTEGER);
174 assert(right.type == INTEGER);
177 result.type = INTEGER;
178 result.instance.integer = left.instance.integer * right.instance.integer;
182 Object operator$integerDivide(Object left, Object right)
184 assert(left.type == INTEGER);
185 assert(right.type == INTEGER);
188 result.type = INTEGER;
189 result.instance.integer = left.instance.integer / right.instance.integer;
193 Object operator$modularDivide(Object left, Object right)
195 assert(left.type == INTEGER);
196 assert(right.type == INTEGER);
199 result.type = INTEGER;
200 result.instance.integer = left.instance.integer % right.instance.integer;
204 Object operator$equals(Object left, Object right)
206 assert(left.type == INTEGER);
207 assert(right.type == INTEGER);
209 Object result = { BOOLEAN, left.instance.integer == right.instance.integer };
213 Object operator$notEquals(Object left, Object right)
215 assert(left.type == INTEGER);
216 assert(right.type == INTEGER);
218 Object result = { BOOLEAN, left.instance.integer != right.instance.integer };
222 Object operator$greaterThan(Object left, Object right)
224 assert(left.type == INTEGER);
225 assert(right.type == INTEGER);
227 Object result = { BOOLEAN, left.instance.integer > right.instance.integer };
231 Object operator$lessThan(Object left, Object right)
233 assert(left.type == INTEGER);
234 assert(right.type == INTEGER);
236 Object result = { BOOLEAN, left.instance.integer < right.instance.integer };
240 Object operator$greaterThanOrEqual(Object left, Object right)
242 assert(left.type == INTEGER);
243 assert(right.type == INTEGER);
245 Object result = { BOOLEAN, left.instance.integer >= right.instance.integer };
249 Object operator$lessThanOrEqual(Object left, Object right)
251 assert(left.type == INTEGER);
252 assert(right.type == INTEGER);
254 Object result = { BOOLEAN, left.instance.integer <= right.instance.integer };
258 Object operator$and(Object left, Object right)
260 assert(left.type == BOOLEAN);
261 assert(right.type == BOOLEAN);
263 Object result = { BOOLEAN, left.instance.boolean && right.instance.boolean };
267 Object operator$or(Object left, Object right)
269 assert(left.type == BOOLEAN);
270 assert(right.type == BOOLEAN);
272 Object result = { BOOLEAN, left.instance.boolean || right.instance.boolean };
276 {% if 'pow' in builtins %}
277 Object builtin$pow$implementation(size_t argc, Object* args)
281 Object base = args[0];
282 Object exponent = args[1];
284 assert(base.type == INTEGER);
285 assert(exponent.type == INTEGER);
288 result.type = INTEGER;
289 result.instance.integer = pow(base.instance.integer, exponent.instance.integer);
293 Object builtin$pow = { CLOSURE, (Instance)builtin$pow$implementation };
296 {% if 'print' in builtins %}
297 Object builtin$print$implementation(size_t argc, Object* args)
299 for(size_t i = 0; i < argc; i++)
301 Object output = args[i];
305 fputs(output.instance.boolean ? "true" : "false", stdout);
309 printf("%" PRId32, output.instance.integer);
313 // Using fwrite instead of printf to handle size_t length
314 printf("%s", output.instance.string);
322 // TODO Return something better
326 Object builtin$print = { CLOSURE, (Instance)builtin$print$implementation };
329 {% for function_definition in function_definition_list %}
330 Object user${{function_definition.name}}$implementation(size_t argc, Object* args)
332 Environment* environment = Environment_construct();
334 {% for statement in function_definition.statement_list %}
335 {{ generate_statement(statement) }}
338 Object result = {{ generate_statement(function_definition.statement_list[-1]) }}
339 Environment_destruct(environment);
343 Object user${{function_definition.name}} = { CLOSURE, (Instance)user${{function_definition.name}}$implementation };
346 int main(int argc, char** argv)
348 Environment* environment = Environment_construct();
350 // TODO Use the symbol from SYMBOL_LIST
351 {% for builtin in builtins %}
352 Environment_set(environment, "{{ builtin }}", builtin${{ builtin }});
355 {% for statement in statements %}
356 {{ generate_statement(statement) }}
359 Environment_destruct(environment);