From a1dbc40961e19ae7cce4163e314fe013353380a2 Mon Sep 17 00:00:00 2001 From: Andre Wagner Date: Sat, 2 May 2026 08:19:20 -0500 Subject: [PATCH] . --- doc/OPCODES | 1 + src/vm/expr.cc | 2 + src/vm/expr.hh | 2 +- src/vm/instruction.cc | 2 + src/vm/instruction.hh | 1 + src/vm/tests.cc | 1 + src/vm/vm.cc | 105 +++++++++++++++--------------------------- 7 files changed, 44 insertions(+), 70 deletions(-) diff --git a/doc/OPCODES b/doc/OPCODES index f809bae..06676fb 100644 --- a/doc/OPCODES +++ b/doc/OPCODES @@ -68,6 +68,7 @@ Logical/arithmetic: 2e pow Power 2f shl Shift left 30 shr Shift right +31 mod Modulo Other value operations: 40 len Get table, array or string size diff --git a/src/vm/expr.cc b/src/vm/expr.cc index f81172a..e875725 100644 --- a/src/vm/expr.cc +++ b/src/vm/expr.cc @@ -53,6 +53,8 @@ static int init_ = []() { BIN_OP(ShiftRight, Integer, Integer) { return Value::CreateInteger(a.as_integer() >> b.as_integer()); }; + BIN_OP(Modulo, Integer, Integer) { return Value::CreateInteger(a.as_integer() % b.as_integer()); }; + #undef BIN_OP return 0; diff --git a/src/vm/expr.hh b/src/vm/expr.hh index 655a390..a0bc4dd 100644 --- a/src/vm/expr.hh +++ b/src/vm/expr.hh @@ -7,7 +7,7 @@ namespace tyche::vm { enum class BinaryOperationType { Sum, Subtraction, Multiplication, Division, IntegerDivision, Equality, Inequality, LessThan, LessThanOrEquals, - GreaterThan, GreaterThanOrEquals, BitwiseAnd, BitwiseOr, BitwiseXor, Power, ShiftLeft, ShiftRight, + GreaterThan, GreaterThanOrEquals, BitwiseAnd, BitwiseOr, BitwiseXor, Power, ShiftLeft, ShiftRight, Modulo, COUNT }; diff --git a/src/vm/instruction.cc b/src/vm/instruction.cc index f60f0b9..f739b0a 100644 --- a/src/vm/instruction.cc +++ b/src/vm/instruction.cc @@ -46,6 +46,7 @@ const std::unordered_map instruction_names = { { "pow", Instruction::Power }, { "shl", Instruction::ShiftLeft }, { "shr", Instruction::ShiftRight }, + { "mod", Instruction::Modulo }, { "len", Instruction::Len }, { "type", Instruction::Type }, { "cast", Instruction::Cast }, @@ -133,6 +134,7 @@ std::pair debug_instruction(Instruction inst, int oper) case Instruction::Power: out = "pow"; break; case Instruction::ShiftLeft: out = "shl"; break; case Instruction::ShiftRight: out = "shr"; break; + case Instruction::Modulo: out = "mod"; break; case Instruction::Len: out = "len"; break; case Instruction::Type: out = "type"; break; case Instruction::Cast: out = "cast"; break; diff --git a/src/vm/instruction.hh b/src/vm/instruction.hh index a058751..f603ff2 100644 --- a/src/vm/instruction.hh +++ b/src/vm/instruction.hh @@ -77,6 +77,7 @@ enum class Instruction : uint8_t { Power = 0x2e, ShiftLeft = 0x2f, ShiftRight = 0x30, + Modulo = 0x31, // other value operations Len = 0x40, diff --git a/src/vm/tests.cc b/src/vm/tests.cc index 4786b03..eee5f25 100644 --- a/src/vm/tests.cc +++ b/src/vm/tests.cc @@ -125,6 +125,7 @@ TEST(VM, IntegerIntegerOperations) ASSERT_EQ(test_op(2, 3, "pow"), 8); ASSERT_EQ(test_op(2, 3, "shl"), 16); ASSERT_EQ(test_op(30, 2, "shr"), 7); + ASSERT_EQ(test_op(8, 3, "mod"), 2); // TODO - div } diff --git a/src/vm/vm.cc b/src/vm/vm.cc index 0918c53..1a602f4 100644 --- a/src/vm/vm.cc +++ b/src/vm/vm.cc @@ -52,82 +52,49 @@ void VM::run_until_return() void VM::step() { + Operation op = code_.operation(loc_.top()); - Value a, b; switch (op.instruction) { + + // + // stack management + // + case Instruction::PushInt8: case Instruction::PushInt16: case Instruction::PushInt32: push_integer(op.operator_); break; - case Instruction::Sum: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::Sum)); - break; - case Instruction::Subtract: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::Subtraction)); - break; - case Instruction::Multiply: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::Multiplication)); - break; - case Instruction::Divide: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::Division)); - break; - case Instruction::DivideInt: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::IntegerDivision)); - break; - case Instruction::Equals: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::Equality)); - break; - case Instruction::NotEquals: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::Inequality)); - break; - case Instruction::LessThan: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::LessThan)); - break; - case Instruction::LessThanEq: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::LessThanOrEquals)); - break; - case Instruction::GreaterThan: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::GreaterThan)); - break; - case Instruction::GreaterThanEq: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::GreaterThanOrEquals)); - break; - case Instruction::And: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::BitwiseAnd)); - break; - case Instruction::Or: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::BitwiseOr)); - break; - case Instruction::Xor: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::BitwiseXor)); - break; - case Instruction::Power: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::Power)); - break; - case Instruction::ShiftLeft: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::ShiftLeft)); - break; - case Instruction::ShiftRight: - a = stack_.pop(); b = stack_.pop(); - stack_.push(binary_operation(a, b, BinaryOperationType::ShiftRight)); - break; + + // + // logical/arithmetic + // + +#define BIN_OP(op) { Value a = stack_.pop(); Value b = stack_.pop(); stack_.push(binary_operation(a, b, BinaryOperationType::op)); } + case Instruction::Sum: BIN_OP(Sum) break; + case Instruction::Subtract: BIN_OP(Subtraction) break; + case Instruction::Multiply: BIN_OP(Multiplication) break; + case Instruction::Divide: BIN_OP(Division) break; + case Instruction::DivideInt: BIN_OP(IntegerDivision) break; + case Instruction::Equals: BIN_OP(Equality) break; + case Instruction::NotEquals: BIN_OP(Inequality) break; + case Instruction::LessThan: BIN_OP(LessThan) break; + case Instruction::LessThanEq: BIN_OP(LessThanOrEquals) break; + case Instruction::GreaterThan: BIN_OP(GreaterThan) break; + case Instruction::GreaterThanEq: BIN_OP(GreaterThanOrEquals) break; + case Instruction::And: BIN_OP(BitwiseAnd) break; + case Instruction::Or: BIN_OP(BitwiseOr) break; + case Instruction::Xor: BIN_OP(BitwiseXor) break; + case Instruction::Power: BIN_OP(Power) break; + case Instruction::ShiftLeft: BIN_OP(ShiftLeft) break; + case Instruction::ShiftRight: BIN_OP(ShiftRight) break; + case Instruction::Modulo: BIN_OP(Modulo) break; +#undef BIN_OP + + // + // function operations + // + case Instruction::Return: { Value v = stack_.pop(); stack_.pop_fp();