.
This commit is contained in:
10
.idea/ctestState.xml
generated
Normal file
10
.idea/ctestState.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CidrCTestProjectState">
|
||||||
|
<ctestState>
|
||||||
|
<lineNumber testId="path:CMakeLists.txt test:tyche_as_test" value="108" />
|
||||||
|
<lineNumber testId="path:CMakeLists.txt test:tyche_bytecode_test" value="100" />
|
||||||
|
<lineNumber testId="path:CMakeLists.txt test:tyche_vm_test" value="104" />
|
||||||
|
</ctestState>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -66,26 +66,26 @@ add_library(lib${PROJECT_NAME} SHARED
|
|||||||
src/bytecode/bytecode.hh
|
src/bytecode/bytecode.hh
|
||||||
src/bytecode/bytecodeprototype.hh
|
src/bytecode/bytecodeprototype.hh
|
||||||
src/bytecode/constant.hh
|
src/bytecode/constant.hh
|
||||||
src/vm/code.cc
|
src/bytecode/bc_exceptions.hh
|
||||||
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/assembler/lexer.cc
|
src/assembler/lexer.cc
|
||||||
src/assembler/lexer.hh
|
src/assembler/lexer.hh
|
||||||
src/assembler/assembler.cc
|
src/assembler/assembler.cc
|
||||||
src/assembler/assembler.hh
|
src/assembler/assembler.hh
|
||||||
src/assembler/as_exceptions.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})
|
target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings})
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "as_exceptions.hh"
|
#include "as_exceptions.hh"
|
||||||
#include "../bytecode/bytecode.hh"
|
#include "../bytecode/bytecode.hh"
|
||||||
#include "../vm/instruction.hh"
|
#include "../instructions/instruction.hh"
|
||||||
|
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
@@ -61,16 +61,16 @@ ByteArray Assembler::assemble()
|
|||||||
tt = lexer_.ingest();
|
tt = lexer_.ingest();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto oinst = vm::translate_instruction(instruction, oper);
|
auto oinst = translate_instruction(instruction, oper);
|
||||||
if (!oinst)
|
if (!oinst)
|
||||||
throw AssemblyError("Invalid or misused instruction '" + instruction + "'", tt.line, tt.column);
|
throw AssemblyError("Invalid or misused instruction '" + instruction + "'", tt.line, tt.column);
|
||||||
|
|
||||||
bp.functions.at(function_id).code.append_byte((uint8_t) *oinst);
|
bp.functions.at(function_id).code.append_byte((uint8_t) *oinst);
|
||||||
switch (vm::instruction_operand_type(*oinst)) {
|
switch (instruction_operand_type(*oinst)) {
|
||||||
case vm::OperandType::Int8: bp.functions.at(function_id).code.append_int8((int8_t) *oper); break;
|
case 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 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 OperandType::Int32: bp.functions.at(function_id).code.append_int32(*oper); break;
|
||||||
case vm::OperandType::NoOperand: default: break;
|
case OperandType::NoOperand: default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tt.type != TokenType::Enter)
|
if (tt.type != TokenType::Enter)
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#include "lexer.hh"
|
#include "lexer.hh"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
#include "as_exceptions.hh"
|
#include "as_exceptions.hh"
|
||||||
|
|
||||||
namespace tyche::as {
|
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 };
|
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<std::string>(t.token) << ")"s;
|
||||||
|
case TokenType::Instruction: os << "Instruction ("s << std::get<std::string>(t.token) << ")"s;
|
||||||
|
case TokenType::Integer: os << "Integer ("s << std::to_string(std::get<int>(t.token)) << ")"s;
|
||||||
|
case TokenType::Float: os << "Float ("s << std::to_string(std::get<float>(t.token)) << ")"s;
|
||||||
|
case TokenType::String: os << "String ("s << std::get<std::string>(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
|
} // tyche
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ enum class TokenType {
|
|||||||
|
|
||||||
using TokenValue = std::variant<std::monostate, int, float, std::string>;
|
using TokenValue = std::variant<std::monostate, int, float, std::string>;
|
||||||
|
|
||||||
|
|
||||||
struct Token {
|
struct Token {
|
||||||
TokenType type;
|
TokenType type;
|
||||||
TokenValue token = std::monostate();
|
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); }
|
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);
|
std::string token_type_name(TokenType type);
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,11 @@
|
|||||||
|
|
||||||
#include "../bytecode/bytecodeprototype.hh"
|
#include "../bytecode/bytecodeprototype.hh"
|
||||||
#include "../bytecode/bytecode.hh"
|
#include "../bytecode/bytecode.hh"
|
||||||
#include "../vm/instruction.hh"
|
#include "../instructions/instruction.hh"
|
||||||
|
|
||||||
using namespace tyche;
|
using namespace tyche;
|
||||||
using namespace tyche::as;
|
using namespace tyche::as;
|
||||||
using namespace tyche::bc;
|
using namespace tyche::bc;
|
||||||
using namespace tyche::vm;
|
|
||||||
|
|
||||||
TEST(Lexer, Lexer)
|
TEST(Lexer, Lexer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ ConstantValue Bytecode::get_constant(uint32_t idx) const
|
|||||||
case CONST_TYPE_FLOAT:
|
case CONST_TYPE_FLOAT:
|
||||||
return byte_array_.get_float(cache_.constants_start_addr + constant_idx + 1);
|
return byte_array_.get_float(cache_.constants_start_addr + constant_idx + 1);
|
||||||
case CONST_TYPE_STRING:
|
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:
|
default:
|
||||||
throw BytecodeParsingError("Invalid bytecode format (invalid constant type)");
|
throw BytecodeParsingError("Invalid bytecode format (invalid constant type)");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "../common/bytearray.hh"
|
#include "../common/bytearray.hh"
|
||||||
#include "bytecodeprototype.hh"
|
#include "bytecodeprototype.hh"
|
||||||
|
#include "constant.hh"
|
||||||
|
|
||||||
namespace tyche::bc {
|
namespace tyche::bc {
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "constant.hh"
|
|
||||||
#include "../common/bytearray.hh"
|
#include "../common/bytearray.hh"
|
||||||
|
|
||||||
namespace tyche::bc {
|
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 {}) {}
|
Function(uint16_t n_pars_, uint16_t n_locals_) : n_pars(n_pars_), n_locals(n_locals_), code(ByteArray {}) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using ConstantValue = std::variant<float, std::string>;
|
||||||
std::vector<ConstantValue> constants {};
|
std::vector<ConstantValue> constants {};
|
||||||
std::vector<Function> functions {};
|
std::vector<Function> functions {};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace tyche::bc {
|
namespace tyche::bc {
|
||||||
|
|
||||||
using ConstantValue = std::variant<float, std::string>;
|
using ConstantValue = std::variant<float, const char*>;
|
||||||
|
|
||||||
enum ConstantType : uint8_t { CONST_TYPE_FLOAT = 1, CONST_TYPE_STRING = 2 };
|
enum ConstantType : uint8_t { CONST_TYPE_FLOAT = 1, CONST_TYPE_STRING = 2 };
|
||||||
|
|
||||||
|
|||||||
@@ -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, -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_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
|
#undef TESTX
|
||||||
}
|
}
|
||||||
@@ -145,7 +148,7 @@ TEST(Bytecode, Parsing)
|
|||||||
ASSERT_EQ(bc.get_function_sz(1), 1);
|
ASSERT_EQ(bc.get_function_sz(1), 1);
|
||||||
|
|
||||||
ASSERT_FLOAT_EQ(std::get<float>(bc.get_constant(0)), 3.14f);
|
ASSERT_FLOAT_EQ(std::get<float>(bc.get_constant(0)), 3.14f);
|
||||||
ASSERT_EQ(std::get<std::string>(bc.get_constant(1)), "HELLO");
|
EXPECT_STREQ(std::get<const char*>(bc.get_constant(1)), "HELLO");
|
||||||
|
|
||||||
Bytecode::FunctionDef f1 = bc.get_function_def(0);
|
Bytecode::FunctionDef f1 = bc.get_function_def(0);
|
||||||
ASSERT_EQ(f1.n_params, 0);
|
ASSERT_EQ(f1.n_params, 0);
|
||||||
|
|||||||
@@ -117,12 +117,9 @@ float ByteArray::get_float(uint32_t addr) const
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string, size_t> ByteArray::get_string(uint32_t addr) const
|
std::pair<const char*, size_t> ByteArray::get_string_ptr(uint32_t addr) const
|
||||||
{
|
{
|
||||||
std::string data;
|
return { (const char *) &data_.at(addr), strlen((const char *) &data_.at(addr)) + 1 };
|
||||||
while (char c = (char) get_byte(addr++))
|
|
||||||
data += c;
|
|
||||||
return { data, data.size() + 1 };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteArray::append_bytearray(ByteArray const& bytearray)
|
void ByteArray::append_bytearray(ByteArray const& bytearray)
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
[[nodiscard]] int16_t get_int16(uint32_t addr) const;
|
[[nodiscard]] int16_t get_int16(uint32_t addr) const;
|
||||||
[[nodiscard]] int32_t get_int32(uint32_t addr) const;
|
[[nodiscard]] int32_t get_int32(uint32_t addr) const;
|
||||||
[[nodiscard]] float get_float(uint32_t addr) const;
|
[[nodiscard]] float get_float(uint32_t addr) const;
|
||||||
[[nodiscard]] std::pair<std::string, size_t> get_string(uint32_t addr) const;
|
[[nodiscard]] std::pair<const char*, size_t> get_string_ptr(uint32_t addr) const;
|
||||||
|
|
||||||
[[nodiscard]] std::vector<uint8_t> const& data() const { return data_; }
|
[[nodiscard]] std::vector<uint8_t> const& data() const { return data_; }
|
||||||
[[nodiscard]] size_t size() const { return data_.size(); }
|
[[nodiscard]] size_t size() const { return data_.size(); }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace tyche::vm {
|
namespace tyche {
|
||||||
|
|
||||||
const std::unordered_map<std::string, Instruction> instruction_names = {
|
const std::unordered_map<std::string, Instruction> instruction_names = {
|
||||||
{ "pushi", Instruction::PushInt8 },
|
{ "pushi", Instruction::PushInt8 },
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "../bytecode/bytecode.hh"
|
#include "../bytecode/bytecode.hh"
|
||||||
|
|
||||||
namespace tyche::vm {
|
namespace tyche {
|
||||||
|
|
||||||
constexpr uint8_t OPCODE_NEXT_SIZE = 0x20;
|
constexpr uint8_t OPCODE_NEXT_SIZE = 0x20;
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "code.hh"
|
#include "code.hh"
|
||||||
#include "../common/overloaded.hh"
|
#include "../common/overloaded.hh"
|
||||||
#include "instruction.hh"
|
#include "../instructions/instruction.hh"
|
||||||
|
|
||||||
namespace tyche::vm {
|
namespace tyche::vm {
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef TYCHE_CODE_HH
|
#ifndef TYCHE_CODE_HH
|
||||||
#define TYCHE_CODE_HH
|
#define TYCHE_CODE_HH
|
||||||
|
|
||||||
#include "instruction.hh"
|
#include "../instructions/instruction.hh"
|
||||||
#include "location.hh"
|
#include "location.hh"
|
||||||
#include "value.hh"
|
#include "value.hh"
|
||||||
#include "../bytecode/bytecode.hh"
|
#include "../bytecode/bytecode.hh"
|
||||||
|
|||||||
Reference in New Issue
Block a user