From 21eff156a3094c82ad85f8d3658fc1ac79c63da1 Mon Sep 17 00:00:00 2001 From: mryouse Date: Sat, 27 May 2023 01:08:47 +0000 Subject: multiplication --- chunk.d | 1 + compiler.d | 18 ++++++++++++++++++ dbg.d | 6 ++++-- vm.d | 7 +++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/chunk.d b/chunk.d index 18bf12d..02d2a69 100644 --- a/chunk.d +++ b/chunk.d @@ -187,6 +187,7 @@ enum OpCode { OP_POPB, OP_POP_SCOPE, OP_SUBTRACT, + OP_MULTIPLY, OP_NIL, OP_JUMP, diff --git a/compiler.d b/compiler.d index d55b7f5..f94aad3 100644 --- a/compiler.d +++ b/compiler.d @@ -240,6 +240,21 @@ class Compiler { return ValueType.NUMBER; } + void compileMultiply(Form[] args) { + if (args.length < 2) { + this.error(format("'*': expected [2+] arguments, received %d", args.length), -1); + this.advance(); + return; + } + ValueType vt = this.resolve(args[0], ValueType.NUMBER); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, args[0].line); + for (int i = 1; i < args.length; i++) { + vt = this.resolve(args[i], ValueType.NUMBER); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, args[i].line); + this.func.chunk.writeOp(OpCode.OP_MULTIPLY, args[i].line); + } + } + //ValueType compileLess(Form[] args, ValueType expected = ValueType.ANY) { ValueType compileLess(Form[] args, ValueType expected) { if (args.length != 2) { @@ -833,6 +848,9 @@ class Compiler { return this.compileSubtract(cons.tail, ValueType.NUMBER); } break; + case "*": + this.compileMultiply(cons.tail); + break; // BOOLEAN case "<": diff --git a/dbg.d b/dbg.d index b9aad21..6958a05 100644 --- a/dbg.d +++ b/dbg.d @@ -8,8 +8,8 @@ import parser; //import dbg; //import value; -bool DEBUG = true; -//bool DEBUG = false; +//bool DEBUG = true; +bool DEBUG = false; void printForm(Form f, string prefix = "") { @@ -177,6 +177,8 @@ int disassemble(Chunk chunk, int offset) { return listInstruction("OP_LIST", chunk, offset); case OpCode.OP_ADD: return simpleInstruction("OP_ADD", offset); + case OpCode.OP_MULTIPLY: + return simpleInstruction("OP_MULTIPLY", offset); case OpCode.OP_LESS: return simpleInstruction("OP_LESS", offset); case OpCode.OP_GREATER: diff --git a/vm.d b/vm.d index ba7fc50..a865a50 100644 --- a/vm.d +++ b/vm.d @@ -500,6 +500,13 @@ class VM { double anum = asNumber(a); this.pushA(makeNumberValue(anum - bnum)); break; + case OpCode.OP_MULTIPLY: + Value b = this.popA(); + Value a = this.popA(); + double bnum = asNumber(b); + double anum = asNumber(a); + this.pushA(makeNumberValue(anum * bnum)); + break; case OpCode.OP_NOT: Value val = this.popA(); bool bval = asBoolean(val); -- cgit v1.2.3