From cbcf142f5760a365614003a2c1c5ab20277ddd7f Mon Sep 17 00:00:00 2001 From: David Wilson Date: Thu, 17 Mar 2022 18:59:32 +0200 Subject: [PATCH] language: Add modulo `%` operator that works on integers --- src/compiler.c | 3 +++ src/disasm.c | 2 ++ src/op.h | 1 + src/scanner.c | 2 ++ src/scanner.h | 1 + src/vm.c | 10 ++++++++++ 6 files changed, 19 insertions(+) diff --git a/src/compiler.c b/src/compiler.c index 6d6e6f3..b4f8528 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -953,6 +953,9 @@ static void compiler_parse_operator_call(CompilerContext *ctx, Token *call_token case TokenKindSlash: compiler_emit_byte(ctx, OP_DIVIDE); break; + case TokenKindPercent: + compiler_emit_byte(ctx, OP_MODULO); + break; case TokenKindAnd: compiler_emit_byte(ctx, OP_AND); break; diff --git a/src/disasm.c b/src/disasm.c index 1b88b75..f972386 100644 --- a/src/disasm.c +++ b/src/disasm.c @@ -72,6 +72,8 @@ int mesche_disasm_instr(Chunk *chunk, int offset) { return mesche_disasm_simple_instr("OP_MULTIPLY", offset); case OP_DIVIDE: return mesche_disasm_simple_instr("OP_DIVIDE", offset); + case OP_MODULO: + return mesche_disasm_simple_instr("OP_MODULO", offset); case OP_NEGATE: return mesche_disasm_simple_instr("OP_NEGATE", offset); case OP_AND: diff --git a/src/op.h b/src/op.h index 91dc507..f05b4c5 100644 --- a/src/op.h +++ b/src/op.h @@ -13,6 +13,7 @@ typedef enum { OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE, + OP_MODULO, OP_NEGATE, // TODO: Remove in favor of SUBTRACT! OP_AND, OP_OR, diff --git a/src/scanner.c b/src/scanner.c index 37b5081..4a5c2c0 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -320,6 +320,8 @@ Token mesche_scanner_next_token(Scanner *scanner) { return scanner_make_token(scanner, TokenKindStar); case '/': return scanner_make_token(scanner, TokenKindSlash); + case '%': + return scanner_make_token(scanner, TokenKindPercent); case '>': { if (scanner_peek(scanner) == '=') { scanner_next_char(scanner); diff --git a/src/scanner.h b/src/scanner.h index 8ad9597..ca5e323 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -21,6 +21,7 @@ typedef enum { TokenKindMinus, TokenKindStar, TokenKindSlash, + TokenKindPercent, TokenKindAnd, TokenKindOr, TokenKindNot, diff --git a/src/vm.c b/src/vm.c index bd02904..b7b08a0 100644 --- a/src/vm.c +++ b/src/vm.c @@ -751,6 +751,16 @@ InterpretResult mesche_vm_run(VM *vm) { case OP_DIVIDE: BINARY_OP(NUMBER_VAL, IS_NUMBER, AS_NUMBER, /); break; + case OP_MODULO: { + if (!IS_NUMBER(vm_stack_peek(vm, 0)) || !IS_NUMBER(vm_stack_peek(vm, 1))) { + vm_runtime_error(vm, "Operands must be numbers."); + return INTERPRET_RUNTIME_ERROR; + } + int b = (int)AS_NUMBER(mesche_vm_stack_pop(vm)); + int a = (int)AS_NUMBER(mesche_vm_stack_pop(vm)); + mesche_vm_stack_push(vm, NUMBER_VAL(a % b)); + break; + } case OP_AND: BINARY_OP(BOOL_VAL, IS_ANY, AS_BOOL, &&); break;