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 {% for od in operator_declarations %}
164 Object operator${{ od.name }}(Object left, Object right)
166 assert(left.type == {{ od.input_type.upper() }});
167 assert(right.type == {{ od.input_type.upper() }});
170 result.type = {{ od.result_type.upper() }};
171 result.instance.{{ od.result_type.lower() }} = left.instance.{{ od.input_type.lower() }} {{ od.c_operator }} right.instance.{{ od.input_type.lower() }};
176 Object operator$equals(Object left, Object right)
178 assert(left.type == INTEGER);
179 assert(right.type == INTEGER);
181 Object result = { BOOLEAN, { left.instance.integer == right.instance.integer } };
185 Object operator$notEquals(Object left, Object right)
187 assert(left.type == INTEGER);
188 assert(right.type == INTEGER);
190 Object result = { BOOLEAN, { left.instance.integer != right.instance.integer } };
194 Object operator$greaterThan(Object left, Object right)
196 assert(left.type == INTEGER);
197 assert(right.type == INTEGER);
199 Object result = { BOOLEAN, { left.instance.integer > right.instance.integer } };
203 Object operator$lessThan(Object left, Object right)
205 assert(left.type == INTEGER);
206 assert(right.type == INTEGER);
208 Object result = { BOOLEAN, { left.instance.integer < right.instance.integer } };
212 Object operator$greaterThanOrEqual(Object left, Object right)
214 assert(left.type == INTEGER);
215 assert(right.type == INTEGER);
217 Object result = { BOOLEAN, { left.instance.integer >= right.instance.integer } };
221 Object operator$lessThanOrEqual(Object left, Object right)
223 assert(left.type == INTEGER);
224 assert(right.type == INTEGER);
226 Object result = { BOOLEAN, { left.instance.integer <= right.instance.integer } };
230 {% if 'pow' in builtins %}
231 Object builtin$pow$implementation(Environment* parent, size_t argc, Object* args)
235 Object base = args[0];
236 Object exponent = args[1];
238 assert(base.type == INTEGER);
239 assert(exponent.type == INTEGER);
242 result.type = INTEGER;
243 result.instance.integer = pow(base.instance.integer, exponent.instance.integer);
247 Object builtin$pow = { CLOSURE, (Instance)builtin$pow$implementation };
250 {% if 'print' in builtins %}
251 Object builtin$print$implementation(Environment* parent, size_t argc, Object* args)
253 for(size_t i = 0; i < argc; i++)
255 Object output = args[i];
259 fputs(output.instance.boolean ? "true" : "false", stdout);
263 printf("%" PRId32, output.instance.integer);
267 // Using fwrite instead of printf to handle size_t length
268 printf("%s", output.instance.string);
276 // TODO Return something better
280 Object builtin$print = { CLOSURE, (Instance)builtin$print$implementation };
283 {% for function_definition in function_definition_list %}
284 Object user${{function_definition.name}}$implementation(Environment* parent, size_t argc, Object* args)
286 Environment* environment = Environment_construct(parent);
288 {% for statement in function_definition.statement_list[:-1] %}
289 {{ generate_statement(statement) }}
292 Object result = {{ generate_statement(function_definition.statement_list[-1]) }}
293 Environment_destruct(environment);
297 Object user${{function_definition.name}} = { CLOSURE, (Instance)user${{function_definition.name}}$implementation };
300 int main(int argc, char** argv)
302 Environment* environment = Environment_construct(NULL);
304 // TODO Use the symbol from SYMBOL_LIST
305 {% for builtin in builtins %}
306 Environment_set(environment, "{{ builtin }}", builtin${{ builtin }});
309 {% for statement in statements %}
310 {{ generate_statement(statement) }}
313 Environment_destruct(environment);