add % operator

This commit is contained in:
K Lange 2020-12-28 16:32:27 +09:00
parent 27f888543d
commit b32dde0431
6 changed files with 12 additions and 1 deletions

View File

@ -19,6 +19,7 @@ typedef enum {
OP_SUBTRACT,
OP_MULTIPLY,
OP_DIVIDE,
OP_MODULO,
OP_NONE,
OP_TRUE,
OP_FALSE,

View File

@ -301,6 +301,7 @@ static void binary(int canAssign) {
case TOKEN_MINUS: emitByte(OP_SUBTRACT); break;
case TOKEN_ASTERISK: emitByte(OP_MULTIPLY); break;
case TOKEN_SOLIDUS: emitByte(OP_DIVIDE); break;
case TOKEN_MODULO: emitByte(OP_MODULO); break;
default: return;
}
}
@ -732,7 +733,6 @@ static void forStatement() {
/* LOOP STARTS HERE */
loopStart = currentChunk()->count;
emitByte(0xFF);
/* Call the iterator */
EMIT_CONSTANT_OP(OP_GET_LOCAL, indLoopIter);
@ -971,6 +971,7 @@ ParseRule rules[] = {
[TOKEN_SEMICOLON] = {NULL, NULL, PREC_NONE},
[TOKEN_SOLIDUS] = {NULL, binary, PREC_FACTOR},
[TOKEN_ASTERISK] = {NULL, binary, PREC_FACTOR},
[TOKEN_MODULO] = {NULL, binary, PREC_FACTOR},
[TOKEN_BANG] = {unary, NULL, PREC_NONE},
[TOKEN_BANG_EQUAL] = {NULL, binary, PREC_EQUALITY},
[TOKEN_EQUAL] = {NULL, NULL, PREC_NONE},

View File

@ -62,6 +62,7 @@ size_t krk_disassembleInstruction(KrkChunk * chunk, size_t offset) {
SIMPLE(OP_MULTIPLY)
SIMPLE(OP_DIVIDE)
SIMPLE(OP_NEGATE)
SIMPLE(OP_MODULO)
SIMPLE(OP_NONE)
SIMPLE(OP_TRUE)
SIMPLE(OP_FALSE)

View File

@ -282,6 +282,7 @@ KrkToken krk_scanToken() {
case ';': return makeToken(TOKEN_SEMICOLON);
case '/': return makeToken(TOKEN_SOLIDUS);
case '*': return makeToken(TOKEN_ASTERISK);
case '%': return makeToken(TOKEN_MODULO);
case '!': return makeToken(match('=') ? TOKEN_BANG_EQUAL : TOKEN_BANG);
case '=': return makeToken(match('=') ? TOKEN_EQUAL_EQUAL : TOKEN_EQUAL);

View File

@ -44,6 +44,7 @@ typedef enum {
TOKEN_EOL, /* 47 */
TOKEN_EXPORT, /* 48 */
TOKEN_MODULO,
TOKEN_ERROR,
TOKEN_EOF,

6
vm.c
View File

@ -455,6 +455,11 @@ MAKE_BIN_OP(subtract,-)
MAKE_BIN_OP(multiply,*)
MAKE_BIN_OP(divide,/)
static KrkValue modulo(KrkValue a, KrkValue b) {
if (!IS_INTEGER(a) || !IS_INTEGER(b)) return NONE_VAL();
return INTEGER_VAL(AS_INTEGER(a) % AS_INTEGER(b));
}
#define MAKE_COMPARATOR(name, operator) \
static KrkValue name (KrkValue a, KrkValue b) { \
if (IS_INTEGER(a) && IS_INTEGER(b)) return BOOLEAN_VAL(AS_INTEGER(a) operator AS_INTEGER(b)); \
@ -676,6 +681,7 @@ static KrkValue run() {
case OP_SUBTRACT: BINARY_OP(subtract)
case OP_MULTIPLY: BINARY_OP(multiply)
case OP_DIVIDE: BINARY_OP(divide)
case OP_MODULO: BINARY_OP(modulo)
case OP_NEGATE: {
KrkValue value = krk_pop();
if (IS_INTEGER(value)) krk_push(INTEGER_VAL(-AS_INTEGER(value)));