This commit is contained in:
Andre Wagner
2026-05-01 16:52:32 -05:00
parent 0bc40cc562
commit 8f6d858a28
9 changed files with 93 additions and 64 deletions

View File

@@ -65,17 +65,20 @@ Logical/arithmetic:
2b and Bitwise AND 2b and Bitwise AND
2c or Bitwise OR 2c or Bitwise OR
2d xor Bitwise XOR 2d xor Bitwise XOR
2e pow Power
2f shl Shift left
30 shr Shift right
Other value operations: Other value operations:
30 len Get table, array or string size 40 len Get table, array or string size
31 type Get type from value at the top of the stack 41 type Get type from value at the top of the stack
b0 cast [type] Cast type to another type b0 cast [type] Cast type to another type
32 ver Return VM version 42 ver Return VM version
External code: External code:
38 cmpl Compile code to assembly 48 cmpl Compile code to assembly
39 asmbl Assemble code to bytecode format 49 asmbl Assemble code to bytecode format
3a load Load bytecode as function (will place function on stack) 4a load Load bytecode as function (will place function on stack)
Control flow: Control flow:
a8 c8 e8 bz [pc] Branch if zero a8 c8 e8 bz [pc] Branch if zero

View File

@@ -134,7 +134,7 @@ std::string ByteArray::hexdump() const
{ {
auto to_hex = [](uint32_t value, size_t n_chars) -> std::string { auto to_hex = [](uint32_t value, size_t n_chars) -> std::string {
char buf[15]; 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 }; return { buf };
}; };

View File

@@ -44,6 +44,7 @@ Operation Code::operation(Location const& location) const
.operator_ = bytecode_.get_code_int32(location.function_id, location.pc + 1), .operator_ = bytecode_.get_code_int32(location.function_id, location.pc + 1),
.next_location = { .function_id = location.function_id, .pc = location.pc + 5 }, .next_location = { .function_id = location.function_id, .pc = location.pc + 5 },
}; };
default:
} }
throw std::logic_error("Should not get here"); throw std::logic_error("Should not get here");

View File

@@ -1,5 +1,6 @@
#include "expr.hh" #include "expr.hh"
#include <cmath>
#include <functional> #include <functional>
#include "vm_exceptions.hh" #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(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 #undef BIN_OP
return 0; return 0;

View File

@@ -7,7 +7,7 @@ namespace tyche::vm {
enum class BinaryOperationType enum class BinaryOperationType
{ {
Sum, Subtraction, Multiplication, Division, IntegerDivision, Equality, Inequality, LessThan, LessThanOrEquals, Sum, Subtraction, Multiplication, Division, IntegerDivision, Equality, Inequality, LessThan, LessThanOrEquals,
GreaterThan, GreaterThanOrEquals, BitwiseAnd, BitwiseOr, BitwiseXor, GreaterThan, GreaterThanOrEquals, BitwiseAnd, BitwiseOr, BitwiseXor, Power, ShiftLeft, ShiftRight,
COUNT COUNT
}; };

View File

@@ -5,54 +5,57 @@
namespace tyche::vm { namespace tyche::vm {
const std::unordered_map<std::string, vm::Instruction> instruction_names = { const std::unordered_map<std::string, Instruction> instruction_names = {
{ "pushi", vm::Instruction::PushInt8 }, { "pushi", Instruction::PushInt8 },
{ "pushc", vm::Instruction::PushConstant8 }, { "pushc", Instruction::PushConstant8 },
{ "pushz", vm::Instruction::PushZero }, { "pushz", Instruction::PushZero },
{ "pusht", vm::Instruction::PushTrue }, { "pusht", Instruction::PushTrue },
{ "newa", vm::Instruction::NewArray }, { "newa", Instruction::NewArray },
{ "newt", vm::Instruction::NewTable }, { "newt", Instruction::NewTable },
{ "pop", vm::Instruction::Pop }, { "pop", Instruction::Pop },
{ "dup", vm::Instruction::Duplicate }, { "dup", Instruction::Duplicate },
{ "setl", vm::Instruction::SetLocal8 }, { "setl", Instruction::SetLocal8 },
{ "getl", vm::Instruction::GetLocal8 }, { "getl", Instruction::GetLocal8 },
{ "setg", vm::Instruction::SetGlobal8 }, { "setg", Instruction::SetGlobal8 },
{ "getl", vm::Instruction::GetGlobal8 }, { "getl", Instruction::GetGlobal8 },
{ "call8", vm::Instruction::Call8 }, { "call8", Instruction::Call8 },
{ "ret", vm::Instruction::Return }, { "ret", Instruction::Return },
{ "retn", vm::Instruction::ReturnNil }, { "retn", Instruction::ReturnNil },
{ "getkv", vm::Instruction::GetKeyValue }, { "getkv", Instruction::GetKeyValue },
{ "setkv", vm::Instruction::SetKeyValue }, { "setkv", Instruction::SetKeyValue },
{ "geta", vm::Instruction::GetArrayItem }, { "geta", Instruction::GetArrayItem },
{ "seta", vm::Instruction::SetArrayItem }, { "seta", Instruction::SetArrayItem },
{ "appnd", vm::Instruction::Append }, { "appnd", Instruction::Append },
{ "next", vm::Instruction::Next }, { "next", Instruction::Next },
{ "smt", vm::Instruction::SetMetatable }, { "smt", Instruction::SetMetatable },
{ "mt", vm::Instruction::GetMetatable }, { "mt", Instruction::GetMetatable },
{ "sum", vm::Instruction::Sum }, { "sum", Instruction::Sum },
{ "sub", vm::Instruction::Subtract }, { "sub", Instruction::Subtract },
{ "mul", vm::Instruction::Multiply }, { "mul", Instruction::Multiply },
{ "div", vm::Instruction::Divide }, { "div", Instruction::Divide },
{ "idiv", vm::Instruction::DivideInt }, { "idiv", Instruction::DivideInt },
{ "eq", vm::Instruction::Equals }, { "eq", Instruction::Equals },
{ "neq", vm::Instruction::NotEquals }, { "neq", Instruction::NotEquals },
{ "lt", vm::Instruction::LessThan }, { "lt", Instruction::LessThan },
{ "lte", vm::Instruction::LessThanEq }, { "lte", Instruction::LessThanEq },
{ "gt", vm::Instruction::GreaterThan }, { "gt", Instruction::GreaterThan },
{ "gte", vm::Instruction::GreaterThanEq }, { "gte", Instruction::GreaterThanEq },
{ "and", vm::Instruction::And }, { "and", Instruction::And },
{ "or", vm::Instruction::Or }, { "or", Instruction::Or },
{ "xor", vm::Instruction::Xor }, { "xor", Instruction::Xor },
{ "len", vm::Instruction::Len }, { "pow", Instruction::Power },
{ "type", vm::Instruction::Type }, { "shl", Instruction::ShiftLeft },
{ "cast", vm::Instruction::Cast }, { "shr", Instruction::ShiftRight },
{ "ver", vm::Instruction::Version }, { "len", Instruction::Len },
{ "bz", vm::Instruction::BranchIfZero8 }, { "type", Instruction::Type },
{ "bnz", vm::Instruction::BranchIfNotZero8 }, { "cast", Instruction::Cast },
{ "jmp", vm::Instruction::Jump8 }, { "ver", Instruction::Version },
{ "cmpl", vm::Instruction::Compile }, { "bz", Instruction::BranchIfZero8 },
{ "asmbl", vm::Instruction::Assemble }, { "bnz", Instruction::BranchIfNotZero8 },
{ "load", vm::Instruction::Load }, { "jmp", Instruction::Jump8 },
{ "cmpl", Instruction::Compile },
{ "asmbl", Instruction::Assemble },
{ "load", Instruction::Load },
}; };
@@ -127,6 +130,9 @@ std::pair<std::string, size_t> debug_instruction(Instruction inst, int oper)
case Instruction::And: out = "and"; break; case Instruction::And: out = "and"; break;
case Instruction::Or: out = "or"; break; case Instruction::Or: out = "or"; break;
case Instruction::Xor: out = "xor"; 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::Len: out = "len"; break;
case Instruction::Type: out = "type"; break; case Instruction::Type: out = "type"; break;
case Instruction::Cast: out = "cast"; break; case Instruction::Cast: out = "cast"; break;

View File

@@ -74,12 +74,15 @@ enum class Instruction : uint8_t {
And = 0x2b, And = 0x2b,
Or = 0x2c, Or = 0x2c,
Xor = 0x2d, Xor = 0x2d,
Power = 0x2e,
ShiftLeft = 0x2f,
ShiftRight = 0x30,
// other value operations // other value operations
Len = 0x30, Len = 0x40,
Type = 0x31, Type = 0x41,
Cast = 0x32, Cast = 0x42,
Version = 0x33, Version = 0x43,
// control flow // control flow
BranchIfZero8 = 0xa8, BranchIfZero8 = 0xa8,
@@ -93,9 +96,9 @@ enum class Instruction : uint8_t {
Jump32 = 0xea, Jump32 = 0xea,
// external code // external code
Compile = 0x38, Compile = 0x48,
Assemble = 0x39, Assemble = 0x49,
Load = 0x3a, Load = 0x4a,
}; };
std::pair<std::string, size_t> debug_instruction(Instruction inst, int oper=0); std::pair<std::string, size_t> debug_instruction(Instruction inst, int oper=0);

View File

@@ -15,7 +15,7 @@ std::string type_name(Type type)
case Type::Table: return "table"; case Type::Table: return "table";
case Type::Function: return "function"; case Type::Function: return "function";
case Type::NativePointer: return "native pointer"; case Type::NativePointer: return "native pointer";
default: return "???"; case Type::COUNT: default: return "???";
} }
} }

View File

@@ -101,6 +101,15 @@ void VM::step()
case Instruction::Xor: case Instruction::Xor:
stack_.push(binary_operation(stack_.pop(), stack_.pop(), BinaryOperationType::BitwiseXor)); stack_.push(binary_operation(stack_.pop(), stack_.pop(), BinaryOperationType::BitwiseXor));
break; 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: { case Instruction::Return: {
Value v = stack_.pop(); Value v = stack_.pop();
stack_.pop_fp(); stack_.pop_fp();