From 8f6d858a28a97ac41f3b1ab2ac8bb5e862fc4cb7 Mon Sep 17 00:00:00 2001 From: Andre Wagner Date: Fri, 1 May 2026 16:52:32 -0500 Subject: [PATCH] . --- doc/OPCODES | 15 +++--- src/common/bytearray.cc | 2 +- src/vm/code.cc | 1 + src/vm/expr.cc | 7 +++ src/vm/expr.hh | 2 +- src/vm/instruction.cc | 102 +++++++++++++++++++++------------------- src/vm/instruction.hh | 17 ++++--- src/vm/value.cc | 2 +- src/vm/vm.cc | 9 ++++ 9 files changed, 93 insertions(+), 64 deletions(-) diff --git a/doc/OPCODES b/doc/OPCODES index 507e79a..f809bae 100644 --- a/doc/OPCODES +++ b/doc/OPCODES @@ -65,17 +65,20 @@ Logical/arithmetic: 2b and Bitwise AND 2c or Bitwise OR 2d xor Bitwise XOR +2e pow Power +2f shl Shift left +30 shr Shift right Other value operations: -30 len Get table, array or string size -31 type Get type from value at the top of the stack +40 len Get table, array or string size +41 type Get type from value at the top of the stack b0 cast [type] Cast type to another type -32 ver Return VM version +42 ver Return VM version External code: -38 cmpl Compile code to assembly -39 asmbl Assemble code to bytecode format -3a load Load bytecode as function (will place function on stack) +48 cmpl Compile code to assembly +49 asmbl Assemble code to bytecode format +4a load Load bytecode as function (will place function on stack) Control flow: a8 c8 e8 bz [pc] Branch if zero diff --git a/src/common/bytearray.cc b/src/common/bytearray.cc index 2af83b2..39a4194 100644 --- a/src/common/bytearray.cc +++ b/src/common/bytearray.cc @@ -134,7 +134,7 @@ std::string ByteArray::hexdump() const { auto to_hex = [](uint32_t value, size_t n_chars) -> std::string { char buf[15]; - snprintf(buf, sizeof buf, (std::string("%0") + std::to_string(n_chars) + "X").c_str(), value); + snprintf(buf, sizeof buf, "%0*X", (int) n_chars, value); return { buf }; }; diff --git a/src/vm/code.cc b/src/vm/code.cc index d780fbc..ab3d9b3 100644 --- a/src/vm/code.cc +++ b/src/vm/code.cc @@ -44,6 +44,7 @@ Operation Code::operation(Location const& location) const .operator_ = bytecode_.get_code_int32(location.function_id, location.pc + 1), .next_location = { .function_id = location.function_id, .pc = location.pc + 5 }, }; + default: } throw std::logic_error("Should not get here"); diff --git a/src/vm/expr.cc b/src/vm/expr.cc index 89b1dab..304a2eb 100644 --- a/src/vm/expr.cc +++ b/src/vm/expr.cc @@ -1,5 +1,6 @@ #include "expr.hh" +#include #include #include "vm_exceptions.hh" @@ -45,6 +46,12 @@ static int init_ = []() { BIN_OP(BitwiseXor, Integer, Integer) { return Value::CreateInteger(a.as_integer() ^ b.as_integer()); }; + BIN_OP(Power, Integer, Integer) { return Value::CreateInteger((int32_t) powl(a.as_integer(), b.as_integer())); }; + + BIN_OP(ShiftLeft, Integer, Integer) { return Value::CreateInteger(a.as_integer() << b.as_integer()); }; + + BIN_OP(ShiftRight, 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 83a307c..655a390 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, + GreaterThan, GreaterThanOrEquals, BitwiseAnd, BitwiseOr, BitwiseXor, Power, ShiftLeft, ShiftRight, COUNT }; diff --git a/src/vm/instruction.cc b/src/vm/instruction.cc index f719fb8..27ea8ce 100644 --- a/src/vm/instruction.cc +++ b/src/vm/instruction.cc @@ -5,54 +5,57 @@ namespace tyche::vm { -const std::unordered_map instruction_names = { - { "pushi", vm::Instruction::PushInt8 }, - { "pushc", vm::Instruction::PushConstant8 }, - { "pushz", vm::Instruction::PushZero }, - { "pusht", vm::Instruction::PushTrue }, - { "newa", vm::Instruction::NewArray }, - { "newt", vm::Instruction::NewTable }, - { "pop", vm::Instruction::Pop }, - { "dup", vm::Instruction::Duplicate }, - { "setl", vm::Instruction::SetLocal8 }, - { "getl", vm::Instruction::GetLocal8 }, - { "setg", vm::Instruction::SetGlobal8 }, - { "getl", vm::Instruction::GetGlobal8 }, - { "call8", vm::Instruction::Call8 }, - { "ret", vm::Instruction::Return }, - { "retn", vm::Instruction::ReturnNil }, - { "getkv", vm::Instruction::GetKeyValue }, - { "setkv", vm::Instruction::SetKeyValue }, - { "geta", vm::Instruction::GetArrayItem }, - { "seta", vm::Instruction::SetArrayItem }, - { "appnd", vm::Instruction::Append }, - { "next", vm::Instruction::Next }, - { "smt", vm::Instruction::SetMetatable }, - { "mt", vm::Instruction::GetMetatable }, - { "sum", vm::Instruction::Sum }, - { "sub", vm::Instruction::Subtract }, - { "mul", vm::Instruction::Multiply }, - { "div", vm::Instruction::Divide }, - { "idiv", vm::Instruction::DivideInt }, - { "eq", vm::Instruction::Equals }, - { "neq", vm::Instruction::NotEquals }, - { "lt", vm::Instruction::LessThan }, - { "lte", vm::Instruction::LessThanEq }, - { "gt", vm::Instruction::GreaterThan }, - { "gte", vm::Instruction::GreaterThanEq }, - { "and", vm::Instruction::And }, - { "or", vm::Instruction::Or }, - { "xor", vm::Instruction::Xor }, - { "len", vm::Instruction::Len }, - { "type", vm::Instruction::Type }, - { "cast", vm::Instruction::Cast }, - { "ver", vm::Instruction::Version }, - { "bz", vm::Instruction::BranchIfZero8 }, - { "bnz", vm::Instruction::BranchIfNotZero8 }, - { "jmp", vm::Instruction::Jump8 }, - { "cmpl", vm::Instruction::Compile }, - { "asmbl", vm::Instruction::Assemble }, - { "load", vm::Instruction::Load }, +const std::unordered_map instruction_names = { + { "pushi", Instruction::PushInt8 }, + { "pushc", Instruction::PushConstant8 }, + { "pushz", Instruction::PushZero }, + { "pusht", Instruction::PushTrue }, + { "newa", Instruction::NewArray }, + { "newt", Instruction::NewTable }, + { "pop", Instruction::Pop }, + { "dup", Instruction::Duplicate }, + { "setl", Instruction::SetLocal8 }, + { "getl", Instruction::GetLocal8 }, + { "setg", Instruction::SetGlobal8 }, + { "getl", Instruction::GetGlobal8 }, + { "call8", Instruction::Call8 }, + { "ret", Instruction::Return }, + { "retn", Instruction::ReturnNil }, + { "getkv", Instruction::GetKeyValue }, + { "setkv", Instruction::SetKeyValue }, + { "geta", Instruction::GetArrayItem }, + { "seta", Instruction::SetArrayItem }, + { "appnd", Instruction::Append }, + { "next", Instruction::Next }, + { "smt", Instruction::SetMetatable }, + { "mt", Instruction::GetMetatable }, + { "sum", Instruction::Sum }, + { "sub", Instruction::Subtract }, + { "mul", Instruction::Multiply }, + { "div", Instruction::Divide }, + { "idiv", Instruction::DivideInt }, + { "eq", Instruction::Equals }, + { "neq", Instruction::NotEquals }, + { "lt", Instruction::LessThan }, + { "lte", Instruction::LessThanEq }, + { "gt", Instruction::GreaterThan }, + { "gte", Instruction::GreaterThanEq }, + { "and", Instruction::And }, + { "or", Instruction::Or }, + { "xor", Instruction::Xor }, + { "pow", Instruction::Power }, + { "shl", Instruction::ShiftLeft }, + { "shr", Instruction::ShiftRight }, + { "len", Instruction::Len }, + { "type", Instruction::Type }, + { "cast", Instruction::Cast }, + { "ver", Instruction::Version }, + { "bz", Instruction::BranchIfZero8 }, + { "bnz", Instruction::BranchIfNotZero8 }, + { "jmp", Instruction::Jump8 }, + { "cmpl", Instruction::Compile }, + { "asmbl", Instruction::Assemble }, + { "load", Instruction::Load }, }; @@ -127,6 +130,9 @@ std::pair debug_instruction(Instruction inst, int oper) case Instruction::And: out = "and"; break; case Instruction::Or: out = "or"; break; case Instruction::Xor: out = "xor"; break; + case Instruction::Power: out = "pow"; break; + case Instruction::ShiftLeft: out = "shl"; break; + case Instruction::ShiftRight: out = "shr"; 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 e87622a..a058751 100644 --- a/src/vm/instruction.hh +++ b/src/vm/instruction.hh @@ -74,12 +74,15 @@ enum class Instruction : uint8_t { And = 0x2b, Or = 0x2c, Xor = 0x2d, + Power = 0x2e, + ShiftLeft = 0x2f, + ShiftRight = 0x30, // other value operations - Len = 0x30, - Type = 0x31, - Cast = 0x32, - Version = 0x33, + Len = 0x40, + Type = 0x41, + Cast = 0x42, + Version = 0x43, // control flow BranchIfZero8 = 0xa8, @@ -93,9 +96,9 @@ enum class Instruction : uint8_t { Jump32 = 0xea, // external code - Compile = 0x38, - Assemble = 0x39, - Load = 0x3a, + Compile = 0x48, + Assemble = 0x49, + Load = 0x4a, }; std::pair debug_instruction(Instruction inst, int oper=0); diff --git a/src/vm/value.cc b/src/vm/value.cc index 535f78c..07523b4 100644 --- a/src/vm/value.cc +++ b/src/vm/value.cc @@ -15,7 +15,7 @@ std::string type_name(Type type) case Type::Table: return "table"; case Type::Function: return "function"; case Type::NativePointer: return "native pointer"; - default: return "???"; + case Type::COUNT: default: return "???"; } } diff --git a/src/vm/vm.cc b/src/vm/vm.cc index a1a9d33..b59cfb8 100644 --- a/src/vm/vm.cc +++ b/src/vm/vm.cc @@ -101,6 +101,15 @@ void VM::step() case Instruction::Xor: stack_.push(binary_operation(stack_.pop(), stack_.pop(), BinaryOperationType::BitwiseXor)); break; + case Instruction::Power: + stack_.push(binary_operation(stack_.pop(), stack_.pop(), BinaryOperationType::Power)); + break; + case Instruction::ShiftLeft: + stack_.push(binary_operation(stack_.pop(), stack_.pop(), BinaryOperationType::ShiftLeft)); + break; + case Instruction::ShiftRight: + stack_.push(binary_operation(stack_.pop(), stack_.pop(), BinaryOperationType::ShiftRight)); + break; case Instruction::Return: { Value v = stack_.pop(); stack_.pop_fp();