This commit is contained in:
Andre Wagner
2026-05-02 15:06:31 -05:00
parent 1d63645c32
commit 3fce2d383c
4 changed files with 69 additions and 6 deletions

View File

@@ -31,14 +31,14 @@ After some additional development:
- [x] Print stack
- [x] Assembler
- [ ] VM execution
- [ ] Stack operations (nil, integer, float, string, function)
- [x] Stack operations (nil, integer, float, string, function)
- [x] Integer
- [x] Float
- [x] String
- [ ] Expressions
- [x] Expressions
- [x] Integer
- [x] Float
- [ ] String
- [x] String
- [ ] Local/global variables
- [ ] Functions
- [ ] Constants

View File

@@ -10,12 +10,24 @@ namespace tyche::vm {
std::function<Value(Value const&, Value const&)> binary_ops[(size_t) BinaryOperationType::COUNT][(size_t) Type::COUNT][(size_t) Type::COUNT];
static int init_ = []() {
for (size_t i = 0; i < (size_t) BinaryOperationType::COUNT; ++i)
for (size_t j = 0; j < (size_t) Type::COUNT; ++j)
for (size_t k = 0; k < (size_t) Type::COUNT; ++k)
// every combination, except when explicit, return type error
for (size_t i = 0; i < (size_t) BinaryOperationType::COUNT; ++i) {
for (size_t j = 0; j < (size_t) Type::COUNT; ++j) {
for (size_t k = 0; k < (size_t) Type::COUNT; ++k) {
binary_ops[i][j][k] = [&i](Value const& a, Value const& b) -> Value {
throw VMInvalidOperation((BinaryOperationType) i, a.type(), b.type());
};
}
}
}
// every equality/inequality, by default, return inequal
for (size_t j = 0; j < (size_t) Type::COUNT; ++j) {
for (size_t k = 0; k < (size_t) Type::COUNT; ++k) {
binary_ops[(size_t) BinaryOperationType::Equality][j][k] = [](Value const&, Value const&) { return Value::createFalse(); };
binary_ops[(size_t) BinaryOperationType::Inequality][j][k] = [](Value const&, Value const&) { return Value::createTrue(); };
}
}
#define BIN_OP(op, t1, t2) binary_ops[(size_t) BinaryOperationType::op][(size_t) Type::t1][(size_t) Type::t2] = [](Value const& b, Value const& a)
@@ -23,6 +35,7 @@ static int init_ = []() {
BIN_OP(Sum, Integer, Float) { return Value::createFloat((float) a.as_integer() + b.as_float()); };
BIN_OP(Sum, Float, Integer) { return Value::createFloat(a.as_float() + (float) b.as_integer()); };
BIN_OP(Sum, Float, Float) { return Value::createFloat(a.as_float() + b.as_float()); };
BIN_OP(Sum, String, String) { return Value::createString(a.as_string() + b.as_string()); };
BIN_OP(Subtraction, Integer, Integer) { return Value::createInteger(a.as_integer() - b.as_integer()); };
BIN_OP(Subtraction, Integer, Float) { return Value::createFloat((float) a.as_integer() - b.as_float()); };
@@ -48,11 +61,13 @@ static int init_ = []() {
BIN_OP(Equality, Integer, Float) { return Value::createIntegerFromBool(std::abs((float) a.as_integer() - b.as_float()) < FLOAT_EPSILON); };
BIN_OP(Equality, Float, Integer) { return Value::createIntegerFromBool(std::abs(a.as_float() - (float) b.as_integer()) < FLOAT_EPSILON); };
BIN_OP(Equality, Float, Float) { return Value::createIntegerFromBool(std::abs(a.as_float() - b.as_float()) < FLOAT_EPSILON); };
BIN_OP(Equality, String, String) { return Value::createIntegerFromBool(a.as_string() == b.as_string()); };
BIN_OP(Inequality, Integer, Integer) { return Value::createIntegerFromBool(a.as_integer() != b.as_integer()); };
BIN_OP(Inequality, Integer, Float) { return Value::createIntegerFromBool(std::abs((float) a.as_integer() - b.as_float()) >= FLOAT_EPSILON); };
BIN_OP(Inequality, Float, Integer) { return Value::createIntegerFromBool(std::abs(a.as_float() - (float) b.as_integer()) >= FLOAT_EPSILON); };
BIN_OP(Inequality, Float, Float) { return Value::createIntegerFromBool(std::abs(a.as_float() - b.as_float()) >= FLOAT_EPSILON); };
BIN_OP(Inequality, String, String) { return Value::createIntegerFromBool(a.as_string() != b.as_string()); };
BIN_OP(LessThan, Integer, Integer) { return Value::createIntegerFromBool(a.as_integer() < b.as_integer()); };
BIN_OP(LessThan, Integer, Float) { return Value::createIntegerFromBool((float) a.as_integer() < b.as_float()); };

View File

@@ -222,6 +222,52 @@ TEST(VM, FloatFloatOperations)
ASSERT_FLOAT_EQ(test_op("3.2", "3.2", "eq").to_integer(-1), 1);
}
TEST(VM, StringString)
{
ASSERT_EQ(run(R"(
.const
0: "Hello"
1: "World"
.func 0
pushc 0
pushc 1
sum
ret
)").to_string(-1), "HelloWorld");
ASSERT_EQ(run(R"(
.const
0: "Hello"
1: "World"
.func 0
pushc 0
pushc 1
eq
ret
)").to_integer(-1), 0);
ASSERT_EQ(run(R"(
.const
0: "Hello"
1: "Hello"
.func 0
pushc 0
pushc 1
eq
ret
)").to_integer(-1), 1);
ASSERT_EQ(run(R"(
.const
0: "Hello"
.func 0
pushc 0
pushi 1
eq
ret
)").to_integer(-1), 0);
}
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);

View File

@@ -28,6 +28,8 @@ public:
static Value createString(std::string const& str) { return Value(str); }
static Value createFunctionId(FunctionId f_id) { return Value(Function { f_id }); }
static Value createFalse() { return createInteger(0); }
static Value createTrue() { return createInteger(1); }
static Value createIntegerFromBool(bool b) { return createInteger(b ? 1 : 0); }
[[nodiscard]] Type type() const;