Added power operator '^', added OP_POW

- added TOKEN_CARROT to clex.[ch]
This commit is contained in:
cpunch 2021-02-10 17:26:20 -06:00
parent 24bbc22cd4
commit 1539a7e676
5 changed files with 20 additions and 3 deletions

View File

@ -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

View File

@ -24,6 +24,7 @@ typedef enum {
TOKEN_STAR,
TOKEN_POUND,
TOKEN_PERCENT,
TOKEN_CARROT,
TOKEN_EOS, // end of statement
// equality operators

View File

@ -40,6 +40,7 @@ typedef enum {
OP_MULT,
OP_DIV,
OP_MOD,
OP_POW,
OP_NOT,
OP_NEGATE,
OP_COUNT,

View File

@ -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},

View File

@ -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: {