diff --git a/.idea/ctestState.xml b/.idea/ctestState.xml new file mode 100644 index 0000000..1bbf61b --- /dev/null +++ b/.idea/ctestState.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 718a11b..4460ae5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,26 +66,26 @@ add_library(lib${PROJECT_NAME} SHARED src/bytecode/bytecode.hh src/bytecode/bytecodeprototype.hh src/bytecode/constant.hh - src/vm/code.cc - src/vm/code.hh - src/vm/instruction.hh - src/vm/instruction.cc - 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/bytecode/bc_exceptions.hh src/assembler/lexer.cc src/assembler/lexer.hh src/assembler/assembler.cc src/assembler/assembler.hh src/assembler/as_exceptions.hh - src/bytecode/bc_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 ) target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings}) diff --git a/src/assembler/assembler.cc b/src/assembler/assembler.cc index babf196..f2df9a1 100644 --- a/src/assembler/assembler.cc +++ b/src/assembler/assembler.cc @@ -4,7 +4,7 @@ #include "as_exceptions.hh" #include "../bytecode/bytecode.hh" -#include "../vm/instruction.hh" +#include "../instructions/instruction.hh" using namespace std::string_literals; @@ -61,16 +61,16 @@ ByteArray Assembler::assemble() tt = lexer_.ingest(); } - auto oinst = vm::translate_instruction(instruction, oper); + auto oinst = translate_instruction(instruction, oper); if (!oinst) throw AssemblyError("Invalid or misused instruction '" + instruction + "'", tt.line, tt.column); bp.functions.at(function_id).code.append_byte((uint8_t) *oinst); - switch (vm::instruction_operand_type(*oinst)) { - case vm::OperandType::Int8: bp.functions.at(function_id).code.append_int8((int8_t) *oper); break; - case vm::OperandType::Int16: bp.functions.at(function_id).code.append_int16((int16_t) *oper); break; - case vm::OperandType::Int32: bp.functions.at(function_id).code.append_int32(*oper); break; - case vm::OperandType::NoOperand: default: break; + switch (instruction_operand_type(*oinst)) { + case OperandType::Int8: bp.functions.at(function_id).code.append_int8((int8_t) *oper); break; + case OperandType::Int16: bp.functions.at(function_id).code.append_int16((int16_t) *oper); break; + case OperandType::Int32: bp.functions.at(function_id).code.append_int32(*oper); break; + case OperandType::NoOperand: default: break; } if (tt.type != TokenType::Enter) diff --git a/src/assembler/lexer.cc b/src/assembler/lexer.cc index ab10cf2..b470ae0 100644 --- a/src/assembler/lexer.cc +++ b/src/assembler/lexer.cc @@ -1,5 +1,8 @@ #include "lexer.hh" +#include +using namespace std::string_literals; + #include "as_exceptions.hh" namespace tyche::as { @@ -119,4 +122,21 @@ void Lexer::ingest_next_token() current_token_ = { .type = type, .token = value, .line = current_line, .column = pos_ - current_line_pos }; } +std::ostream& operator<<(std::ostream& os, Token const& t) +{ + switch (t.type) { + case TokenType::BOF: os << "BOF"s; break; + case TokenType::Directive: os << "Directive ("s << std::get(t.token) << ")"s; + case TokenType::Instruction: os << "Instruction ("s << std::get(t.token) << ")"s; + case TokenType::Integer: os << "Integer ("s << std::to_string(std::get(t.token)) << ")"s; + case TokenType::Float: os << "Float ("s << std::to_string(std::get(t.token)) << ")"s; + case TokenType::String: os << "String ("s << std::get(t.token) << ")"s; + case TokenType::Enter: os << "Enter"s; + case TokenType::Colon: os << "Colon"s; + case TokenType::EOF_: os << "EOF"s; + default: os << "???"s; + } + return os; +} + } // tyche diff --git a/src/assembler/lexer.hh b/src/assembler/lexer.hh index eab14aa..c63c175 100644 --- a/src/assembler/lexer.hh +++ b/src/assembler/lexer.hh @@ -13,6 +13,7 @@ enum class TokenType { using TokenValue = std::variant; + struct Token { TokenType type; TokenValue token = std::monostate(); @@ -21,6 +22,7 @@ struct Token { friend bool operator==(Token const& lhs, Token const& rhs) { return std::tie(lhs.type, lhs.token) == std::tie(rhs.type, rhs.token); } }; +std::ostream& operator<<(std::ostream& os, Token const& t); std::string token_type_name(TokenType type); diff --git a/src/assembler/tests.cc b/src/assembler/tests.cc index d897b8a..328c731 100644 --- a/src/assembler/tests.cc +++ b/src/assembler/tests.cc @@ -3,12 +3,11 @@ #include "../bytecode/bytecodeprototype.hh" #include "../bytecode/bytecode.hh" -#include "../vm/instruction.hh" +#include "../instructions/instruction.hh" using namespace tyche; using namespace tyche::as; using namespace tyche::bc; -using namespace tyche::vm; TEST(Lexer, Lexer) { diff --git a/src/bytecode/bytecode.cc b/src/bytecode/bytecode.cc index 996ba2e..b8554d1 100644 --- a/src/bytecode/bytecode.cc +++ b/src/bytecode/bytecode.cc @@ -48,7 +48,7 @@ ConstantValue Bytecode::get_constant(uint32_t idx) const case CONST_TYPE_FLOAT: return byte_array_.get_float(cache_.constants_start_addr + constant_idx + 1); case CONST_TYPE_STRING: - return byte_array_.get_string(cache_.constants_start_addr + constant_idx + 1).first; + return byte_array_.get_string_ptr(cache_.constants_start_addr + constant_idx + 1).first; default: throw BytecodeParsingError("Invalid bytecode format (invalid constant type)"); } diff --git a/src/bytecode/bytecode.hh b/src/bytecode/bytecode.hh index cc6ec04..5835ab8 100644 --- a/src/bytecode/bytecode.hh +++ b/src/bytecode/bytecode.hh @@ -3,6 +3,7 @@ #include "../common/bytearray.hh" #include "bytecodeprototype.hh" +#include "constant.hh" namespace tyche::bc { diff --git a/src/bytecode/bytecodeprototype.hh b/src/bytecode/bytecodeprototype.hh index 5a1bb58..908bb2f 100644 --- a/src/bytecode/bytecodeprototype.hh +++ b/src/bytecode/bytecodeprototype.hh @@ -5,7 +5,6 @@ #include #include #include -#include "constant.hh" #include "../common/bytearray.hh" namespace tyche::bc { @@ -19,6 +18,7 @@ struct BytecodePrototype { Function(uint16_t n_pars_, uint16_t n_locals_) : n_pars(n_pars_), n_locals(n_locals_), code(ByteArray {}) {} }; + using ConstantValue = std::variant; std::vector constants {}; std::vector functions {}; diff --git a/src/bytecode/constant.hh b/src/bytecode/constant.hh index 968c8e4..3965aa1 100644 --- a/src/bytecode/constant.hh +++ b/src/bytecode/constant.hh @@ -6,7 +6,7 @@ namespace tyche::bc { -using ConstantValue = std::variant; +using ConstantValue = std::variant; enum ConstantType : uint8_t { CONST_TYPE_FLOAT = 1, CONST_TYPE_STRING = 2 }; diff --git a/src/bytecode/tests.cc b/src/bytecode/tests.cc index 049332f..fa02e34 100644 --- a/src/bytecode/tests.cc +++ b/src/bytecode/tests.cc @@ -36,7 +36,10 @@ TEST(ByteArray, ByteArray) ba.set_float(1, -3.14); ASSERT_FLOAT_EQ(ba.get_float(1), -3.14); ba.set_float(1, -5000300.1324); ASSERT_FLOAT_EQ(ba.get_float(1), -5000300.1324); - ba.set_string(1, "Hello world!"); ASSERT_EQ(ba.get_string(1), std::make_pair("Hello world!", 13)); + ba.set_string(1, "Hello world!"); + auto str = ba.get_string_ptr(1); + EXPECT_STREQ(str.first, "Hello world!"); + ASSERT_EQ(str.second, 13); #undef TESTX } @@ -145,7 +148,7 @@ TEST(Bytecode, Parsing) ASSERT_EQ(bc.get_function_sz(1), 1); ASSERT_FLOAT_EQ(std::get(bc.get_constant(0)), 3.14f); - ASSERT_EQ(std::get(bc.get_constant(1)), "HELLO"); + EXPECT_STREQ(std::get(bc.get_constant(1)), "HELLO"); Bytecode::FunctionDef f1 = bc.get_function_def(0); ASSERT_EQ(f1.n_params, 0); diff --git a/src/common/bytearray.cc b/src/common/bytearray.cc index 39a4194..cb3e973 100644 --- a/src/common/bytearray.cc +++ b/src/common/bytearray.cc @@ -117,12 +117,9 @@ float ByteArray::get_float(uint32_t addr) const return value; } -std::pair ByteArray::get_string(uint32_t addr) const +std::pair ByteArray::get_string_ptr(uint32_t addr) const { - std::string data; - while (char c = (char) get_byte(addr++)) - data += c; - return { data, data.size() + 1 }; + return { (const char *) &data_.at(addr), strlen((const char *) &data_.at(addr)) + 1 }; } void ByteArray::append_bytearray(ByteArray const& bytearray) diff --git a/src/common/bytearray.hh b/src/common/bytearray.hh index c20a011..d3ed12f 100644 --- a/src/common/bytearray.hh +++ b/src/common/bytearray.hh @@ -40,7 +40,7 @@ public: [[nodiscard]] int16_t get_int16(uint32_t addr) const; [[nodiscard]] int32_t get_int32(uint32_t addr) const; [[nodiscard]] float get_float(uint32_t addr) const; - [[nodiscard]] std::pair get_string(uint32_t addr) const; + [[nodiscard]] std::pair get_string_ptr(uint32_t addr) const; [[nodiscard]] std::vector const& data() const { return data_; } [[nodiscard]] size_t size() const { return data_.size(); } diff --git a/src/vm/instruction.cc b/src/instructions/instruction.cc similarity index 99% rename from src/vm/instruction.cc rename to src/instructions/instruction.cc index b246919..07d9c4f 100644 --- a/src/vm/instruction.cc +++ b/src/instructions/instruction.cc @@ -3,7 +3,7 @@ #include #include -namespace tyche::vm { +namespace tyche { const std::unordered_map instruction_names = { { "pushi", Instruction::PushInt8 }, diff --git a/src/vm/instruction.hh b/src/instructions/instruction.hh similarity index 99% rename from src/vm/instruction.hh rename to src/instructions/instruction.hh index f53bc2e..4d6a970 100644 --- a/src/vm/instruction.hh +++ b/src/instructions/instruction.hh @@ -8,7 +8,7 @@ #include "../bytecode/bytecode.hh" -namespace tyche::vm { +namespace tyche { constexpr uint8_t OPCODE_NEXT_SIZE = 0x20; diff --git a/src/vm/code.cc b/src/vm/code.cc index 96a2e11..75a98d3 100644 --- a/src/vm/code.cc +++ b/src/vm/code.cc @@ -1,6 +1,6 @@ #include "code.hh" #include "../common/overloaded.hh" -#include "instruction.hh" +#include "../instructions/instruction.hh" namespace tyche::vm { diff --git a/src/vm/code.hh b/src/vm/code.hh index e4c9b87..6296018 100644 --- a/src/vm/code.hh +++ b/src/vm/code.hh @@ -1,7 +1,7 @@ #ifndef TYCHE_CODE_HH #define TYCHE_CODE_HH -#include "instruction.hh" +#include "../instructions/instruction.hh" #include "location.hh" #include "value.hh" #include "../bytecode/bytecode.hh"