X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=templates%2Fprogram2.c;h=180a4c79efb2e120ecb332f4c2b14627ac5dde15;hp=8602054d666f93c206724e184b9c53d752939027;hb=4efcfd00920263da31dc2bb216050df4041299e7;hpb=c7f381fbcb57ba1b7e33558a28fdb34f31234c07 diff --git a/templates/program2.c b/templates/program2.c index 8602054..180a4c7 100644 --- a/templates/program2.c +++ b/templates/program2.c @@ -8,6 +8,7 @@ enum Type; typedef enum Type Type; enum Type { + BOOLEAN, BUILTIN, INTEGER, STRING @@ -25,6 +26,7 @@ union Value; typedef union Value Value; union Value { Builtin builtin; + bool boolean; char* string; int32_t integer; }; @@ -111,6 +113,11 @@ void call(struct Thread* thread, Argument argument) { Object arg = Stack_pop(&(thread->stack)); switch(arg.type) { + case BOOLEAN: + if(arg.value.boolean) printf("true"); + else printf("false"); + break; + case INTEGER: printf("%i", arg.value.integer); break; @@ -151,10 +158,44 @@ void drop(struct Thread* thread, Argument argument) { void end(struct Thread* thread, Argument argument) { } +{% with name='eq', operation='==' %} + {% include "comparison_instruction.c" %} +{% endwith %} + +{% with name='gt', operation='>' %} + {% include "comparison_instruction.c" %} +{% endwith %} + +{% with name='gte', operation='>=' %} + {% include "comparison_instruction.c" %} +{% endwith %} + {% with name='idiv', operation='/' %} {% include "arithmetic_instruction.c" %} {% endwith %} +void jump(Thread* thread, Argument argument) { + thread->program_counter = argument.label - 1; // We will increment before running +} + +void jump_if_false(Thread* thread, Argument argument) { + assert(!Stack_isEmpty(&(thread->stack))); + Object result = Stack_pop(&(thread->stack)); + assert(result.type == BOOLEAN); + + if(!(result.value.boolean)) { + jump(thread, argument); + } +} + +{% with name='lt', operation='<' %} + {% include "comparison_instruction.c" %} +{% endwith %} + +{% with name='lte', operation='<=' %} + {% include "comparison_instruction.c" %} +{% endwith %} + {% with name='mod', operation='%' %} {% include "arithmetic_instruction.c" %} {% endwith %} @@ -163,7 +204,11 @@ void end(struct Thread* thread, Argument argument) { {% include "arithmetic_instruction.c" %} {% endwith %} -void neg(struct Thread* thread, Argument argument) { +{% with name='neq', operation='!=' %} + {% include "comparison_instruction.c" %} +{% endwith %} + +void neg(Thread* thread, Argument argument) { assert(!Stack_isEmpty(&(thread->stack))); Object result = Stack_pop(&(thread->stack)); assert(result.type == INTEGER); @@ -192,16 +237,20 @@ void pop(struct Thread* thread, Argument argument) { void push(struct Thread* thread, Argument argument) { char* argumentString = argument.string; - if(strcmp(argumentString, "print") == 0) { + if(strcmp(argumentString, "false") == 0) { + Stack_push(&(thread->stack), (Object){ BOOLEAN, false }); + }else if(strcmp(argumentString, "pow") == 0) { Object result; result.type = BUILTIN; - result.value.builtin = PRINT; + result.value.builtin = POW; Stack_push(&(thread->stack), result); - } else if(strcmp(argumentString, "pow") == 0) { + } else if(strcmp(argumentString, "print") == 0) { Object result; result.type = BUILTIN; - result.value.builtin = POW; + result.value.builtin = PRINT; Stack_push(&(thread->stack), result); + } else if(strcmp(argumentString, "true") == 0) { + Stack_push(&(thread->stack), (Object){ BOOLEAN, true }); } else { Environment_get_Result result = Environment_get(thread->environment, argumentString); if(!result.found) { @@ -251,7 +300,7 @@ const Instruction program[] = { int main() { Thread thread; - Thread_initialize(&thread, 0); + Thread_initialize(&thread, LABEL___main__); for(; program[thread.program_counter].instruction != end; thread.program_counter++) { program[thread.program_counter].instruction(