From: David Kerkeslager Date: Tue, 1 Oct 2019 05:06:40 +0000 (-0400) Subject: Implement pow X-Git-Url: https://code.kerkeslager.com/?a=commitdiff_plain;ds=inline;h=379bdcf727cc66ee58d36a112e306b81e427fcf1;hp=b7a244b6319f5c770582283097f6184e5a6ec192;p=fur Implement pow --- diff --git a/templates/program2.c b/templates/program2.c index 8abe2a2..76fc2f8 100644 --- a/templates/program2.c +++ b/templates/program2.c @@ -17,6 +17,7 @@ enum Builtin; typedef enum Builtin Builtin; enum Builtin { NIL, + POW, PRINT }; @@ -74,10 +75,35 @@ union Argument { 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 @@ -145,8 +171,11 @@ void pop(struct Thread* thread, const union Argument argument) { if(strcmp(argumentString, "print") == 0) { assert(false); + } else if(strcmp(argumentString, "pow") == 0) { + assert(false); } + Environment_set(thread->environment, argumentString, result); } @@ -158,6 +187,11 @@ void push(struct Thread* thread, const union Argument argument) { 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 { Environment_get_Result result = Environment_get(thread->environment, argumentString); if(!result.found) {