mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-25 00:21:05 +00:00
Added modulo operator '%'
- added OP_MOD, which performs a modulo operation on the 2 <number> values on the stack. Pops the 2 values and pushes the result. - also added TOKEN_PERCENT to the lexer, and extended binary() in cparse.c to support it.
This commit is contained in:
parent
58485d9375
commit
84f7895684
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
CC=clang
|
CC=clang
|
||||||
CFLAGS=-fPIE -Wall -O3 -std=c11
|
CFLAGS=-fPIE -Wall -O3 -std=c11
|
||||||
LDFLAGS=#-fsanitize=address
|
LDFLAGS=-lm #-fsanitize=address
|
||||||
OUT=bin/cosmo
|
OUT=bin/cosmo
|
||||||
|
|
||||||
CHDR=\
|
CHDR=\
|
||||||
|
@ -144,6 +144,8 @@ int disasmInstr(CChunk *chunk, int offset, int indent) {
|
|||||||
return simpleInstruction("OP_MULT", offset);
|
return simpleInstruction("OP_MULT", offset);
|
||||||
case OP_DIV:
|
case OP_DIV:
|
||||||
return simpleInstruction("OP_DIV", offset);
|
return simpleInstruction("OP_DIV", offset);
|
||||||
|
case OP_MOD:
|
||||||
|
return simpleInstruction("OP_MOD", offset);
|
||||||
case OP_TRUE:
|
case OP_TRUE:
|
||||||
return simpleInstruction("OP_TRUE", offset);
|
return simpleInstruction("OP_TRUE", offset);
|
||||||
case OP_FALSE:
|
case OP_FALSE:
|
||||||
|
@ -308,6 +308,7 @@ CToken cosmoL_scanToken(CLexState *state) {
|
|||||||
case ',': return makeToken(state, TOKEN_COMMA);
|
case ',': return makeToken(state, TOKEN_COMMA);
|
||||||
case ':': return makeToken(state, TOKEN_COLON);
|
case ':': return makeToken(state, TOKEN_COLON);
|
||||||
case '*': return makeToken(state, TOKEN_STAR);
|
case '*': return makeToken(state, TOKEN_STAR);
|
||||||
|
case '%': return makeToken(state, TOKEN_PERCENT);
|
||||||
case '#': return makeToken(state, TOKEN_POUND);
|
case '#': return makeToken(state, TOKEN_POUND);
|
||||||
case '/': return makeToken(state, TOKEN_SLASH);
|
case '/': return makeToken(state, TOKEN_SLASH);
|
||||||
// two character tokens
|
// two character tokens
|
||||||
|
@ -23,6 +23,7 @@ typedef enum {
|
|||||||
TOKEN_SLASH,
|
TOKEN_SLASH,
|
||||||
TOKEN_STAR,
|
TOKEN_STAR,
|
||||||
TOKEN_POUND,
|
TOKEN_POUND,
|
||||||
|
TOKEN_PERCENT,
|
||||||
TOKEN_EOS, // end of statement
|
TOKEN_EOS, // end of statement
|
||||||
|
|
||||||
// equality operators
|
// equality operators
|
||||||
|
@ -37,6 +37,7 @@ typedef enum {
|
|||||||
OP_SUB,
|
OP_SUB,
|
||||||
OP_MULT,
|
OP_MULT,
|
||||||
OP_DIV,
|
OP_DIV,
|
||||||
|
OP_MOD,
|
||||||
OP_NOT,
|
OP_NOT,
|
||||||
OP_NEGATE,
|
OP_NEGATE,
|
||||||
OP_COUNT,
|
OP_COUNT,
|
||||||
|
@ -430,6 +430,7 @@ static void binary(CParseState *pstate, bool canAssign) {
|
|||||||
case TOKEN_MINUS: writeu8Chunk(pstate->state, getChunk(pstate), OP_SUB, cachedLine); break;
|
case TOKEN_MINUS: writeu8Chunk(pstate->state, getChunk(pstate), OP_SUB, cachedLine); break;
|
||||||
case TOKEN_STAR: writeu8Chunk(pstate->state, getChunk(pstate), OP_MULT, cachedLine); break;
|
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_SLASH: writeu8Chunk(pstate->state, getChunk(pstate), OP_DIV, cachedLine); break;
|
||||||
|
case TOKEN_PERCENT: writeu8Chunk(pstate->state, getChunk(pstate), OP_MOD, cachedLine); break;
|
||||||
// EQUALITY
|
// EQUALITY
|
||||||
case TOKEN_EQUAL_EQUAL: writeu8Chunk(pstate->state, getChunk(pstate), OP_EQUAL, cachedLine); break;
|
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;
|
case TOKEN_GREATER: writeu8Chunk(pstate->state, getChunk(pstate), OP_GREATER, cachedLine); break;
|
||||||
@ -730,6 +731,7 @@ ParseRule ruleTable[] = {
|
|||||||
[TOKEN_PLUS_PLUS] = {preincrement, NULL, PREC_TERM},
|
[TOKEN_PLUS_PLUS] = {preincrement, NULL, PREC_TERM},
|
||||||
[TOKEN_SLASH] = {NULL, binary, PREC_FACTOR},
|
[TOKEN_SLASH] = {NULL, binary, PREC_FACTOR},
|
||||||
[TOKEN_STAR] = {NULL, binary, PREC_FACTOR},
|
[TOKEN_STAR] = {NULL, binary, PREC_FACTOR},
|
||||||
|
[TOKEN_PERCENT] = {NULL, binary, PREC_FACTOR},
|
||||||
[TOKEN_POUND] = {unary, NULL, PREC_NONE},
|
[TOKEN_POUND] = {unary, NULL, PREC_NONE},
|
||||||
[TOKEN_EOS] = {NULL, NULL, PREC_NONE},
|
[TOKEN_EOS] = {NULL, NULL, PREC_NONE},
|
||||||
[TOKEN_BANG] = {unary, NULL, PREC_NONE},
|
[TOKEN_BANG] = {unary, NULL, PREC_NONE},
|
||||||
|
14
src/cvm.c
14
src/cvm.c
@ -6,6 +6,8 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
COSMO_API void cosmoV_pushFString(CState *state, const char *format, ...) {
|
COSMO_API void cosmoV_pushFString(CState *state, const char *format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
@ -802,6 +804,18 @@ int cosmoV_execute(CState *state) {
|
|||||||
NUMBEROP(cosmoV_newNumber, /)
|
NUMBEROP(cosmoV_newNumber, /)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OP_MOD: {
|
||||||
|
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(fmod(cosmoV_readNumber(*valA), cosmoV_readNumber(*valB))));
|
||||||
|
} else { \
|
||||||
|
cosmoV_error(state, "Expected numbers, got %s and %s!", cosmoV_typeStr(*valA), cosmoV_typeStr(*valB));
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OP_NOT: {
|
case OP_NOT: {
|
||||||
cosmoV_pushBoolean(state, isFalsey(cosmoV_pop(state)));
|
cosmoV_pushBoolean(state, isFalsey(cosmoV_pop(state)));
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user