X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=templates%2Fprogram2.c;h=89d80de7fbe1561096efb71fe51dc53b23b9c8b7;hp=1610a540db5c977f832eb7e163feda85395b5c5b;hb=3dc627f8d6b5846081ef8ed15d5546e51d2ecb8d;hpb=d28e140fd317ef3d63286ba6d87eb0418ee536c9 diff --git a/templates/program2.c b/templates/program2.c index 1610a54..89d80de 100644 --- a/templates/program2.c +++ b/templates/program2.c @@ -108,25 +108,36 @@ void call(struct Thread* thread, Argument argument) { break; case PRINT: { - // TODO Handle multiple arguments - assert(!Stack_isEmpty(&(thread->stack))); - 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; - - case STRING: - printf("%s", arg.value.string); - break; - - default: - assert(0); + assert(argumentCount > 0); + + Object arguments[argumentCount]; + size_t count; + + for(count = 0; count < argumentCount; count++) { + assert(!Stack_isEmpty(&(thread->stack))); + arguments[argumentCount - count - 1] = Stack_pop(&(thread->stack)); + } + + for(count = 0; count < argumentCount; count ++) { + Object arg = arguments[count]; + + switch(arg.type) { + case BOOLEAN: + if(arg.value.boolean) printf("true"); + else printf("false"); + break; + + case INTEGER: + printf("%i", arg.value.integer); + break; + + case STRING: + printf("%s", arg.value.string); + break; + + default: + assert(0); + } } Stack_push(&(thread->stack), BUILTIN_NIL); @@ -157,10 +168,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 %} @@ -169,7 +214,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); @@ -261,7 +310,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(