This commit is contained in:
Andre Wagner
2026-04-30 09:27:28 -05:00
parent 8720bd1cd9
commit 5843a19b2f
9 changed files with 113 additions and 15 deletions

View File

@@ -85,7 +85,8 @@ target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings})
# tests
#
add_executable(${PROJECT_NAME}-bytecode-test src/bytecode/tests.cc)
add_executable(${PROJECT_NAME}-bytecode-test src/bytecode/tests.cc
src/vm/location.hh)
target_link_libraries(${PROJECT_NAME}-bytecode-test lib${PROJECT_NAME} gtest_main)
add_test(NAME tyche_bytecode_test COMMAND ${PROJECT_NAME}-bytecode-test)

View File

@@ -14,6 +14,41 @@ FunctionId Code::import_bytecode(ByteArray incoming)
return 0; // TODO
}
Operation Code::operation(Location const& location) const
{
Instruction inst = (Instruction) bytecode_.get_code_byte(location.function_id, location.pc);
OperandType opet = instruction_operand_type(inst);
switch (opet) {
case OperandType::NoOperand:
return {
.instruction = inst,
.operator_ = 0,
.next_location = { .function_id = location.function_id, .pc = location.pc + 1 },
};
case OperandType::Int8:
return {
.instruction = inst,
.operator_ = bytecode_.get_code_int8(location.function_id, location.pc + 1),
.next_location = { .function_id = location.function_id, .pc = location.pc + 2 },
};
case OperandType::Int16:
return {
.instruction = inst,
.operator_ = bytecode_.get_code_int16(location.function_id, location.pc + 1),
.next_location = { .function_id = location.function_id, .pc = location.pc + 3 },
};
case OperandType::Int32:
return {
.instruction = inst,
.operator_ = bytecode_.get_code_int32(location.function_id, location.pc + 1),
.next_location = { .function_id = location.function_id, .pc = location.pc + 5 },
};
}
throw std::logic_error("Should not get here");
}
std::string Code::disassemble() const
{
std::string out;

View File

@@ -1,17 +1,28 @@
#ifndef TYCHE_CODE_HH
#define TYCHE_CODE_HH
#include "instruction.hh"
#include "location.hh"
#include "value.hh"
#include "../bytecode/bytecode.hh"
namespace tyche {
struct Operation
{
Instruction instruction;
int32_t operator_;
Location next_location;
};
class Code {
public:
FunctionId import_bytecode(ByteArray incoming);
[[nodiscard]] std::string disassemble() const;
[[nodiscard]] Operation operation(Location const& location) const;
private:
Bytecode bytecode_;
};

View File

@@ -98,15 +98,17 @@ std::pair<std::string, size_t> debug_instruction(Instruction inst, int oper)
out = "???";
}
if ((uint8_t) inst < 0xa0)
OperandType operands = instruction_operand_type(inst);
if (operands == OperandType::NoOperand)
return { out, 1 };
out += " " + std::to_string(oper);
if ((uint8_t) inst >= 0xe0)
if (operands == OperandType::Int32)
return { out, 5 };
else if ((uint8_t) inst >= 0xc0)
if (operands == OperandType::Int16)
return { out, 3 };
else
return { out, 2 };
}
@@ -114,14 +116,30 @@ std::pair<std::string, size_t> debug_instruction(Bytecode const& bt, uint32_t fu
{
auto inst = (Instruction) bt.get_code_byte(function_id, addr);
if ((uint8_t) inst >= 0xe0)
return debug_instruction(inst, bt.get_code_int32(function_id, addr + 1));
else if ((uint8_t) inst >= 0xc0)
return debug_instruction(inst, bt.get_code_int16(function_id, addr + 1));
else if ((uint8_t) inst >= 0xa0)
return debug_instruction(inst, bt.get_code_int8(function_id, addr + 1));
switch (instruction_operand_type(inst)) {
case OperandType::NoOperand:
return debug_instruction(inst);
case OperandType::Int8:
return debug_instruction(inst, bt.get_code_int8(function_id, addr + 1));
case OperandType::Int16:
return debug_instruction(inst, bt.get_code_int16(function_id, addr + 1));
case OperandType::Int32:
return debug_instruction(inst, bt.get_code_int32(function_id, addr + 1));
default:
}
return { "???", 1 };
}
OperandType instruction_operand_type(Instruction inst)
{
if ((uint8_t) inst >= 0xe0)
return OperandType::Int32;
if ((uint8_t) inst >= 0xc0)
return OperandType::Int16;
if ((uint8_t) inst >= 0xa0)
return OperandType::Int8;
return OperandType::NoOperand;
}
}

View File

@@ -98,6 +98,9 @@ enum class Instruction : uint8_t {
std::pair<std::string, size_t> debug_instruction(Instruction inst, int oper=0);
std::pair<std::string, size_t> debug_instruction(Bytecode const& bt, uint32_t function_id, uint32_t addr);
enum class OperandType { NoOperand, Int8, Int16, Int32 };
OperandType instruction_operand_type(Instruction instruction);
}
#endif //TYCHE_INSTRUCTION_HH

16
src/vm/location.hh Normal file
View File

@@ -0,0 +1,16 @@
#ifndef TYCHE_LOCATION_HH
#define TYCHE_LOCATION_HH
#include <cstdint>
namespace tyche {
struct Location
{
uint32_t function_id;
uint32_t pc;
};
}
#endif //TYCHE_LOCATION_HH

View File

@@ -21,6 +21,8 @@ public:
void push_fp();
void pop_fp();
[[nodiscard]] size_t fp_level() const { return fps_.size(); }
private:
std::vector<Value> stack_;
std::stack<size_t> fps_;

View File

@@ -27,7 +27,19 @@ void VM::call(size_t n_params)
void VM::run_until_return()
{
size_t level = stack_.fp_level();
while (stack_.fp_level() >= level)
step();
}
void VM::step()
{
Operation op = code_.operation(loc_.top());
switch (op.instruction) {
// TODO
}
loc_.top() = op.next_location;
}
} // tyche

View File

@@ -2,6 +2,7 @@
#define TYCHE_VM_HH
#include "code.hh"
#include "location.hh"
#include "stack.hh"
namespace tyche {
@@ -13,9 +14,8 @@ public:
void call(size_t n_params);
private:
struct Location { uint32_t function_id; uint32_t pc; };
void run_until_return();
void step();
Stack stack_;
Code code_;