diff --git a/CMakeLists.txt b/CMakeLists.txt index 4460ae5..1f00baf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,18 +74,18 @@ add_library(lib${PROJECT_NAME} SHARED src/assembler/as_exceptions.hh src/instructions/instruction.hh src/instructions/instruction.cc - #src/vm/code.cc - #src/vm/code.hh - #src/vm/value.cc - #src/vm/value.hh - #src/vm/stack.cc - #src/vm/stack.hh - #src/vm/vm_exceptions.hh - #src/vm/vm.cc - #src/vm/vm.hh - #src/vm/expr.cc - #src/vm/expr.hh - #src/vm/location.hh + src/vm/code.cc + src/vm/code.hh + src/vm/value.cc + src/vm/value.hh + src/vm/stack.cc + src/vm/stack.hh + src/vm/vm_exceptions.hh + src/vm/vm.cc + src/vm/vm.hh + src/vm/expr.cc + src/vm/expr.hh + src/vm/location.hh ) target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings}) diff --git a/src/vm/expr.cc b/src/vm/expr.cc index 67123ea..bcc00a3 100644 --- a/src/vm/expr.cc +++ b/src/vm/expr.cc @@ -35,7 +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(Sum, String, String) { return Value::createString(std::string(a.as_string_ptr()) + std::string(b.as_string_ptr())); }; 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()); }; @@ -61,13 +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(Equality, String, String) { return Value::createIntegerFromBool(strcmp(a.as_string_ptr(), b.as_string_ptr()) == 0); }; 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(Inequality, String, String) { return Value::createIntegerFromBool(strcmp(a.as_string_ptr(), b.as_string_ptr()) != 0); }; 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()); }; diff --git a/src/vm/tests.cc b/src/vm/tests.cc index 23ed175..d7d1417 100644 --- a/src/vm/tests.cc +++ b/src/vm/tests.cc @@ -110,7 +110,7 @@ TEST(VM, StackOperations) ASSERT_FLOAT_EQ(run("pushi 5000").to_float(-1), 5000.f); ASSERT_FLOAT_EQ(run("pushc 0").to_float(-1), 3.14f); ASSERT_EQ(run("pushc 0").to_integer(-1), 3); - ASSERT_EQ(run("pushc 1").to_string(-1), "Hello world"); + EXPECT_STREQ(run("pushc 1").to_string_ptr(-1), "Hello world"); ASSERT_TRUE(run("pushf 0").is_function(-1)); ASSERT_EQ(run("pushi 2\n pushi 3\n pop").to_integer(-1), 2); } @@ -233,7 +233,7 @@ TEST(VM, StringString) pushc 1 sum ret - )").to_string(-1), "HelloWorld"); + )").to_string_ptr(-1), "HelloWorld"); ASSERT_EQ(run(R"( .const diff --git a/src/vm/value.cc b/src/vm/value.cc index 07523b4..27f873c 100644 --- a/src/vm/value.cc +++ b/src/vm/value.cc @@ -41,4 +41,13 @@ std::string Value::to_string() const }, value_); } +const char* Value::as_string_ptr() const +{ + if (auto s = std::get_if(&value_)) + return s->c_str(); + if (auto s = std::get_if(&value_)) + return *s; + throw std::logic_error("Shouldn't get here"); +} + } diff --git a/src/vm/value.hh b/src/vm/value.hh index 65c98ce..8bb2cde 100644 --- a/src/vm/value.hh +++ b/src/vm/value.hh @@ -26,6 +26,7 @@ public: static Value createInteger(int32_t v) { return Value(v); } static Value createFloat(float f) { return Value(f); } static Value createString(std::string const& str) { return Value(str); } + static Value createStringFromConstant(const char* str) { return Value(str); } static Value createFunctionId(FunctionId f_id) { return Value(Function { f_id }); } static Value createFalse() { return createInteger(0); } @@ -36,13 +37,13 @@ public: [[nodiscard]] int32_t as_integer() const { return std::get(value_); } [[nodiscard]] float as_float() const { return std::get(value_); } - [[nodiscard]] std::string as_string() const { return std::get(value_); } + [[nodiscard]] const char* as_string_ptr() const; [[nodiscard]] FunctionId as_function_id() const { return std::get(value_).f_id; } [[nodiscard]] std::string to_string() const; private: - using Internal = std::variant; + using Internal = std::variant; Internal value_; explicit Value(Internal const& internal) : value_(internal) {} diff --git a/src/vm/vm.cc b/src/vm/vm.cc index ab8ac99..6afeb4a 100644 --- a/src/vm/vm.cc +++ b/src/vm/vm.cc @@ -49,11 +49,11 @@ float VM::to_float(int index) const throw VMTypeError(Type::Float, f.type()); } -std::string VM::to_string(int index) const +const char* VM::to_string_ptr(int index) const { - Value i = stack_.at(index); - assert_type(i, Type::String); - return i.as_string(); + Value s = stack_.at(index); + assert_type(s, Type::String); + return s.as_string_ptr(); } VM& VM::push_nil() @@ -110,8 +110,8 @@ void VM::step() auto cnst = code_.bytecode().get_constant(op.operator_); if (auto f = std::get_if(&cnst)) push_float(*f); - else if (auto s = std::get_if(&cnst)) - push_string(*s); + else if (auto s = std::get_if(&cnst)) + stack_.push(Value::createStringFromConstant(*s)); else throw std::logic_error("Shouldn't get here"); break; diff --git a/src/vm/vm.hh b/src/vm/vm.hh index 4367df6..848ed3c 100644 --- a/src/vm/vm.hh +++ b/src/vm/vm.hh @@ -31,7 +31,7 @@ public: [[nodiscard]] int32_t to_integer(int index) const; [[nodiscard]] float to_float(int index) const; - [[nodiscard]] std::string to_string(int index) const; + [[nodiscard]] const char* to_string_ptr(int index) const; [[nodiscard]] std::string debug_stack() const { return stack_.debug(); }