9 typedef enum Type Type;
17 typedef enum Builtin Builtin;
24 typedef union Value Value;
32 typedef struct Object Object;
38 #define BUILTIN_NIL (Object) { BUILTIN, (Value)(Builtin)NIL }
40 void Object_deinitialize(Object* self) {
43 {% include "stack.c" %}
46 typedef struct Thread Thread;
49 size_t program_counter;
52 void Thread_initialize(Thread* self, size_t program_counter) {
53 Stack_initialize(&(self->stack));
54 self->program_counter = program_counter;
57 void Thread_deinitialize(Thread* self) {
58 Stack_deinitialize(&(self->stack));
62 typedef const union Argument Argument;
70 void call(struct Thread* thread, const union Argument argument) {
71 assert(!Stack_isEmpty(&(thread->stack)));
72 Object f = Stack_pop(&(thread->stack));
76 switch(f.value.builtin) {
79 // TODO Handle multiple arguments
80 assert(!Stack_isEmpty(&(thread->stack)));
81 Object arg = Stack_pop(&(thread->stack));
85 printf("%i", arg.value.integer);
89 printf("%s", arg.value.string);
96 Stack_push(&(thread->stack), BUILTIN_NIL);
110 void drop(struct Thread* thread, const union Argument argument) {
111 assert(!Stack_isEmpty(&(thread->stack)));
112 Object result = Stack_pop(&(thread->stack));
113 Object_deinitialize(&result);
116 void end(struct Thread* thread, const union Argument argument) {
119 void push(struct Thread* thread, const union Argument argument) {
120 char* argumentString = argument.string;
124 if(strcmp(argumentString, "print") == 0) {
125 result.type = BUILTIN;
126 result.value.builtin = PRINT;
131 Stack_push(&(thread->stack), result);
134 void push_integer(struct Thread* thread, const union Argument argument) {
136 result.type = INTEGER;
137 result.value.integer = argument.integer;
139 Stack_push(&(thread->stack), result);
142 void push_string(struct Thread* thread, const union Argument argument) {
144 result.type = STRING;
145 result.value.string = argument.string;
147 Stack_push(&(thread->stack), result);
151 typedef const struct Instruction Instruction;
153 void (*instruction)(struct Thread*,const union Argument);
157 {% for label in labels_to_instruction_indices.keys() %}
158 #define LABEL_{{ label }} {{ labels_to_instruction_indices[label] }}
161 const Instruction program[] = {
162 {% for instruction in instruction_list %}
163 (Instruction){ {{ instruction.instruction }}, (Argument){{ generate_argument(instruction) }} },
169 Thread_initialize(&thread, 0);
171 for(; program[thread.program_counter].instruction != end; thread.program_counter++) {
172 program[thread.program_counter].instruction(
174 program[thread.program_counter].argument
178 Thread_deinitialize(&thread);