Expressions #7
@@ -68,6 +68,7 @@ Logical/arithmetic:
|
|||||||
2e pow Power
|
2e pow Power
|
||||||
2f shl Shift left
|
2f shl Shift left
|
||||||
30 shr Shift right
|
30 shr Shift right
|
||||||
|
31 mod Modulo
|
||||||
|
|
||||||
Other value operations:
|
Other value operations:
|
||||||
40 len Get table, array or string size
|
40 len Get table, array or string size
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ static int init_ = []() {
|
|||||||
|
|
||||||
BIN_OP(ShiftRight, 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()); };
|
||||||
|
|
||||||
|
BIN_OP(Modulo, Integer, Integer) { return Value::CreateInteger(a.as_integer() % b.as_integer()); };
|
||||||
|
|
||||||
#undef BIN_OP
|
#undef BIN_OP
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -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, Power, ShiftLeft, ShiftRight,
|
GreaterThan, GreaterThanOrEquals, BitwiseAnd, BitwiseOr, BitwiseXor, Power, ShiftLeft, ShiftRight, Modulo,
|
||||||
COUNT
|
COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ const std::unordered_map<std::string, Instruction> instruction_names = {
|
|||||||
{ "pow", Instruction::Power },
|
{ "pow", Instruction::Power },
|
||||||
{ "shl", Instruction::ShiftLeft },
|
{ "shl", Instruction::ShiftLeft },
|
||||||
{ "shr", Instruction::ShiftRight },
|
{ "shr", Instruction::ShiftRight },
|
||||||
|
{ "mod", Instruction::Modulo },
|
||||||
{ "len", Instruction::Len },
|
{ "len", Instruction::Len },
|
||||||
{ "type", Instruction::Type },
|
{ "type", Instruction::Type },
|
||||||
{ "cast", Instruction::Cast },
|
{ "cast", Instruction::Cast },
|
||||||
@@ -133,6 +134,7 @@ std::pair<std::string, size_t> debug_instruction(Instruction inst, int oper)
|
|||||||
case Instruction::Power: out = "pow"; break;
|
case Instruction::Power: out = "pow"; break;
|
||||||
case Instruction::ShiftLeft: out = "shl"; break;
|
case Instruction::ShiftLeft: out = "shl"; break;
|
||||||
case Instruction::ShiftRight: out = "shr"; break;
|
case Instruction::ShiftRight: out = "shr"; break;
|
||||||
|
case Instruction::Modulo: out = "mod"; 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;
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ enum class Instruction : uint8_t {
|
|||||||
Power = 0x2e,
|
Power = 0x2e,
|
||||||
ShiftLeft = 0x2f,
|
ShiftLeft = 0x2f,
|
||||||
ShiftRight = 0x30,
|
ShiftRight = 0x30,
|
||||||
|
Modulo = 0x31,
|
||||||
|
|
||||||
// other value operations
|
// other value operations
|
||||||
Len = 0x40,
|
Len = 0x40,
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ TEST(VM, IntegerIntegerOperations)
|
|||||||
ASSERT_EQ(test_op(2, 3, "pow"), 8);
|
ASSERT_EQ(test_op(2, 3, "pow"), 8);
|
||||||
ASSERT_EQ(test_op(2, 3, "shl"), 16);
|
ASSERT_EQ(test_op(2, 3, "shl"), 16);
|
||||||
ASSERT_EQ(test_op(30, 2, "shr"), 7);
|
ASSERT_EQ(test_op(30, 2, "shr"), 7);
|
||||||
|
ASSERT_EQ(test_op(8, 3, "mod"), 2);
|
||||||
|
|
||||||
// TODO - div
|
// TODO - div
|
||||||
}
|
}
|
||||||
|
|||||||
105
src/vm/vm.cc
105
src/vm/vm.cc
@@ -52,82 +52,49 @@ void VM::run_until_return()
|
|||||||
|
|
||||||
void VM::step()
|
void VM::step()
|
||||||
{
|
{
|
||||||
|
|
||||||
Operation op = code_.operation(loc_.top());
|
Operation op = code_.operation(loc_.top());
|
||||||
Value a, b;
|
|
||||||
switch (op.instruction) {
|
switch (op.instruction) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// stack management
|
||||||
|
//
|
||||||
|
|
||||||
case Instruction::PushInt8:
|
case Instruction::PushInt8:
|
||||||
case Instruction::PushInt16:
|
case Instruction::PushInt16:
|
||||||
case Instruction::PushInt32:
|
case Instruction::PushInt32:
|
||||||
push_integer(op.operator_);
|
push_integer(op.operator_);
|
||||||
break;
|
break;
|
||||||
case Instruction::Sum:
|
|
||||||
a = stack_.pop(); b = stack_.pop();
|
//
|
||||||
stack_.push(binary_operation(a, b, BinaryOperationType::Sum));
|
// logical/arithmetic
|
||||||
break;
|
//
|
||||||
case Instruction::Subtract:
|
|
||||||
a = stack_.pop(); b = stack_.pop();
|
#define BIN_OP(op) { Value a = stack_.pop(); Value b = stack_.pop(); stack_.push(binary_operation(a, b, BinaryOperationType::op)); }
|
||||||
stack_.push(binary_operation(a, b, BinaryOperationType::Subtraction));
|
case Instruction::Sum: BIN_OP(Sum) break;
|
||||||
break;
|
case Instruction::Subtract: BIN_OP(Subtraction) break;
|
||||||
case Instruction::Multiply:
|
case Instruction::Multiply: BIN_OP(Multiplication) break;
|
||||||
a = stack_.pop(); b = stack_.pop();
|
case Instruction::Divide: BIN_OP(Division) break;
|
||||||
stack_.push(binary_operation(a, b, BinaryOperationType::Multiplication));
|
case Instruction::DivideInt: BIN_OP(IntegerDivision) break;
|
||||||
break;
|
case Instruction::Equals: BIN_OP(Equality) break;
|
||||||
case Instruction::Divide:
|
case Instruction::NotEquals: BIN_OP(Inequality) break;
|
||||||
a = stack_.pop(); b = stack_.pop();
|
case Instruction::LessThan: BIN_OP(LessThan) break;
|
||||||
stack_.push(binary_operation(a, b, BinaryOperationType::Division));
|
case Instruction::LessThanEq: BIN_OP(LessThanOrEquals) break;
|
||||||
break;
|
case Instruction::GreaterThan: BIN_OP(GreaterThan) break;
|
||||||
case Instruction::DivideInt:
|
case Instruction::GreaterThanEq: BIN_OP(GreaterThanOrEquals) break;
|
||||||
a = stack_.pop(); b = stack_.pop();
|
case Instruction::And: BIN_OP(BitwiseAnd) break;
|
||||||
stack_.push(binary_operation(a, b, BinaryOperationType::IntegerDivision));
|
case Instruction::Or: BIN_OP(BitwiseOr) break;
|
||||||
break;
|
case Instruction::Xor: BIN_OP(BitwiseXor) break;
|
||||||
case Instruction::Equals:
|
case Instruction::Power: BIN_OP(Power) break;
|
||||||
a = stack_.pop(); b = stack_.pop();
|
case Instruction::ShiftLeft: BIN_OP(ShiftLeft) break;
|
||||||
stack_.push(binary_operation(a, b, BinaryOperationType::Equality));
|
case Instruction::ShiftRight: BIN_OP(ShiftRight) break;
|
||||||
break;
|
case Instruction::Modulo: BIN_OP(Modulo) break;
|
||||||
case Instruction::NotEquals:
|
#undef BIN_OP
|
||||||
a = stack_.pop(); b = stack_.pop();
|
|
||||||
stack_.push(binary_operation(a, b, BinaryOperationType::Inequality));
|
//
|
||||||
break;
|
// function operations
|
||||||
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;
|
|
||||||
case Instruction::Return: {
|
case Instruction::Return: {
|
||||||
Value v = stack_.pop();
|
Value v = stack_.pop();
|
||||||
stack_.pop_fp();
|
stack_.pop_fp();
|
||||||
|
|||||||
Reference in New Issue
Block a user