.
This commit is contained in:
6
TODO.md
6
TODO.md
@@ -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
|
||||
|
||||
@@ -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()); };
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user