From 1539a7e67600d59595b02aa47799ff69a776072a Mon Sep 17 00:00:00 2001 From: cpunch Date: Wed, 10 Feb 2021 17:26:20 -0600 Subject: [PATCH] Added power operator '^', added OP_POW - added TOKEN_CARROT to clex.[ch] --- src/clex.c | 1 + src/clex.h | 1 + src/coperators.h | 1 + src/cparse.c | 2 ++ src/cvm.c | 18 +++++++++++++++--- 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/clex.c b/src/clex.c index e27b645..1640f47 100644 --- a/src/clex.c +++ b/src/clex.c @@ -391,6 +391,7 @@ CToken cosmoL_scanToken(CLexState *state) { case ':': return makeToken(state, TOKEN_COLON); case '*': return makeToken(state, TOKEN_STAR); case '%': return makeToken(state, TOKEN_PERCENT); + case '^': return makeToken(state, TOKEN_CARROT); case '#': return makeToken(state, TOKEN_POUND); case '/': return makeToken(state, TOKEN_SLASH); // two character tokens diff --git a/src/clex.h b/src/clex.h index 552b3c7..f8229a6 100644 --- a/src/clex.h +++ b/src/clex.h @@ -24,6 +24,7 @@ typedef enum { TOKEN_STAR, TOKEN_POUND, TOKEN_PERCENT, + TOKEN_CARROT, TOKEN_EOS, // end of statement // equality operators diff --git a/src/coperators.h b/src/coperators.h index 9e027c9..18c7b56 100644 --- a/src/coperators.h +++ b/src/coperators.h @@ -40,6 +40,7 @@ typedef enum { OP_MULT, OP_DIV, OP_MOD, + OP_POW, OP_NOT, OP_NEGATE, OP_COUNT, diff --git a/src/cparse.c b/src/cparse.c index bc7a8ee..7a835db 100644 --- a/src/cparse.c +++ b/src/cparse.c @@ -465,6 +465,7 @@ static void binary(CParseState *pstate, bool canAssign, Precedence prec) { case TOKEN_STAR: writeu8Chunk(pstate->state, getChunk(pstate), OP_MULT, cachedLine); break; case TOKEN_SLASH: writeu8Chunk(pstate->state, getChunk(pstate), OP_DIV, cachedLine); break; case TOKEN_PERCENT: writeu8Chunk(pstate->state, getChunk(pstate), OP_MOD, cachedLine); break; + case TOKEN_CARROT: writeu8Chunk(pstate->state, getChunk(pstate), OP_POW, cachedLine); break; // EQUALITY case TOKEN_EQUAL_EQUAL: writeu8Chunk(pstate->state, getChunk(pstate), OP_EQUAL, cachedLine); break; case TOKEN_GREATER: writeu8Chunk(pstate->state, getChunk(pstate), OP_GREATER, cachedLine); break; @@ -921,6 +922,7 @@ ParseRule ruleTable[] = { [TOKEN_SLASH] = {NULL, binary, PREC_FACTOR}, [TOKEN_STAR] = {NULL, binary, PREC_FACTOR}, [TOKEN_PERCENT] = {NULL, binary, PREC_FACTOR}, + [TOKEN_CARROT] = {NULL, binary, PREC_FACTOR}, [TOKEN_POUND] = {unary, NULL, PREC_NONE}, [TOKEN_EOS] = {NULL, NULL, PREC_NONE}, [TOKEN_BANG] = {unary, NULL, PREC_NONE}, diff --git a/src/cvm.c b/src/cvm.c index e58074c..68a56dc 100644 --- a/src/cvm.c +++ b/src/cvm.c @@ -981,10 +981,22 @@ int cosmoV_execute(CState *state) { if (IS_NUMBER(*valA) && IS_NUMBER(*valB)) { cosmoV_setTop(state, 2); /* pop the 2 values */ cosmoV_pushValue(state, cosmoV_newNumber(fmod(cosmoV_readNumber(*valA), cosmoV_readNumber(*valB)))); - } else { \ + } else { cosmoV_error(state, "Expected numbers, got %s and %s!", cosmoV_typeStr(*valA), cosmoV_typeStr(*valB)); - return -1; \ - } \ + return -1; + } + continue; + } + case OP_POW: { + StkPtr valA = cosmoV_getTop(state, 1); + StkPtr valB = cosmoV_getTop(state, 0); + if (IS_NUMBER(*valA) && IS_NUMBER(*valB)) { + cosmoV_setTop(state, 2); /* pop the 2 values */ + cosmoV_pushValue(state, cosmoV_newNumber(pow(cosmoV_readNumber(*valA), cosmoV_readNumber(*valB)))); + } else { + cosmoV_error(state, "Expected numbers, got %s and %s!", cosmoV_typeStr(*valA), cosmoV_typeStr(*valB)); + return -1; + } continue; } case OP_NOT: {