X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=templates%2Fprogram2.c;h=01203fd92eb47ac133e0667280bc3759ef84d05c;hp=f51cdbfa9788db5101ac1f46d7b1f170f1cbf773;hb=c24be69b26aedc427c7831f150e86ca00182d8e0;hpb=5e3bb8aa55a25e2ced307e06f6579c027749ff0e diff --git a/templates/program2.c b/templates/program2.c index f51cdbf..01203fd 100644 --- a/templates/program2.c +++ b/templates/program2.c @@ -14,6 +14,7 @@ enum Type { INTEGER, LIST, STRING, + STRUCTURE, SYMBOL }; @@ -42,6 +43,9 @@ struct Closure { struct List; typedef struct List List; +struct Structure; +typedef struct Structure Structure; + union Value; typedef union Value Value; union Value { @@ -51,6 +55,7 @@ union Value { int32_t integer; List* list; char* string; + Structure* structure; char* symbol; }; @@ -64,6 +69,12 @@ struct List { List* tail; }; +struct Structure { + char* key; + Object value; + Structure* next; +}; + #define BUILTIN_NIL (Object) { BUILTIN, (Value)(Builtin)NIL } void Object_deinitialize(Object* self) { @@ -178,6 +189,7 @@ void callBuiltin(Thread* thread, Builtin b, size_t argumentCount) { case POW: callBuiltinPow(thread, argumentCount); break; + case PRINT: callBuiltinPrint(thread, argumentCount); break; @@ -188,7 +200,7 @@ void callBuiltin(Thread* thread, Builtin b, size_t argumentCount) { } void callClosure(Thread* thread, Closure closure, size_t argumentCount) { - assert(argumentCount == 0); + // TODO Find a way to assert the argument count Frame* returnFrame = malloc(sizeof(Frame)); *returnFrame = thread->frame; @@ -268,17 +280,37 @@ void inst_end(Thread* thread, Argument argument) { {% include "comparison_instruction.c" %} {% endwith %} -void inst_get(Thread* thread, Argument argument) { +void inst_field(Thread* thread, Argument argument) { assert(!Stack_isEmpty(&(thread->stack))); - Object listObject = Stack_pop(&(thread->stack)); - assert(listObject.type == LIST); - List* list = listObject.value.list; + Object key = Stack_pop(&(thread->stack)); + assert(key.type == SYMBOL); + + assert(!Stack_isEmpty(&(thread->stack))); + Object structure = Stack_pop(&(thread->stack)); + assert(structure.type == STRUCTURE); + while(structure.value.structure != NULL) { + if(strcmp(structure.value.structure->key, key.value.string) == 0) { + Stack_push(&(thread->stack), structure.value.structure->value); + return; + } + structure.value.structure = structure.value.structure->next; + } + + assert(false); // Symbol wasn't found in structure +} + +void inst_get(Thread* thread, Argument argument) { assert(!Stack_isEmpty(&(thread->stack))); Object indexObject = Stack_pop(&(thread->stack)); assert(indexObject.type == INTEGER); int32_t index = indexObject.value.integer; + assert(!Stack_isEmpty(&(thread->stack))); + Object listObject = Stack_pop(&(thread->stack)); + assert(listObject.type == LIST); + List* list = listObject.value.list; + while(index > 0) { assert(list != NULL); list = list->tail; @@ -320,7 +352,9 @@ void inst_list(Thread* thread, Argument argument) { result.type = LIST; result.value.list = NULL; - while(argument.integer > 0) { + int32_t count = argument.integer; + + while(count > 0) { assert(!Stack_isEmpty(&(thread->stack))); Object item = Stack_pop(&(thread->stack)); @@ -329,6 +363,7 @@ void inst_list(Thread* thread, Argument argument) { node->tail = result.value.list; result.value.list = node; + count--; } Stack_push(&(thread->stack), result); @@ -385,7 +420,7 @@ void inst_push(Thread* thread, Argument argument) { if(strcmp(argumentString, "false") == 0) { Stack_push(&(thread->stack), (Object){ BOOLEAN, false }); - }else if(strcmp(argumentString, "pow") == 0) { + } else if(strcmp(argumentString, "pow") == 0) { Object result; result.type = BUILTIN; result.value.builtin = POW; @@ -432,6 +467,8 @@ void inst_push_symbol(Thread* thread, Argument argument) { Object result; result.type = SYMBOL; result.value.symbol = argument.symbol; + + Stack_push(&(thread->stack), result); } {% with name='sub', operation='-' %} @@ -454,7 +491,30 @@ void inst_return(Thread* thread, Argument argument) { } void inst_structure(Thread* thread, Argument argument) { - assert(false); + Object result; + result.type = STRUCTURE; + result.value.structure = NULL; + + int32_t count = argument.integer; + + while(count > 0) { + assert(!Stack_isEmpty(&(thread->stack))); + Object key = Stack_pop(&(thread->stack)); + assert(key.type == SYMBOL); + + assert(!Stack_isEmpty(&(thread->stack))); + Object value = Stack_pop(&(thread->stack)); + + Structure* node = malloc(sizeof(Structure)); + node->key = key.value.string; + node->value = value; + node->next = result.value.structure; + + result.value.structure = node; + count--; + } + + Stack_push(&(thread->stack), result); } struct Instruction;