{% include "environment.c" %}
{% include "stack.c" %}
+{% include "frame.c" %}
struct Thread;
typedef struct Thread Thread;
struct Thread {
Environment* environment;
Stack stack;
- size_t program_counter;
+ size_t programCounter;
};
-void Thread_initialize(Thread* self, size_t program_counter) {
+void Thread_initialize(Thread* self, size_t programCounter) {
self->environment = Environment_construct();
Stack_initialize(&(self->stack));
- self->program_counter = program_counter;
+ self->programCounter = programCounter;
}
void Thread_deinitialize(Thread* self) {
Stack_deinitialize(&(self->stack));
}
+Environment* Thread_getEnvironment(Thread* self) {
+ return self->environment;
+}
+
+void Thread_setProgramCounter(Thread* self, size_t programCounter) {
+ self->programCounter = programCounter;
+}
+
+void Thread_incrementProgramCounter(Thread* self) {
+ self->programCounter++;
+}
+
+size_t Thread_getProgramCounter(Thread* self) {
+ return self->programCounter;
+}
+
union Argument;
typedef const union Argument Argument;
union Argument {
break;
default:
- assert(0);
+ assert(false);
}
}
}
}
-void inst_call(struct Thread* thread, Argument argument) {
+void callClosure(Thread* thread, Closure closure, size_t argumentCount) {
+ assert(argumentCount == 0);
+
+
+}
+
+void inst_call(Thread* thread, Argument argument) {
assert(!Stack_isEmpty(&(thread->stack)));
Object f = Stack_pop(&(thread->stack));
size_t argumentCount = argument.label;
break;
case CLOSURE:
- {
- assert(false);
- }
+ callClosure(thread, f.value.closure, argumentCount);
break;
default:
{% endwith %}
void inst_close(Thread* thread, Argument argument) {
- assert(false);
+ Object result;
+ result.type = CLOSURE;
+ result.value.closure.environment = Thread_getEnvironment(thread);
+ result.value.closure.entry = argument.label;
+
+ Stack_push(&(thread->stack), result);
}
void inst_drop(Thread* thread, Argument argument) {
Object_deinitialize(&result);
}
-void inst_end(struct Thread* thread, Argument argument) {
+void inst_end(Thread* thread, Argument argument) {
}
{% with name='eq', operation='==' %}
{% endwith %}
void inst_jump(Thread* thread, Argument argument) {
- thread->program_counter = argument.label - 1; // We will increment before running
+ Thread_setProgramCounter(thread, argument.label - 1); // We will increment before running
}
void inst_jump_if_false(Thread* thread, Argument argument) {
Stack_push(&(thread->stack), result);
}
-void inst_pop(struct Thread* thread, Argument argument) {
+void inst_pop(Thread* thread, Argument argument) {
char* argumentString = argument.string;
assert(!Stack_isEmpty(&(thread->stack)));
}
- Environment_set(thread->environment, argumentString, result);
+ Environment_set(Thread_getEnvironment(thread), argumentString, result);
}
-void inst_push(struct Thread* thread, Argument argument) {
+void inst_push(Thread* thread, Argument argument) {
char* argumentString = argument.string;
if(strcmp(argumentString, "false") == 0) {
} else if(strcmp(argumentString, "true") == 0) {
Stack_push(&(thread->stack), (Object){ BOOLEAN, true });
} else {
- Environment_get_Result result = Environment_get(thread->environment, argumentString);
+ Environment_get_Result result = Environment_get(
+ Thread_getEnvironment(thread),
+ argumentString
+ );
if(!result.found) {
fprintf(stderr, "Variable `%s` not found", argumentString);
assert(false);
struct Instruction;
typedef const struct Instruction Instruction;
struct Instruction {
- void (*instruction)(struct Thread*,Argument);
+ void (*instruction)(Thread*,Argument);
Argument argument;
};
Thread thread;
Thread_initialize(&thread, LABEL___main__);
- for(; program[thread.program_counter].instruction != inst_end; thread.program_counter++) {
- program[thread.program_counter].instruction(
+ for(; program[Thread_getProgramCounter(&thread)].instruction != inst_end; Thread_incrementProgramCounter(&thread)) {
+ program[Thread_getProgramCounter(&thread)].instruction(
&thread,
- program[thread.program_counter].argument
+ program[Thread_getProgramCounter(&thread)].argument
);
}