typedef enum Builtin Builtin;
enum Builtin {
NIL,
+ POW,
PRINT
};
void Object_deinitialize(Object* self) {
}
+{% include "environment.c" %}
{% include "stack.c" %}
struct Thread;
typedef struct Thread Thread;
struct Thread {
+ Environment* environment;
Stack stack;
size_t program_counter;
};
void Thread_initialize(Thread* self, size_t program_counter) {
+ self->environment = Environment_construct();
Stack_initialize(&(self->stack));
self->program_counter = program_counter;
}
void Thread_deinitialize(Thread* self) {
+ Environment_destruct(self->environment);
Stack_deinitialize(&(self->stack));
}
void call(struct Thread* thread, const union Argument argument) {
assert(!Stack_isEmpty(&(thread->stack)));
Object f = Stack_pop(&(thread->stack));
+ size_t argumentCount = argument.label;
switch(f.type) {
case BUILTIN:
switch(f.value.builtin) {
+ case POW:
+ {
+ assert(argumentCount == 2);
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object exponent = Stack_pop(&(thread->stack));
+ assert(exponent.type == INTEGER);
+ assert(exponent.value.integer >= 0);
+
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object base = Stack_pop(&(thread->stack));
+ assert(base.type == INTEGER);
+
+ Object result;
+ result.type = INTEGER;
+ result.value.integer = 1;
+
+ while(exponent.value.integer > 0) {
+ result.value.integer *= base.value.integer;
+ exponent.value.integer--;
+ }
+
+ Stack_push(&(thread->stack), result);
+ }
+ break;
case PRINT:
{
// TODO Handle multiple arguments
}
}
+{% with name='add', operation='+' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
+
void drop(struct Thread* thread, const union Argument argument) {
assert(!Stack_isEmpty(&(thread->stack)));
Object result = Stack_pop(&(thread->stack));
void end(struct Thread* thread, const union Argument argument) {
}
-void push(struct Thread* thread, const union Argument argument) {
+{% with name='idiv', operation='/' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
+{% with name='mod', operation='%' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
+{% with name='mul', operation='*' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
+void pop(struct Thread* thread, const union Argument argument) {
char* argumentString = argument.string;
- Object result;
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object result = Stack_pop(&(thread->stack));
+
+ if(strcmp(argumentString, "print") == 0) {
+ assert(false);
+ } else if(strcmp(argumentString, "pow") == 0) {
+ assert(false);
+ }
+
+
+ Environment_set(thread->environment, argumentString, result);
+}
+
+void push(struct Thread* thread, const union Argument argument) {
+ char* argumentString = argument.string;
if(strcmp(argumentString, "print") == 0) {
+ Object result;
result.type = BUILTIN;
result.value.builtin = PRINT;
+ Stack_push(&(thread->stack), result);
+ } else if(strcmp(argumentString, "pow") == 0) {
+ Object result;
+ result.type = BUILTIN;
+ result.value.builtin = POW;
+ Stack_push(&(thread->stack), result);
} else {
- assert(false);
+ Environment_get_Result result = Environment_get(thread->environment, argumentString);
+ if(!result.found) {
+ fprintf(stderr, "Variable `%s` not found", argumentString);
+ assert(false);
+ }
+ Stack_push(&(thread->stack), result.result);
}
-
- Stack_push(&(thread->stack), result);
}
void push_integer(struct Thread* thread, const union Argument argument) {
Stack_push(&(thread->stack), result);
}
+{% with name='sub', operation='-' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
struct Instruction;
typedef const struct Instruction Instruction;
struct Instruction {