Expressions #7

Merged
andre merged 21 commits from vm2 into master 2026-05-02 15:07:12 -05:00
9 changed files with 93 additions and 64 deletions
Showing only changes of commit 8f6d858a28 - Show all commits

View File

@@ -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

View File

@@ -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 };
};

View File

@@ -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");

View File

@@ -1,5 +1,6 @@
#include "expr.hh"
#include <cmath>
#include <functional>
#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;

View File

@@ -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
};

View File

@@ -5,54 +5,57 @@
namespace tyche::vm {
const std::unordered_map<std::string, vm::Instruction> 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<std::string, Instruction> 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<std::string, size_t> 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;

View File

@@ -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<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::Function: return "function";
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:
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();