From f201021a07c68f74a7d32ec87333a35f29e7a1b4 Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Wed, 18 Mar 2026 21:20:54 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E9=87=8D=E6=9E=84VM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/debug.hpp | 128 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 include/debug.hpp diff --git a/include/debug.hpp b/include/debug.hpp new file mode 100644 index 0000000..534b147 --- /dev/null +++ b/include/debug.hpp @@ -0,0 +1,128 @@ +// +// 调试输出宏定义 +// 定义DEBUG_OUTPUT宏来启用调试输出 +// Created by DaLL +// + +#pragma once + +#include +#include +#include + +// 启用调试输出宏 - 定义这个宏来启用调试输出 +// 注释掉这一行来禁用调试输出 +#define DEBUG_OUTPUT + +#ifdef DEBUG_OUTPUT + +// 控制台颜色代码 +#define COLOR_RESET "\033[0m" +#define COLOR_YELLOW "\033[33m" +#define COLOR_GREEN "\033[32m" +#define COLOR_CYAN "\033[36m" +#define COLOR_MAGENTA "\033[35m" +#define COLOR_RED "\033[31m" +#define COLOR_BLUE "\033[34m" +#define COLOR_WHITE "\033[37m" + +// 带颜色的输出宏 +#define DEBUG_COLOR(color, msg) do { \ + std::cerr << color << "[DEBUG] " << __FILE__ << ":" << __LINE__ << " - " << msg << COLOR_RESET << std::endl; \ +} while(0) + +// 基础调试输出宏(黄色) +#define DEBUG_LOG(msg) do { \ + std::cerr << COLOR_YELLOW << "[DEBUG] " << __FILE__ << ":" << __LINE__ << " - " << msg << COLOR_RESET << std::endl; \ +} while(0) + +// 带格式的调试输出(黄色) +#define DEBUG_LOG_FMT(fmt, ...) do { \ + std::cerr << COLOR_YELLOW << "[DEBUG] " << __FILE__ << ":" << __LINE__ << " - "; \ + std::fprintf(stderr, fmt, ##__VA_ARGS__); \ + std::cerr << COLOR_RESET << std::endl; \ +} while(0) + +// 进入函数调试(青色) +#define DEBUG_ENTER_FUNC() do { \ + std::cerr << COLOR_CYAN << "[DEBUG] ENTER: " << __FUNCTION__ << " at " << __FILE__ << ":" << __LINE__ << COLOR_RESET << std::endl; \ +} while(0) + +// 离开函数调试(绿色) +#define DEBUG_LEAVE_FUNC() do { \ + std::cerr << COLOR_GREEN << "[DEBUG] LEAVE: " << __FUNCTION__ << " at " << __FILE__ << ":" << __LINE__ << COLOR_RESET << std::endl; \ +} while(0) + +// 值调试(黄色) +#define DEBUG_VAL(name, val) do { \ + std::cerr << COLOR_YELLOW << "[DEBUG] " << __FILE__ << ":" << __LINE__ << " - " << name << " = " << (val) << COLOR_RESET << std::endl; \ +} while(0) + +// 指针调试(洋红色) +#define DEBUG_PTR(name, ptr) do { \ + std::cerr << COLOR_MAGENTA << "[DEBUG] " << __FILE__ << ":" << __LINE__ << " - " << name << " = " << static_cast(ptr) << COLOR_RESET << std::endl; \ +} while(0) + +// 错误调试(红色) +#define DEBUG_ERROR(msg) do { \ + std::cerr << COLOR_RED << "[ERROR] " << __FILE__ << ":" << __LINE__ << " - " << msg << COLOR_RESET << std::endl; \ +} while(0) + +// Token列表展示(蓝色) +#define DEBUG_TOKEN_LIST(tokens) do { \ + std::cerr << COLOR_BLUE << "\n========== TOKEN LIST ==========" << COLOR_RESET << std::endl; \ + for (size_t i = 0; i < tokens.size(); i++) { \ + std::cerr << COLOR_BLUE << "[" << std::setw(3) << i << "] " << tokens[i] << COLOR_RESET << std::endl; \ + } \ + std::cerr << COLOR_BLUE << "================================" << COLOR_RESET << std::endl; \ +} while(0) + +// 字节码展示(青色) +#define DEBUG_BYTECODE(ops) do { \ + std::cerr << COLOR_CYAN << "\n========== BYTECODE ==========" << COLOR_RESET << std::endl; \ + Generator::print_ops(const_cast&>(ops)); \ + std::cerr << COLOR_CYAN << "==============================" << COLOR_RESET << std::endl; \ +} while(0) + +// 执行步骤展示(黄色) +#define DEBUG_EXEC_STEP(pc, op, desc) do { \ + std::cerr << COLOR_YELLOW << "[EXEC] PC=" << std::setw(4) << pc << " | " << desc << COLOR_RESET << std::endl; \ +} while(0) + +// 寄存器状态展示(白色) +#define DEBUG_REGS(regs) do { \ + std::cerr << COLOR_WHITE << " REGS: "; \ + for (size_t i = 0; i < REG_COUNT && i < 16; i++) { \ + if (regs[i].type == ValueType::Int) \ + std::cerr << "r" << i << "=" << regs[i].i64 << " "; \ + else if (regs[i].type == ValueType::Bool) \ + std::cerr << "r" << i << "=" << (regs[i].b ? "T" : "F") << " "; \ + else if (regs[i].type == ValueType::Float) \ + std::cerr << "r" << i << "=" << regs[i].f64 << " "; \ + } \ + std::cerr << COLOR_RESET << std::endl; \ +} while(0) + +// 分隔线 +#define DEBUG_SEPARATOR(title) do { \ + std::cerr << COLOR_YELLOW << "\n========== " << title << " ==========" << COLOR_RESET << std::endl; \ +} while(0) + +#else + +// 禁用时的空宏 +#define DEBUG_LOG(msg) do {} while(0) +#define DEBUG_LOG_FMT(fmt, ...) do {} while(0) +#define DEBUG_ENTER_FUNC() do {} while(0) +#define DEBUG_LEAVE_FUNC() do {} while(0) +#define DEBUG_VAL(name, val) do {} while(0) +#define DEBUG_PTR(name, ptr) do {} while(0) +#define DEBUG_COLOR(color, msg) do {} while(0) +#define DEBUG_ERROR(msg) do {} while(0) +#define DEBUG_TOKEN_LIST(tokens) do {} while(0) +#define DEBUG_BYTECODE(ops) do {} while(0) +#define DEBUG_EXEC_STEP(pc, op, desc) do {} while(0) +#define DEBUG_REGS(regs) do {} while(0) +#define DEBUG_SEPARATOR(title) do {} while(0) + +#endif From fae844bfa34d843f6ba6d86199c5622fc7c8689e Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Fri, 20 Mar 2026 23:25:11 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=90=91=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + compiler/ast.hpp | 9 +- compiler/generator/emit.cpp | 105 ++- compiler/generator/emit.hpp | 4 + compiler/generator/generator.cpp | 59 +- compiler/generator/generator.hpp | 12 + compiler/lexer.cpp | 530 +++++++------- compiler/lexer.hpp | 2 +- compiler/parser.cpp | 74 +- compiler/parser.hpp | 16 +- include/opcode.hpp | 6 +- include/vmcall.hpp | 56 +- runtime/value/value.cpp | 5 +- runtime/vm.cpp | 1123 +++++++++++++++++++++++++----- runtime/vm.hpp | 80 ++- runtime/vmcall.cpp | 61 ++ tools/lm/common/repl.cpp | 318 +++++++-- 17 files changed, 1868 insertions(+), 594 deletions(-) diff --git a/.gitignore b/.gitignore index 2f51a1e..e992330 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ ios-obj-log/* build/* obj/* rm-win-r.sh +当前的MyLamina.md +当前的MyLamina_详细版.md \ No newline at end of file diff --git a/compiler/ast.hpp b/compiler/ast.hpp index 1bcd1c3..d3dde5d 100644 --- a/compiler/ast.hpp +++ b/compiler/ast.hpp @@ -3,6 +3,7 @@ // #pragma once +#include #include #include #include @@ -23,7 +24,7 @@ namespace lmx { enum ASTKind { Program, - Binary, Unary, NumLiteral, StringLiteral, BoolLiteral, + Binary, Unary, NumLiteral, StringLiteral, BoolLiteral, VectorLiteral, BlockStmt, IfStmt, VarDecl, @@ -219,6 +220,12 @@ struct StringNode final : public ExprNode { ~StringNode() override = default; }; +struct VectorNode final : public ExprNode { + std::vector> elements; + explicit VectorNode(std::vector> elems) + : ExprNode(ASTKind::VectorLiteral), elements(std::move(elems)){} +}; + struct BinaryNode final : public ExprNode { std::shared_ptr left; std::shared_ptr right; diff --git a/compiler/generator/emit.cpp b/compiler/generator/emit.cpp index 66da3d2..cf392a7 100644 --- a/compiler/generator/emit.cpp +++ b/compiler/generator/emit.cpp @@ -32,12 +32,44 @@ void LMXOpcodeEmitter::emit_mov_ri(std::vector &ops, uint8_t r void LMXOpcodeEmitter::emit_mov_rr(std::vector &ops, uint8_t r1, uint8_t r2) { if (r1 == r2) return; - if (ret_type == Reg) { - // 如果上一条指令的 目标寄存器 与本条指令的 源寄存器 相同 - // 不生成新指令, 修改上条指令目标为本条目标 - if (auto& last = ops.back(); last.operands[0] == r2) { - last.operands[0] = r1; - return; + // 只有当ret_type为Reg时才进行优化,并且上一条指令必须是返回Reg类型的指令 + if (ret_type == Reg && !ops.empty()) { + // 检查上一条指令是否是返回Reg类型的指令 + const auto& last_op = ops.back(); + // 只对返回Reg类型的指令进行优化 + bool is_reg_return_op = false; + switch (last_op.op) { + case lmx::runtime::Opcode::MOV_RI: + case lmx::runtime::Opcode::MOV_RR: + case lmx::runtime::Opcode::MOV_RC: + case lmx::runtime::Opcode::ADD: + case lmx::runtime::Opcode::SUB: + case lmx::runtime::Opcode::MUL: + case lmx::runtime::Opcode::DIV: + case lmx::runtime::Opcode::MOD: + case lmx::runtime::Opcode::POW: + case lmx::runtime::Opcode::CMP_GE: + case lmx::runtime::Opcode::CMP_LT: + case lmx::runtime::Opcode::CMP_LE: + case lmx::runtime::Opcode::CMP_GT: + case lmx::runtime::Opcode::CMP_EQ: + case lmx::runtime::Opcode::CMP_NE: + case lmx::runtime::Opcode::AND: + case lmx::runtime::Opcode::OR: + case lmx::runtime::Opcode::LOCAL_GET: + is_reg_return_op = true; + break; + default: + is_reg_return_op = false; + break; + } + // 只有当上一条指令是返回Reg类型的指令时才进行优化 + if (is_reg_return_op) { + // 对于返回Reg类型的指令,operands[0]是目标寄存器 + if (last_op.operands[0] == r2) { + ops.back().operands[0] = r1; + return; + } } } lmx::runtime::Op op(lmx::runtime::Opcode::MOV_RR); @@ -257,6 +289,67 @@ void LMXOpcodeEmitter::emit_dec(std::vector &ops, uint8_t r) { ops.push_back(op); } +void LMXOpcodeEmitter::emit_mov_rm(std::vector &ops, uint8_t r1, uint8_t r2, int8_t offest) { + runtime::Op op(runtime::Opcode::MOV_RM); + op.operands[0] = r1; + op.operands[1] = r2; + op.operands[2] = static_cast(offest); + ops.push_back(op); + ret_type = Reg; +} + +void LMXOpcodeEmitter::emit_mov_mi(std::vector &ops, uint8_t r1, int8_t offest1, int64_t imm) { + runtime::Op op(runtime::Opcode::MOV_MI); + op.operands[0] = r1; + op.operands[1] = static_cast(offest1); + write_imm(op.operands + 2, imm); + ops.push_back(op); + ret_type = None; +} + +void LMXOpcodeEmitter::emit_mov_mr(std::vector &ops, uint8_t r1, int8_t offest1, uint8_t r2) { + runtime::Op op(runtime::Opcode::MOV_MR); + op.operands[0] = r1; + op.operands[1] = static_cast(offest1); + op.operands[2] = r2; + ops.push_back(op); + ret_type = None; +} + +void LMXOpcodeEmitter::emit_mov_mm(std::vector &ops, uint8_t r1, int8_t offest1, uint8_t r2, int8_t offest2) { + runtime::Op op(runtime::Opcode::MOV_MM); + op.operands[0] = r1; + op.operands[1] = static_cast(offest1); + op.operands[2] = r2; + op.operands[3] = static_cast(offest2); + ops.push_back(op); + ret_type = None; +} + +void LMXOpcodeEmitter::emit_mov_mc(std::vector &ops, uint8_t r1, int8_t offest1, uint64_t idx) { + runtime::Op op(runtime::Opcode::MOV_MC); + op.operands[0] = r1; + op.operands[1] = static_cast(offest1); + write_imm(op.operands + 2, std::bit_cast(idx)); + ops.push_back(op); + ret_type = None; +} + +void LMXOpcodeEmitter::emit_push(std::vector& ops, uint8_t reg) { + runtime::Op op(runtime::Opcode::PUSH); + op.operands[0] = reg; + ops.push_back(op); + ret_type = None; +} + +void LMXOpcodeEmitter::emit_create_vector(std::vector& ops, uint8_t rd, uint8_t count) { + runtime::Op op(runtime::Opcode::CREATE_VECTOR); + op.operands[0] = rd; + op.operands[1] = count; + ops.push_back(op); + ret_type = Reg; +} + #undef getter_opt_code } // namespace lmx diff --git a/compiler/generator/emit.hpp b/compiler/generator/emit.hpp index 4c265c9..ee99792 100644 --- a/compiler/generator/emit.hpp +++ b/compiler/generator/emit.hpp @@ -75,6 +75,10 @@ class LMC_API LMXOpcodeEmitter { static void emit_or(std::vector &ops, uint8_t r1, uint8_t r2, uint8_t r3); static void emit_vmc(std::vector &ops, uint16_t idx); + + static void emit_push(std::vector& ops, uint8_t reg); + + static void emit_create_vector(std::vector& ops, uint8_t rd, uint8_t count); }; } // namespace lmx \ No newline at end of file diff --git a/compiler/generator/generator.cpp b/compiler/generator/generator.cpp index 85cdb2e..5d7473b 100644 --- a/compiler/generator/generator.cpp +++ b/compiler/generator/generator.cpp @@ -11,6 +11,7 @@ #include #include +#include "debug.hpp" #include "emit.hpp" #include "opcode.hpp" #include "vmcall.hpp" @@ -24,7 +25,7 @@ Allocator::Allocator() { } size_t Allocator::alloc() { - for (size_t i = 0; i < REG_COUNT; i++) { + for (size_t i = 1; i < REG_COUNT; i++) { if (!bitset.test(i)) { bitset.set(i); return i; @@ -75,6 +76,7 @@ size_t Generator::gen(std::shared_ptr &n) { case NumLiteral: return gen_num(n); case StringLiteral: return gen_string(n); case BoolLiteral: return gen_bool(n); + case VectorLiteral: return this->gen_vector(n); case BlockStmt: return gen_block(n); case IfStmt: return gen_if(n); case FuncDecl: return gen_function(n); @@ -454,6 +456,61 @@ size_t Generator::gen_bool(std::shared_ptr &n) { return expr_ret_reg; } +size_t Generator::gen_vector(std::shared_ptr &n) { + const auto node = std::static_pointer_cast(std::move(n)); + DEBUG_LOG("gen vector"); + regs.print_regs(); + + // 1. 计算向量的大小 + const size_t vector_size = node->elements.size(); + DEBUG_LOG("vector_size: " << vector_size); + + // 2. 为所有元素生成代码,获取它们的值到寄存器 + std::vector elem_regs; + elem_regs.reserve(node->elements.size()); + + for (auto& elem : node->elements) { + std::shared_ptr elem_node = elem; + DEBUG_LOG("Now processing: " << elem_node->kind << ": " << elem_node); + auto reg = gen(elem_node); // 生成元素代码,返回存放结果的寄存器 + if (reg == -1) { + // 如果生成元素代码时出错,设置错误标志并返回 + node_has_error = true; + return -1; + } + elem_regs.push_back(reg); + DEBUG_LOG("Pushed elem_regs:"); + for (auto const& elem_in : elem_regs) DEBUG_LOG(elem_in); + regs.print_regs(); + } + + // 3. 将求解后的值依次压栈 + for (auto reg : elem_regs) { + LMXOpcodeEmitter::emit_push(ops, reg); + DEBUG_LOG("Pushed r" << reg << " to stack"); + } + + // 4. 调用 CREATE_VECTOR 字节码 + // 参数: 目标寄存器, 元素个数 + auto result_reg = regs.alloc(); // 分配结果寄存器 + LMXOpcodeEmitter::emit_create_vector(ops, result_reg, vector_size); + DEBUG_LOG("CREATE_VECTOR r" << result_reg << ", " << vector_size); + + // 5. 释放元素寄存器 + for (const auto reg : elem_regs) { + regs.free(reg); + DEBUG_LOG("Freed register: " << reg); + regs.print_regs(); + } + + // 6. 标记返回寄存器需要在使用后释放 + expr_release = true; + + DEBUG_LOG("gen_vector finished, returning result_reg: " << result_reg); + regs.print_regs(); + return result_reg; // 返回结果寄存器的索引 +} + size_t Generator::gen_block(std::shared_ptr &n) { std::unordered_map save(cur.back()->locals); diff --git a/compiler/generator/generator.hpp b/compiler/generator/generator.hpp index 87fe0ee..2422a8b 100644 --- a/compiler/generator/generator.hpp +++ b/compiler/generator/generator.hpp @@ -13,6 +13,7 @@ #include #include +#include "debug.hpp" #include "../ast.hpp" #include "lmx_export.hpp" @@ -34,6 +35,15 @@ class LMC_API Allocator { size_t alloc(size_t i); void free(size_t i); bool is_free(size_t i); + void print_regs() const { + std::string regs_str = "Allocated registers: "; + for (size_t i = 0; i < REG_COUNT; i++) { + if (bitset.test(i)) { + regs_str += "r" + std::to_string(i) + " "; + } + } + DEBUG_LOG(regs_str); + } }; class LMC_API Generator { @@ -70,6 +80,8 @@ class LMC_API Generator { size_t gen_bool(std::shared_ptr& n); + size_t gen_vector(std::shared_ptr& n); + size_t gen_block(std::shared_ptr& n); size_t basic_gen_block(std::shared_ptr &n); diff --git a/compiler/lexer.cpp b/compiler/lexer.cpp index d7d9b57..9911b2a 100644 --- a/compiler/lexer.cpp +++ b/compiler/lexer.cpp @@ -1,278 +1,252 @@ -// -// Created by geguj on 2025/12/28. -// - -#include "lexer.hpp" - -#include -#include - -namespace lmx { - -std::ostream& operator<<(std::ostream& os, const Token& t) { - os << "Token("; - switch (t.type) { - case TokenType::END_OF_FILE: os << "END_OF_FILE"; break; - case TokenType::IDENTIFIER: os << "IDENTIFIER"; break; - case TokenType::NUM_LITERAL: os << "INT_LITERAL"; break; - case TokenType::STRING_LITERAL: os << "STRING_LITERAL"; break; - case TokenType::COMMA: os << "COMMA"; break; - case TokenType::TRUE_LITERAL: os << "TRUE_LITERAL"; break; - case TokenType::FALSE_LITERAL: os << "FALSE_LITERAL"; break; - case TokenType::OPER_PLUS: os << "OPER_PLUS"; break; - case TokenType::OPER_MINUS: os << "OPER_MINUS"; break; - case TokenType::OPER_MUL: os << "OPER_MUL"; break; - case TokenType::OPER_DIV: os << "OPER_DIV"; break; - case TokenType::OPER_MOD: os << "OPER_MOD"; break; - case TokenType::EQ: os << "EQ"; break; - case TokenType::GE: os << "GE"; break; - case TokenType::GT: os << "GT"; break; - case TokenType::LE: os << "LE"; break; - case TokenType::LT: os << "LT"; break; - case TokenType::COLON: os << "COLON"; break; - case TokenType::COL_COLON: os << "COL_COLON"; break; - case TokenType::OPER_POW: os << "OPER_POW"; break; - case TokenType::ASSIGN: os << "ASSIGN"; break; - case TokenType::NOT: os << "NOT"; break; - case TokenType::NE: os << "NE"; break; - case TokenType::LPAREN: os << "LPAREN"; break; - case TokenType::RPAREN: os << "RPAREN"; break; - case TokenType::LBRACK: os << "LBRACK"; break; - case TokenType::RBRACK: os << "RBRACK"; break; - case TokenType::LBRACE: os << "LBRACE"; break; - case TokenType::RBRACE: os << "RBRACE"; break; - - case TokenType::UNKNOWN: os << "UNKNOWN"; break; - case TokenType::KW_FUNC: os << "KEYWORD_FUNC"; break; - case TokenType::KW_RETURN: os << "KEYWORD_RETURN"; break; - default: os << "UNKNOWN"; - } - os << ", " << t.text << ", " << t.line << ", " << t.col << ')'; - return os; -} - -void Lexer::advance() { - pos++; - if (src[pos] == '\n') { - line++; - col = 1; - } else col++; -} - -Token Lexer::next() { - while (isspace(src[pos])) { - advance(); - } - if (pos >= src.size()) return {TokenType::END_OF_FILE,"", line, col}; - - switch (src[pos]) { - case '+': { - advance(); - return {TokenType::OPER_PLUS, "+", line, col}; - } - case '-': { - advance(); - return {TokenType::OPER_MINUS, "-", line, col}; - } - case '*': { - advance(); - return {TokenType::OPER_MUL, "*", line, col}; - } - case '/': { - advance(); - return {TokenType::OPER_DIV, "/", line, col}; - } - case '%': { - advance(); - return {TokenType::OPER_MOD, "%", line, col}; - } - case '=': { - advance(); - if (src[pos] == '=') { - advance(); - return {TokenType::EQ, "==", line, col}; - } - return {TokenType::ASSIGN, "=", line, col}; - } - case '>': { - advance(); - if (src[pos] == '=') { - advance(); - return {TokenType::GE, ">=", line, col}; - } - return {TokenType::GT, ">", line, col}; - } - case '<': { - advance(); - if (src[pos] == '=') { - advance(); - return {TokenType::LE, "<=", line, col}; - } - return {TokenType::LT, "<", line, col}; - } - case ':': { - advance(); - if (src[pos] == ':') { - advance(); - return {TokenType::COL_COLON, "::", line, col}; - } - return {TokenType::COLON, ":", line, col}; - } - case '^': { - advance(); - return {TokenType::OPER_POW, "^", line, col}; - } - case '#': { - while (pos <= src.size() && src[pos] != '\n' ) - advance(); - advance(); - return {TokenType::COMMENT, {}, line, col}; - } - case '"': { - advance(); - std::string str; - while (src[pos] != '"') { - if (src[pos] == '\\') { - advance(); - switch (src[pos]) { - case 'n': str += '\n'; break; - case 't': str += '\t'; break; - case 'r': str += '\r'; break; - case 'b': str += '\b'; break; - case 'f': str += '\f'; break; - case 'v': str += '\v'; break; - case '0': str += '\0'; break; - default: str += src[pos]; break; - } - advance(); - continue; - } - str += src[pos]; - advance(); - } - advance(); - - return {TokenType::STRING_LITERAL, str, line, col - str.size()}; - } - case '(': { - advance(); - return {TokenType::LPAREN, "(", line, col}; - } - case ')': { - advance(); - return {TokenType::RPAREN, ")", line, col}; - } - case '{': { - advance(); - return {TokenType::LBRACE, "{", line, col}; - } - case '}': { - advance(); - return {TokenType::RBRACE, "}", line, col}; - } - case '[': { - advance(); - return {TokenType::LBRACK, "[", line, col}; - } - case ']': { - advance(); - return {TokenType::RBRACK, "]", line, col}; - } - case ',': { - advance(); - return {TokenType::COMMA, ", ", line, col}; - } - case '!': { - advance(); - if (src[pos] == '=') { - advance(); - return {TokenType::NE, "!=", line, col}; - } - return {TokenType::NOT, "!", line, col}; - } - case '|': { - advance(); - if (src[pos] == '>') { - advance(); - return {TokenType::PIPE, "|>", line, col}; - } - if (src[pos] == '|') { - advance(); - return {TokenType::OR, "||", line, col}; - } - return {TokenType::UNKNOWN, std::string(1, src[pos]), line, col}; - } - case '&': { - advance(); - if (src[pos] == '&') { - advance(); - return {TokenType::AND, "&&", line, col}; - } - return {TokenType::UNKNOWN, std::string(1, src[pos]), line, col}; - } - case '.': { - advance(); - return {TokenType::DOT, ".", line, col}; - } - default: { - if (isdigit(src[pos])) { - auto cur_line = line, cur_col = col; - std::string num; - while (isdigit(src[pos]) || src[pos] == '_') { - if (src[pos] == '_') { - advance(); - continue; - } - num += src[pos]; - advance(); - } - return {TokenType::NUM_LITERAL, num, cur_line, cur_col}; - } - if (isalpha(src[pos]) || src[pos] == '_') { - std::string id; - auto cur_line = line, cur_col = col; - while (isalnum(src[pos])|| src[pos] == '_') { - id += src[pos]; - advance(); - } - static const std::unordered_map keywords = { - {"func", TokenType::KW_FUNC}, - {"return", TokenType::KW_RETURN}, - {"if", TokenType::KW_IF}, - {"else", TokenType::KW_ELSE}, - {"let", TokenType::KW_LET}, - {"__VMC", TokenType::KW_VMC}, - {"module", TokenType::KW_MODULE}, - {"use", TokenType::KW_USE}, - {"loop", TokenType::KW_LOOP}, - {"break", TokenType::KW_BREAK}, - {"continue", TokenType::KW_CONTINUE}, - }; - if (const auto it = keywords.find(id); it != keywords.end()) { - return {it->second, id, cur_line, cur_col}; - } - return {TokenType::IDENTIFIER, id, cur_line, cur_col}; - } - } - } - - auto token = Token{TokenType::UNKNOWN, std::string(1, src[pos]), line, col}; - advance(); - return token; -} - -std::vector Lexer::tokenize(const std::string& new_src) { - src = new_src; - pos = 0; - line = 1; - col = 1; - std::vector tokens; - while (pos < src.size()) { - tokens.push_back(next()); - } - // Add EOF token at the end - tokens.push_back({TokenType::END_OF_FILE, "", line, col}); - return tokens; -} - -} +// +// Created by geguj on 2025/12/28. +// + +#include "lexer.hpp" + +#include +#include +#include + +namespace lmx { + +LMC_API std::ostream& operator<<(std::ostream& os, const Token& t) { + os << "Token("; + switch (t.type) { + case TokenType::END_OF_FILE: os << "END_OF_FILE"; break; + case TokenType::IDENTIFIER: os << "IDENTIFIER"; break; + case TokenType::NUM_LITERAL: os << "NUM_LITERAL"; break; + case TokenType::STRING_LITERAL: os << "STRING_LITERAL"; break; + case TokenType::COMMA: os << "COMMA"; break; + case TokenType::TRUE_LITERAL: os << "TRUE_LITERAL"; break; + case TokenType::FALSE_LITERAL: os << "FALSE_LITERAL"; break; + case TokenType::OPER_PLUS: os << "OPER_PLUS"; break; + case TokenType::OPER_MINUS: os << "OPER_MINUS"; break; + case TokenType::OPER_MUL: os << "OPER_MUL"; break; + case TokenType::OPER_DIV: os << "OPER_DIV"; break; + case TokenType::OPER_MOD: os << "OPER_MOD"; break; + case TokenType::EQ: os << "EQ"; break; + case TokenType::GE: os << "GE"; break; + case TokenType::GT: os << "GT"; break; + case TokenType::LE: os << "LE"; break; + case TokenType::LT: os << "LT"; break; + case TokenType::COLON: os << "COLON"; break; + case TokenType::COL_COLON: os << "COL_COLON"; break; + case TokenType::OPER_POW: os << "OPER_POW"; break; + case TokenType::ASSIGN: os << "ASSIGN"; break; + case TokenType::NOT: os << "NOT"; break; + case TokenType::NE: os << "NE"; break; + case TokenType::LPAREN: os << "LPAREN"; break; + case TokenType::RPAREN: os << "RPAREN"; break; + case TokenType::LBRACK: os << "LBRACK"; break; + case TokenType::RBRACK: os << "RBRACK"; break; + case TokenType::LBRACE: os << "LBRACE"; break; + case TokenType::RBRACE: os << "RBRACE"; break; + case TokenType::UNKNOWN: os << "UNKNOWN"; break; + case TokenType::KW_FUNC: os << "KEYWORD_FUNC"; break; + case TokenType::KW_RETURN: os << "KEYWORD_RETURN"; break; + case TokenType::KW_IF: os << "KEYWORD_IF"; break; + case TokenType::KW_ELSE: os << "KEYWORD_ELSE"; break; + case TokenType::KW_LET: os << "KEYWORD_LET"; break; + case TokenType::KW_VMC: os << "KEYWORD_VMC"; break; + case TokenType::KW_MODULE: os << "KEYWORD_MODULE"; break; + case TokenType::KW_USE: os << "KEYWORD_USE"; break; + case TokenType::KW_LOOP: os << "KEYWORD_LOOP"; break; + case TokenType::KW_BREAK: os << "KEYWORD_BREAK"; break; + case TokenType::KW_CONTINUE: os << "KEYWORD_CONTINUE"; break; + case TokenType::PIPE: os << "PIPE"; break; + case TokenType::OR: os << "OR"; break; + case TokenType::AND: os << "AND"; break; + case TokenType::DOT: os << "DOT"; break; + case TokenType::COMMENT: os << "COMMENT"; break; + default: os << "UNKNOWN"; + } + os << ", " << t.text << ", " << t.line << ", " << t.col << ')'; + return os; +} + +// 定义token类型和对应的正则表达式 +struct TokenPattern { + TokenType type; + std::regex pattern; + TokenPattern(TokenType t, const std::string& regex_str) : type(t), pattern(regex_str) {} +}; + +// 优先级从高到低排序 +static const std::vector token_patterns = { + {TokenType::COMMENT, "^#.*?$"}, + {TokenType::STRING_LITERAL, "^\"(\\.|[^\\\"])*\""}, + {TokenType::EQ, "^=="}, + {TokenType::NE, "^!="}, + {TokenType::GE, "^>="}, + {TokenType::LE, "^<="}, + {TokenType::OR, "^\\|\\|"}, + {TokenType::AND, "^&&"}, + {TokenType::PIPE, "^\\|>"}, + {TokenType::COL_COLON, "^::"}, + {TokenType::OPER_PLUS, "^\\+"}, + {TokenType::OPER_MINUS, "^-"}, + {TokenType::OPER_MUL, "^\\*"}, + {TokenType::OPER_DIV, "^/"}, + {TokenType::OPER_MOD, "^%"}, + {TokenType::OPER_POW, "^\\^"}, + {TokenType::ASSIGN, "^="}, + {TokenType::NOT, "^!"}, + {TokenType::GT, "^>"}, + {TokenType::LT, "^<"}, + {TokenType::COLON, "^:"}, + {TokenType::LPAREN, "^\\("}, + {TokenType::RPAREN, "^\\)"}, + {TokenType::LBRACE, "^\\{"}, + {TokenType::RBRACE, "^\\}"}, + {TokenType::LBRACK, "^\\["}, + {TokenType::RBRACK, "^\\]"}, + {TokenType::COMMA, "^,"}, + {TokenType::DOT, "^\\."}, + {TokenType::NUM_LITERAL, "^\\d[_\\d]*"}, + {TokenType::IDENTIFIER, "^[a-zA-Z_][a-zA-Z0-9_]*"}, +}; + +// 关键字映射 +static const std::unordered_map keywords = { + {"func", TokenType::KW_FUNC}, + {"return", TokenType::KW_RETURN}, + {"if", TokenType::KW_IF}, + {"else", TokenType::KW_ELSE}, + {"let", TokenType::KW_LET}, + {"__VMC", TokenType::KW_VMC}, + {"module", TokenType::KW_MODULE}, + {"use", TokenType::KW_USE}, + {"loop", TokenType::KW_LOOP}, + {"break", TokenType::KW_BREAK}, + {"continue", TokenType::KW_CONTINUE}, + {"true", TokenType::TRUE_LITERAL}, + {"false", TokenType::FALSE_LITERAL}, +}; + +// 移除advance方法,因为我们将使用正则表达式匹配来更新位置 + +Token Lexer::next() { + // 跳过空白字符 + while (pos < src.size() && isspace(src[pos])) { + if (src[pos] == '\n') { + line++; + col = 1; + } else { + col++; + } + pos++; + } + + if (pos >= src.size()) { + return {TokenType::END_OF_FILE, "", line, col}; + } + + // 提取当前位置开始的子串 + std::string remaining = src.substr(pos); + + // 尝试匹配所有token模式 + for (const auto& pattern : token_patterns) { + std::smatch match; + if (std::regex_search(remaining, match, pattern.pattern)) { + std::string matched_text = match.str(0); + size_t match_length = matched_text.size(); + + // 保存当前位置信息 + size_t token_line = line; + size_t token_col = col; + + // 更新位置信息 + for (char c : matched_text) { + if (c == '\n') { + line++; + col = 1; + } else { + col++; + } + } + pos += match_length; + + // 处理标识符和关键字 + if (pattern.type == TokenType::IDENTIFIER) { + auto it = keywords.find(matched_text); + if (it != keywords.end()) { + return {it->second, matched_text, token_line, token_col}; + } + } + + // 处理字符串字面量(去除引号) + if (pattern.type == TokenType::STRING_LITERAL) { + // 去除首尾引号 + std::string unquoted = matched_text.substr(1, matched_text.size() - 2); + // 处理转义字符 + std::string processed; + for (size_t i = 0; i < unquoted.size(); i++) { + if (unquoted[i] == '\\' && i + 1 < unquoted.size()) { + i++; + switch (unquoted[i]) { + case 'n': processed += '\n'; break; + case 't': processed += '\t'; break; + case 'r': processed += '\r'; break; + case 'b': processed += '\b'; break; + case 'f': processed += '\f'; break; + case 'v': processed += '\v'; break; + case '0': processed += '\0'; break; + default: processed += unquoted[i]; break; + } + } else { + processed += unquoted[i]; + } + } + return {TokenType::STRING_LITERAL, processed, token_line, token_col}; + } + + // 处理数字字面量(去除下划线) + if (pattern.type == TokenType::NUM_LITERAL) { + std::string num_without_underscores; + for (char c : matched_text) { + if (c != '_') { + num_without_underscores += c; + } + } + return {TokenType::NUM_LITERAL, num_without_underscores, token_line, token_col}; + } + + // 跳过注释 + if (pattern.type == TokenType::COMMENT) { + return next(); + } + + return {pattern.type, matched_text, token_line, token_col}; + } + } + + // 无法识别的字符 + char unknown_char = src[pos]; + Token token = {TokenType::UNKNOWN, std::string(1, unknown_char), line, col}; + pos++; + col++; + return token; +} + +std::vector Lexer::tokenize(const std::string& new_src) { + src = new_src; + pos = 0; + line = 1; + col = 1; + std::vector tokens; + + while (pos < src.size()) { + Token t = next(); + if (t.type != TokenType::COMMENT) { + tokens.push_back(t); + } + } + + // Add EOF token at the end + tokens.push_back({TokenType::END_OF_FILE, "", line, col}); + + return tokens; +} + +} \ No newline at end of file diff --git a/compiler/lexer.hpp b/compiler/lexer.hpp index 995481e..733de57 100644 --- a/compiler/lexer.hpp +++ b/compiler/lexer.hpp @@ -5,6 +5,7 @@ #pragma once #include #include +#include #include "../include/lmx_export.hpp" @@ -44,7 +45,6 @@ struct LMC_API Token { class LMC_API Lexer { size_t pos{0}, line{1}, col{1}; - void advance(); std::string& src; Token next(); diff --git a/compiler/parser.cpp b/compiler/parser.cpp index 4720432..898c737 100644 --- a/compiler/parser.cpp +++ b/compiler/parser.cpp @@ -4,11 +4,6 @@ #include "parser.hpp" -#include -#include - -#include "../include/opcode.hpp" - namespace lmx { void Parser::parse_args(std::vector> &args) { @@ -150,6 +145,70 @@ std::shared_ptr Parser::parse_if() { } return std::make_shared(condition, then_block, else_block); } +std::shared_ptr Parser::parse_vector() { + // 期望 '[' + if (!match(TokenType::LBRACK)) { + error("expected '[' at start of vector"); + return nullptr; + } + advance(); // 跳过 '[' + + std::vector> elements; + + // 处理空向量情况 + if (match(TokenType::RBRACK)) { + advance(); // 跳过 ']' + return std::make_shared(std::move(elements)); + } + + // 解析第一个元素 + elements.push_back(parse_expr()); + + // 继续解析后续元素,直到遇到 ']' + while (!match(TokenType::RBRACK) && !is_eof()) { + // 必须有逗号分隔 + if (!match(TokenType::COMMA)) { + error("expected ',' between vector elements"); + // 错误恢复:尝试找到下一个逗号或右括号 + while (!match(TokenType::COMMA) && !match(TokenType::RBRACK) && !is_eof()) { + advance(); + } + // 如果找到逗号,跳过它并继续解析下一个元素 + if (match(TokenType::COMMA)) { + advance(); + if (!match(TokenType::RBRACK)) { + elements.push_back(parse_expr()); + } + } + continue; + } + + advance(); // 跳过 ',' + + // 允许尾随逗号?例如 [1, 2, 3,] + if (match(TokenType::RBRACK)) { + break; + } + + elements.push_back(parse_expr()); + } + + // 检查是否以 ']' 结尾 + if (!match(TokenType::RBRACK)) { + error("expected ']' at end of vector"); + // 尝试找到右括号来恢复 + while (!match(TokenType::RBRACK) && !is_eof()) { + advance(); + } + if (match(TokenType::RBRACK)) { + advance(); + } + return std::make_shared(std::move(elements)); // 仍返回已解析的部分 + } + + advance(); // 跳过 ']' + return std::make_shared(std::move(elements)); +} std::shared_ptr Parser::parse() { static bool in_func = false; static bool in_loop = false; @@ -402,7 +461,10 @@ std::shared_ptr Parser::parse_program() { std::shared_ptr Parser::factor() { std::shared_ptr fact = nullptr; - if (match(TokenType::NUM_LITERAL)) { + if (match(TokenType::IDENTIFIER) && cur().text == "vec") { + advance(); + fact = parse_vector(); + } else if (match(TokenType::NUM_LITERAL)) { fact = std::make_shared(cur().text); advance(); } else if (match(TokenType::LPAREN)) { diff --git a/compiler/parser.hpp b/compiler/parser.hpp index 5bcd8ef..ce65bcb 100644 --- a/compiler/parser.hpp +++ b/compiler/parser.hpp @@ -26,43 +26,29 @@ class LMC_API Parser { [[nodiscard]] bool is_eof() const; std::shared_ptr expr(); std::shared_ptr term(); - - std::shared_ptr factor(); - std::shared_ptr parse_func_call(); bool peek_match(TokenType type) const; - void check_eof(); - void error(const std::string& msg); std::shared_ptr parse_block(); - std::shared_ptr parse_string(); - std::shared_ptr parse_if(); std::shared_ptr parse_expr(); - std::shared_ptr parse_logical_and(); - std::shared_ptr parse_relational(); - std::shared_ptr parse_logical_or(); - + std::shared_ptr parse_vector(); std::shared_ptr parse_funcdecl(bool has_block); public: explicit Parser(std::vector& tokens): tokens(tokens) {} std::shared_ptr parse(); - std::shared_ptr parse_module(); - std::shared_ptr parse_type(); - - std::shared_ptr parse_program(); [[nodiscard]] bool error() const {return has_err;} }; diff --git a/include/opcode.hpp b/include/opcode.hpp index 85ccdca..27a4527 100644 --- a/include/opcode.hpp +++ b/include/opcode.hpp @@ -1,4 +1,4 @@ -// +// // Created by geguj on 2025/12/27. // @@ -30,6 +30,8 @@ enum class Opcode : uint8_t { AND, OR, VMC, // vmcall DEC, + PUSH, // 压栈指令 + CREATE_VECTOR, // 创建向量指令 }; inline uint8_t opcode_len(Opcode op) { @@ -70,6 +72,8 @@ inline uint8_t opcode_len(Opcode op) { case DEC: return 1; case JMP: return 8; case DEBUG_LOG: return 9; + case PUSH: return 1; // 压栈指令长度:1个寄存器 + case CREATE_VECTOR: return 2; // 创建向量指令长度:1个目标寄存器 + 1个立即数(元素数量); } return 0; } diff --git a/include/vmcall.hpp b/include/vmcall.hpp index f6df14c..9c5a3bb 100644 --- a/include/vmcall.hpp +++ b/include/vmcall.hpp @@ -1,27 +1,29 @@ -#pragma once -#include "../runtime/vm.hpp" - - -namespace lmx::runtime { -class VMCall { -#define VMCALL_INDEX_MAX UINT16_MAX -#define VMC_REGISTER(name) static void lm_##name(lmx::runtime::VirtualCore* self) - VMC_REGISTER(out); - VMC_REGISTER(in); - VMC_REGISTER(exit); - VMC_REGISTER(dyn_load); - VMC_REGISTER(dyn_set); - VMC_REGISTER(dyn_call); - -#undef VMC_REGISTER -#define VMC_REGISTER(name) void lmx::runtime::VMCall::lm_##name(lmx::runtime::VirtualCore* self) -public: - using VmCallType = void (*)(VirtualCore* self); - - static inline VmCallType vmcall_table[] = { - lm_out, lm_in, lm_exit, lm_dyn_load, lm_dyn_set, lm_dyn_call - }; - static inline uint16_t vmcall_count = sizeof(vmcall_table) / sizeof(VmCallType); -}; -} - +#pragma once +#include "../runtime/vm.hpp" + + +namespace lmx::runtime { +class VMCall { +#define VMCALL_INDEX_MAX UINT16_MAX +#define VMC_REGISTER(name) static void lm_##name(lmx::runtime::VirtualCore* self) + VMC_REGISTER(out); + VMC_REGISTER(in); + VMC_REGISTER(exit); + VMC_REGISTER(dyn_load); + VMC_REGISTER(dyn_set); + VMC_REGISTER(dyn_call); + VMC_REGISTER(alloc_memory); + VMC_REGISTER(store_memory); + +#undef VMC_REGISTER +#define VMC_REGISTER(name) void lmx::runtime::VMCall::lm_##name(lmx::runtime::VirtualCore* self) +public: + using VmCallType = void (*)(VirtualCore* self); + + static inline VmCallType vmcall_table[] = { + lm_out, lm_in, lm_exit, lm_dyn_load, lm_dyn_set, lm_dyn_call, lm_alloc_memory, lm_store_memory + }; + static inline uint16_t vmcall_count = sizeof(vmcall_table) / sizeof(VmCallType); +}; +} + diff --git a/runtime/value/value.cpp b/runtime/value/value.cpp index 8ce310e..af591ba 100644 --- a/runtime/value/value.cpp +++ b/runtime/value/value.cpp @@ -59,7 +59,10 @@ Value& Value::operator=(const Value& rhs) { case ValueType::Float: this->f64 = rhs.f64; break; case ValueType::Str: this->str = rhs.str; break; case ValueType::Bool: this->b = rhs.b; break; - case ValueType::Ptr: this->ptr = rhs.ptr; break; + case ValueType::Ptr: + this->ptr = rhs.ptr; + this->u64 = rhs.u64; + break; case ValueType::Null: this->null = nullptr; break; case ValueType::NO_ENUM_VALUE: break; // add this line to avoid warning. } diff --git a/runtime/vm.cpp b/runtime/vm.cpp index 6fde9c7..031091d 100644 --- a/runtime/vm.cpp +++ b/runtime/vm.cpp @@ -7,17 +7,18 @@ #include #include +#include "value/value.hpp" #include "vmcall.hpp" #include "../compiler/generator/generator.hpp" +#include "../include/debug.hpp" namespace lmx::runtime { VirtualCore::VirtualCore() : const_pool_top(nullptr), ste() { - static std::vector program; - ste.program = &program; + ste.program = nullptr; ste.pc = 0; - ste.cur.push_back(std::make_unique()); - ste.cur.back()->locals.resize(64); + ste.stack_frames.push_back(std::make_unique()); + ste.stack_frames.back()->locals.resize(64); } /*VirtualCore::VirtualCore(LMXState ste) : const_pool_top(nullptr), ste(std::move(ste)) {} @@ -27,195 +28,949 @@ VirtualCore::VirtualCore(LMXState ste, void* const_pool_top) : ste(std::move(ste)) { }*/ -Value *VirtualCore::get_value_from_pool(const size_t offest) const { +Value* VirtualCore::get_value_from_pool(const size_t offest) const { return static_cast(const_pool_top) + offest; } -int VirtualCore::run() { - RUN_CONTINUE: - const Opcode& op = ste.program->operator[](ste.pc).op; - const auto& operands = ste.program->operator[](ste.pc).operands; - switch (op) { - using enum Opcode; - case MOV_RI: { - ste.regs[operands[0]] = *reinterpret_cast(operands + 1); - ste.pc++; - goto RUN_CONTINUE; - } - case MOV_RM: { - // todo! - ste.pc++; - goto RUN_CONTINUE; - } - case MOV_RR: { - ste.regs[operands[0]] = ste.regs[operands[1]]; - ste.pc++; - goto RUN_CONTINUE; - } - case MOV_RC: { - ste.regs[operands[0]] = (char*)get_constant() + *(uint64_t*)(operands + 1); - ste.pc++; - goto RUN_CONTINUE; - } - case MOV_MI: { +bool VirtualCore::is_valid_register(uint8_t reg) const { + return reg < REG_COUNT; +} - // todo! - ste.pc++; - goto RUN_CONTINUE; - } - case MOV_MM: { - // todo! - ste.pc++; - goto RUN_CONTINUE; - } - case MOV_MR: { - // todo! - ste.pc++; - goto RUN_CONTINUE; - } - case MOV_MC: { - // todo! - ste.pc++; - goto RUN_CONTINUE; - } - case ADD: { - ste.regs[operands[0]] = ste.regs[operands[1]].i64 + ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case SUB: { - ste.regs[operands[0]] = ste.regs[operands[1]].i64 - ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case MUL: { - ste.regs[operands[0]] = ste.regs[operands[1]].i64 * ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case DIV: { - ste.regs[operands[0]] = ste.regs[operands[1]].i64 / ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case MOD: { - ste.regs[operands[0]] = ste.regs[operands[1]].i64 % ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case POW: { - ste.regs[operands[0]] = std::pow(ste.regs[operands[1]].f64, ste.regs[operands[2]].f64); - ste.pc++; - goto RUN_CONTINUE; - } - case FCALL: { - ste.ret_addr_stack.push_back(ste.pc + 1); // 返回地址 - ste.pc = *reinterpret_cast(operands); // 跳转地址 - const auto args_count = operands[8]; // 传参数量 - ste.cur.push_back(std::make_unique()); //新建栈帧 - ste.cur.back()->locals.resize(args_count + 1); - for (uint8_t i = 0; i != args_count; i++) ste.cur.back()->locals[i] = ste.regs[REG_COUNT_INDEX_MAX - i]; - goto RUN_CONTINUE; - } - case FRET: { - ste.pc = ste.ret_addr_stack.back(); //返回地址 - ste.ret_addr_stack.pop_back(); - ste.cur.pop_back(); // 恢复栈帧 - goto RUN_CONTINUE; - } - case HALT: { - return 0; - } - case DEBUG_LOG: { - fprintf(stderr,"[LogInfo]: %s\n", static_cast(const_pool_top) + *reinterpret_cast(operands)); - ste.pc++; - goto RUN_CONTINUE; - } - case JMP: { - ste.pc = *reinterpret_cast(operands); - goto RUN_CONTINUE; - } - case CMP_GE: { - ste.regs[operands[0]].b = ste.regs[operands[1]].i64 >= ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case CMP_LT: { - ste.regs[operands[0]].b = ste.regs[operands[1]].i64 < ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case CMP_LE: { - ste.regs[operands[0]].b = ste.regs[operands[1]].i64 <= ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case CMP_GT: { - ste.regs[operands[0]].b = ste.regs[operands[1]].i64 > ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; +bool VirtualCore::validate_registers(const uint8_t* regs, size_t count) const { + for (size_t i = 0; i < count; i++) { + if (!is_valid_register(regs[i])) { + return false; + } } - case CMP_EQ: { - ste.regs[operands[0]].b = ste.regs[operands[1]].i64 == ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case CMP_NE: { - ste.regs[operands[0]].b = ste.regs[operands[1]].i64 != ste.regs[operands[2]].i64; - ste.pc++; - goto RUN_CONTINUE; - } - case IF_TRUE: { - if (ste.regs[operands[0]].b) ste.pc = *reinterpret_cast(operands + 1); - else ste.pc++; - goto RUN_CONTINUE; - } - case IF_FALSE: { - if (!ste.regs[operands[0]].b) ste.pc = *reinterpret_cast(operands + 1); - else ste.pc++; - goto RUN_CONTINUE; - } - case FUNC_CREATE: { - while (ste.program->operator[](ste.pc).op != FUNC_END) {ste.pc++;} - ste.pc ++; - goto RUN_CONTINUE; - } - case FUNC_END: { - ste.pc++; - goto RUN_CONTINUE; - } - case LOCAL_GET: { - ste.regs[operands[0]] = ste.cur[operands[1]]->locals[*(uint16_t*)(operands + 2)]; - ste.pc++; - goto RUN_CONTINUE; - } - case LOCAL_SET: { - ste.cur[operands[0]]->locals[*(uint16_t*)(operands + 1)] = ste.regs[operands[3]]; - ste.pc++; - goto RUN_CONTINUE; - } - case AND: { - ste.regs[operands[0]].b = ste.regs[operands[1]].b && ste.regs[operands[2]].b; - ste.pc++; - goto RUN_CONTINUE; - } - case OR: { - ste.regs[operands[0]].b = ste.regs[operands[1]].b || ste.regs[operands[2]].b; - ste.pc++; - goto RUN_CONTINUE; - } - case VMC: { - VMCall::vmcall_table[*(uint16_t*)operands](this); - ste.pc++; - goto RUN_CONTINUE; + return true; +} + +bool VirtualCore::validate_jump_address(uint64_t address) const { + return address < ste.program->size(); +} + +bool VirtualCore::validate_stack_frame(size_t frame_index, size_t local_index) const { + if (frame_index >= ste.stack_frames.size()) { + return false; } - case DEC: { - ste.regs[operands[0]].i64--; - ste.pc++; - goto RUN_CONTINUE; + return local_index < ste.stack_frames[frame_index]->locals.size(); +} + +const char* VirtualCore::get_constant_string(uint64_t offset) const { + if (const_pool_top == nullptr) { + return nullptr; } + return static_cast(const_pool_top) + offset; +} + +void VirtualCore::handle_error(const char* error_message) const { + fprintf(stderr, "[Error]: %s\n", error_message); +} + +VirtualCore::~VirtualCore() { + // 清理栈帧 + ste.stack_frames.clear(); + // 清理返回地址栈 + ste.ret_addr_stack.clear(); + // 程序指针设为nullptr + ste.program = nullptr; + // 常量池指针设为nullptr + const_pool_top = nullptr; + // 清理加载的库 - 库的析构函数会自动释放动态库句柄 + libs.clear(); +} + +int VirtualCore::run() { + DEBUG_ENTER_FUNC(); + DEBUG_SEPARATOR("VM EXECUTION START"); + + if (ste.program == nullptr) { + handle_error("Program is null"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + + DEBUG_LOG_FMT("Program size: %zu instructions", ste.program->size()); + DEBUG_LOG("Starting VM execution"); + + while (ste.pc < ste.program->size()) { + const Opcode& op = ste.program->operator[](ste.pc).op; + const auto& operands = ste.program->operator[](ste.pc).operands; + + // 显示当前执行的字节码行 + std::cerr << COLOR_YELLOW << "[EXEC] " << ste.pc << " | " << std::flush; + // 根据指令类型显示详细信息 + switch (op) { + using enum Opcode; + case MOV_RI: { + std::cerr << "MOVRI: r" << (int)operands[0] << ", " << *reinterpret_cast(operands + 1); + break; + } + case MOV_RM: { + std::cerr << "MOVRM: r" << (int)operands[0] << ", 0x" << std::hex << (uint64_t)operands[1] << std::dec; + break; + } + case MOV_RR: { + std::cerr << "MOVRR: r" << (int)operands[0] << ", r" << (int)operands[1]; + break; + } + case MOV_RC: { + std::cerr << "MOVRC: r" << (int)operands[0] << ", const[" << *(uint64_t*)(operands + 1) << "]"; + break; + } + case MOV_MI: { + std::cerr << "MOVMI: 0x" << std::hex << (uint64_t)operands[0] << std::dec << ", " << *reinterpret_cast(operands + 1); + break; + } + case MOV_MM: { + std::cerr << "MOVMM: 0x" << std::hex << (uint64_t)operands[0] << ", 0x" << (uint64_t)operands[1] << std::dec; + break; + } + case MOV_MR: { + std::cerr << "MOVMR: 0x" << std::hex << (uint64_t)operands[0] << std::dec << ", r" << (int)operands[1]; + break; + } + case MOV_MC: { + std::cerr << "MOVMC: 0x" << std::hex << (uint64_t)operands[0] << std::dec << ", const[" << (uint64_t)operands[1] << "]"; + break; + } + case ADD: { + std::cerr << "ADD: r" << (int)operands[0] << " = r" << (int)operands[1] << " + r" << (int)operands[2]; + break; + } + case SUB: { + std::cerr << "SUB: r" << (int)operands[0] << " = r" << (int)operands[1] << " - r" << (int)operands[2]; + break; + } + case MUL: { + std::cerr << "MUL: r" << (int)operands[0] << " = r" << (int)operands[1] << " * r" << (int)operands[2]; + break; + } + case DIV: { + std::cerr << "DIV: r" << (int)operands[0] << " = r" << (int)operands[1] << " / r" << (int)operands[2]; + break; + } + case MOD: { + std::cerr << "MOD: r" << (int)operands[0] << " = r" << (int)operands[1] << " % r" << (int)operands[2]; + break; + } + case POW: { + std::cerr << "POW: r" << (int)operands[0] << " = pow(r" << (int)operands[1] << ", r" << (int)operands[2] << ")"; + break; + } + case FCALL: { + std::cerr << "FCALL: func=0x" << std::hex << *reinterpret_cast(operands) << std::dec << ", args=" << (int)operands[8]; + break; + } + case FRET: { + std::cerr << "FRET: Return from function"; + break; + } + case HALT: { + std::cerr << "HALT: Terminate execution"; + break; + } + case DEBUG_LOG: { + std::cerr << "DEBUG_LOG: const[" << *reinterpret_cast(operands) << "]"; + break; + } + case JMP: { + std::cerr << "JMP: to " << *reinterpret_cast(operands); + break; + } + case CMP_GE: { + std::cerr << "CMP_GE: r" << (int)operands[0] << " = r" << (int)operands[1] << " >= r" << (int)operands[2]; + break; + } + case CMP_LT: { + std::cerr << "CMP_LT: r" << (int)operands[0] << " = r" << (int)operands[1] << " < r" << (int)operands[2]; + break; + } + case CMP_LE: { + std::cerr << "CMP_LE: r" << (int)operands[0] << " = r" << (int)operands[1] << " <= r" << (int)operands[2]; + break; + } + case CMP_GT: { + std::cerr << "CMP_GT: r" << (int)operands[0] << " = r" << (int)operands[1] << " > r" << (int)operands[2]; + break; + } + case CMP_EQ: { + std::cerr << "CMP_EQ: r" << (int)operands[0] << " = r" << (int)operands[1] << " == r" << (int)operands[2]; + break; + } + case CMP_NE: { + std::cerr << "CMP_NE: r" << (int)operands[0] << " = r" << (int)operands[1] << " != r" << (int)operands[2]; + break; + } + case IF_TRUE: { + std::cerr << "IF_TRUE: r" << (int)operands[0] << " ? to " << *reinterpret_cast(operands + 1); + break; + } + case IF_FALSE: { + std::cerr << "IF_FALSE: r" << (int)operands[0] << " ? to " << *reinterpret_cast(operands + 1); + break; + } + case FUNC_CREATE: { + std::cerr << "FUNC_CREATE: Function definition"; + break; + } + case FUNC_END: { + std::cerr << "FUNC_END: Function end"; + break; + } + case LOCAL_GET: { + std::cerr << "LOCAL_GET: r" << (int)operands[0] << " = frame[" << (int)operands[1] << "]->locals[" << *(uint16_t*)(operands + 2) << "]"; + break; + } + case LOCAL_SET: { + std::cerr << "LOCAL_SET: frame[" << (int)operands[0] << "]->locals[" << *(uint16_t*)(operands + 1) << "] = r" << (int)operands[3]; + break; + } + case AND: { + std::cerr << "AND: r" << (int)operands[0] << " = r" << (int)operands[1] << " && r" << (int)operands[2]; + break; + } + case OR: { + std::cerr << "OR: r" << (int)operands[0] << " = r" << (int)operands[1] << " || r" << (int)operands[2]; + break; + } + case VMC: { + std::cerr << "VMC: Call vmcall[" << *(uint16_t*)operands << "]"; + break; + } + case DEC: { + std::cerr << "DEC: r" << (int)operands[0] << "--"; + break; + } + case PUSH: { + std::cerr << "PUSH: r" << (int)operands[0]; + break; + } + case CREATE_VECTOR: { + std::cerr << "CREATE_VECTOR: r" << (int)operands[0] << ", " << (int)operands[1]; + break; + } + default: { + std::cerr << "Unknown opcode: " << (int)op; + break; + } + } + std::cerr << COLOR_RESET << std::endl; + + // 执行指令 + switch (op) { + using enum Opcode; + case MOV_RI: { + if (!is_valid_register(operands[0])) { + handle_error("Invalid register index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + const uint8_t dst_reg = operands[0]; + const int64_t imm_val = *reinterpret_cast(operands + 1); + ste.regs[dst_reg] = imm_val; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move immediate value " << imm_val << " to register r" << (int)dst_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to " << imm_val << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVRI instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case MOV_RM: { + if (!is_valid_register(operands[0])) { + handle_error("Invalid register index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + const uint8_t dst_reg = operands[0]; + const uint64_t mem_addr = operands[1]; + if (mem_addr == 0) { + handle_error("Null memory address in MOV_RM"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + ste.regs[dst_reg] = *reinterpret_cast(mem_addr); + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from memory address 0x" << std::hex << mem_addr << std::dec << " to register r" << (int)dst_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to " << ste.regs[dst_reg].i64 << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVRM instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case MOV_RR: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1])) { + handle_error("Invalid register index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + const uint8_t dst_reg = operands[0]; + const uint8_t src_reg = operands[1]; + ste.regs[dst_reg] = ste.regs[src_reg]; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from register r" << (int)src_reg << " to register r" << (int)dst_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to " << ste.regs[dst_reg].i64 << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVRR instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case MOV_RC: { + if (!is_valid_register(operands[0])) { + handle_error("Invalid register index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + if (const_pool_top == nullptr) { + handle_error("Constant pool is null"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + const uint8_t dst_reg = operands[0]; + const uint64_t const_idx = *(uint64_t*)(operands + 1); + ste.regs[dst_reg] = (char*)get_constant() + const_idx; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from constant pool at index " << const_idx << " to register r" << (int)dst_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to constant[" << const_idx << "]" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVRC instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case MOV_MI: { + const uint64_t mem_addr = operands[0]; + const int64_t imm_val = *reinterpret_cast(operands + 1); + ste.heap[mem_addr] = imm_val; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move immediate value " << imm_val << " to memory address 0x" << std::hex << mem_addr << std::dec << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Memory at 0x" << std::hex << mem_addr << std::dec << " set to " << imm_val << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVMI instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case MOV_MM: { + const uint64_t dst_addr = operands[0]; + const uint64_t src_addr = operands[1]; + ste.heap[dst_addr] = ste.heap[src_addr]; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from memory address 0x" << std::hex << src_addr << std::dec << " to memory address 0x" << std::hex << dst_addr << std::dec << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Memory at 0x" << std::hex << dst_addr << std::dec << " set to value from 0x" << std::hex << src_addr << std::dec << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVMM instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case MOV_MR: { + if (!is_valid_register(operands[1])) { + handle_error("Invalid register index"); + return 1; + } + const uint64_t mem_addr = operands[0]; + const uint8_t src_reg = operands[1]; + ste.heap[mem_addr] = ste.regs[src_reg]; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from register r" << (int)src_reg << " to memory address 0x" << std::hex << mem_addr << std::dec << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Memory at 0x" << std::hex << mem_addr << std::dec << " set to value from r" << (int)src_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVMR instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case MOV_MC: { + if (const_pool_top == nullptr) { + handle_error("Constant pool is null"); + return 1; + } + const uint64_t mem_addr = operands[0]; + const uint64_t const_idx = operands[1]; + ste.heap[mem_addr] = (char*)get_constant() + const_idx; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from constant pool at index " << const_idx << " to memory address 0x" << std::hex << mem_addr << std::dec << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Memory at 0x" << std::hex << mem_addr << std::dec << " set to constant[" << const_idx << "]" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVMC instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case ADD: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t add_dst_reg = operands[0]; + const uint8_t add_src1_reg = operands[1]; + const uint8_t add_src2_reg = operands[2]; + + // 类型检查 + const ValueType::ValueType type1 = ste.regs[add_src1_reg].type; + const ValueType::ValueType type2 = ste.regs[add_src2_reg].type; + DEBUG_LOG("type1: " << type1 << ", type2: " << type2); + + // 禁止向量与数字相加 + if ((type1 == ValueType::Ptr && type2 == ValueType::Int) || + (type1 == ValueType::Int && type2 == ValueType::Ptr)) { + handle_error("Cannot add vector and number"); + return 1; + } + + // 只允许相同类型的加法 + if (type1 != type2) { + handle_error("Cannot add different types"); + return 1; + } + + // 处理不同类型的加法 + if (type1 == ValueType::Int) { + const int64_t add_result = ste.regs[add_src1_reg].i64 + ste.regs[add_src2_reg].i64; + ste.regs[add_dst_reg] = add_result; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Add registers r" << (int)add_src1_reg << " + r" << (int)add_src2_reg << " = " << add_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)add_dst_reg << " value set to " << add_result << std::endl; + } else if (type1 == ValueType::Ptr) { + DEBUG_LOG("Adding ptr..."); + // 向量加法:对应元素相加 + const size_t vec1_addr = ste.regs[add_src1_reg].u64; + const size_t vec2_addr = ste.regs[add_src2_reg].u64; + + // 检查向量长度是否相同 + const size_t vec1_len = ste.heap[vec1_addr].i64; + const size_t vec2_len = ste.heap[vec2_addr].i64; + + if (vec1_len != vec2_len) { + handle_error("Vectors must have the same length for addition"); + return 1; + } + + // 分配新向量 + const size_t vec_result_addr = ste.heap.size(); + ste.heap.resize(vec_result_addr + 1 + vec1_len); + + // 存储长度 + ste.heap[vec_result_addr].type = ValueType::Int; + ste.heap[vec_result_addr].i64 = vec1_len; + + // 对应元素相加 + for (size_t i = 0; i < vec1_len; i++) { + const Value& elem1 = ste.heap[vec1_addr + 1 + i]; + const Value& elem2 = ste.heap[vec2_addr + 1 + i]; + + // 确保元素类型相同 + if (elem1.type != elem2.type) { + handle_error("Vector elements must have the same type for addition"); + return 1; + } + + // 执行元素加法 + Value result_elem; + if (elem1.type == ValueType::Int) { + result_elem = elem1.i64 + elem2.i64; + } else { + handle_error("Unsupported vector element type for addition"); + return 1; + } + + ste.heap[vec_result_addr + 1 + i] = result_elem; + } + + // 设置结果 + ste.regs[add_dst_reg].type = ValueType::Ptr; + ste.regs[add_dst_reg].u64 = vec_result_addr; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Add vectors r" << (int)add_src1_reg << " + r" << (int)add_src2_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)add_dst_reg << " value set to vector of length " << vec1_len << std::endl; + } else { + handle_error("Unsupported type for addition"); + return 1; + } + + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed ADD instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case SUB: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t sub_dst_reg = operands[0]; + const uint8_t sub_src1_reg = operands[1]; + const uint8_t sub_src2_reg = operands[2]; + const int64_t sub_result = ste.regs[sub_src1_reg].i64 - ste.regs[sub_src2_reg].i64; + ste.regs[sub_dst_reg] = sub_result; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Subtract registers r" << (int)sub_src1_reg << " - r" << (int)sub_src2_reg << " = " << sub_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)sub_dst_reg << " value set to " << sub_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed SUB instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case MUL: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t mul_dst_reg = operands[0]; + const uint8_t mul_src1_reg = operands[1]; + const uint8_t mul_src2_reg = operands[2]; + const int64_t mul_result = ste.regs[mul_src1_reg].i64 * ste.regs[mul_src2_reg].i64; + ste.regs[mul_dst_reg] = mul_result; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Multiply registers r" << (int)mul_src1_reg << " * r" << (int)mul_src2_reg << " = " << mul_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)mul_dst_reg << " value set to " << mul_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MUL instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case DIV: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t div_dst_reg = operands[0]; + const uint8_t div_src1_reg = operands[1]; + const uint8_t div_src2_reg = operands[2]; + if (ste.regs[div_src2_reg].i64 == 0) { + handle_error("Division by zero"); + return 1; + } + const int64_t div_result = ste.regs[div_src1_reg].i64 / ste.regs[div_src2_reg].i64; + ste.regs[div_dst_reg] = div_result; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Divide registers r" << (int)div_src1_reg << " / r" << (int)div_src2_reg << " = " << div_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)div_dst_reg << " value set to " << div_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed DIV instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case MOD: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t mod_dst_reg = operands[0]; + const uint8_t mod_src1_reg = operands[1]; + const uint8_t mod_src2_reg = operands[2]; + if (ste.regs[mod_src2_reg].i64 == 0) { + handle_error("Modulo by zero"); + return 1; + } + const int64_t mod_result = ste.regs[mod_src1_reg].i64 % ste.regs[mod_src2_reg].i64; + ste.regs[mod_dst_reg] = mod_result; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Modulo registers r" << (int)mod_src1_reg << " % r" << (int)mod_src2_reg << " = " << mod_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)mod_dst_reg << " value set to " << mod_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOD instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case POW: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t pow_dst_reg = operands[0]; + const uint8_t pow_src1_reg = operands[1]; + const uint8_t pow_src2_reg = operands[2]; + const double pow_result = std::pow(ste.regs[pow_src1_reg].f64, ste.regs[pow_src2_reg].f64); + ste.regs[pow_dst_reg] = pow_result; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Power registers r" << (int)pow_src1_reg << " ^ r" << (int)pow_src2_reg << " = " << pow_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)pow_dst_reg << " value set to " << pow_result << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed POW instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case FCALL: { + uint64_t target_pc = *reinterpret_cast(operands); + if (target_pc >= ste.program->size()) { + handle_error("Invalid jump address"); + return 1; + } + const auto args_count = operands[8]; // 传参数量 + ste.ret_addr_stack.push_back(ste.pc + 1); // 返回地址 + ste.pc = target_pc; // 跳转地址 + ste.stack_frames.push_back(std::make_unique()); //新建栈帧 + ste.stack_frames.back()->locals.resize(args_count + 1); + for (uint8_t i = 0; i != args_count; i++) { + if (REG_COUNT_INDEX_MAX - i >= REG_COUNT) { + handle_error("Invalid register index"); + return 1; + } + ste.stack_frames.back()->locals[i] = ste.regs[REG_COUNT_INDEX_MAX - i]; + } + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Call function at address " << target_pc << " with " << (int)args_count << " arguments" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: PC set to " << target_pc << ", return address pushed to stack, new stack frame created" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed FCALL instruction, jumping to function address" << COLOR_RESET << std::endl; + break; + } + case FRET: { + if (ste.ret_addr_stack.empty() || ste.stack_frames.size() <= 1) { + handle_error("Invalid return operation"); + return 1; + } + const size_t return_addr = ste.ret_addr_stack.back(); + ste.pc = return_addr; //返回地址 + ste.ret_addr_stack.pop_back(); + ste.stack_frames.pop_back(); // 恢复栈帧 + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Return from function" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: PC set to return address " << return_addr << ", stack frame popped" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed FRET instruction, returning to caller" << COLOR_RESET << std::endl; + break; + } + case HALT: { + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Terminate VM execution" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: VM execution terminated normally" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed HALT instruction, VM stopped running" << COLOR_RESET << std::endl; + DEBUG_SEPARATOR("VM EXECUTION END (SUCCESS)"); + DEBUG_LEAVE_FUNC(); + return 0; + } + case DEBUG_LOG: { + if (const_pool_top == nullptr) { + handle_error("Constant pool is null"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + fprintf(stderr,"[LogInfo]: %s\n", static_cast(const_pool_top) + *reinterpret_cast(operands)); + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Print debug log" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Log printed to console" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed DEBUG_LOG instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case JMP: { + uint64_t target_pc = *reinterpret_cast(operands); + if (target_pc >= ste.program->size()) { + handle_error("Invalid jump address"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + ste.pc = target_pc; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Jump to address " << target_pc << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Program counter set to " << target_pc << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed JMP instruction, PC set to target address, continuing execution" << COLOR_RESET << std::endl; + break; + } + case CMP_GE: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + const uint8_t dst_reg = operands[0]; + const uint8_t src1_reg = operands[1]; + const uint8_t src2_reg = operands[2]; + bool result = ste.regs[src1_reg].i64 >= ste.regs[src2_reg].i64; + ste.regs[dst_reg].b = result; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Compare registers r" << (int)src1_reg << " >= r" << (int)src2_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " set to " << (result ? "true" : "false") << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed CMP_GE instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case CMP_LT: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t cmp_dst_reg = operands[0]; + const uint8_t cmp_src1_reg = operands[1]; + const uint8_t cmp_src2_reg = operands[2]; + bool cmp_result = ste.regs[cmp_src1_reg].i64 < ste.regs[cmp_src2_reg].i64; + ste.regs[cmp_dst_reg].b = cmp_result; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Compare registers r" << (int)cmp_src1_reg << " < r" << (int)cmp_src2_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)cmp_dst_reg << " set to " << (cmp_result ? "true" : "false") << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed CMP_LT instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case CMP_LE: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t cmp_dst_reg = operands[0]; + const uint8_t cmp_src1_reg = operands[1]; + const uint8_t cmp_src2_reg = operands[2]; + bool cmp_result = ste.regs[cmp_src1_reg].i64 <= ste.regs[cmp_src2_reg].i64; + ste.regs[cmp_dst_reg].b = cmp_result; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Compare registers r" << (int)cmp_src1_reg << " <= r" << (int)cmp_src2_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)cmp_dst_reg << " set to " << (cmp_result ? "true" : "false") << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed CMP_LE instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case CMP_GT: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + ste.regs[operands[0]].b = ste.regs[operands[1]].i64 > ste.regs[operands[2]].i64; + ste.pc++; + break; + } + case CMP_EQ: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + ste.regs[operands[0]].b = ste.regs[operands[1]].i64 == ste.regs[operands[2]].i64; + ste.pc++; + break; + } + case CMP_NE: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + ste.regs[operands[0]].b = ste.regs[operands[1]].i64 != ste.regs[operands[2]].i64; + ste.pc++; + break; + } + case IF_TRUE: { + if (!is_valid_register(operands[0])) { + handle_error("Invalid register index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + uint64_t target_pc = *reinterpret_cast(operands + 1); + if (target_pc >= ste.program->size()) { + handle_error("Invalid jump address"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + const uint8_t cond_reg = operands[0]; + bool condition = ste.regs[cond_reg].b; + if (condition) { + ste.pc = target_pc; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Jump to address " << target_pc << " if condition is true" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Condition is true, PC set to " << target_pc << std::endl; + } else { + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Jump to address " << target_pc << " if condition is true" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Condition is false, PC increased by 1" << std::endl; + } + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed IF_TRUE instruction, " << (condition ? "jumping to target address" : "continuing to next instruction") << COLOR_RESET << std::endl; + break; + } + case IF_FALSE: { + if (!is_valid_register(operands[0])) { + handle_error("Invalid register index"); + return 1; + } + uint64_t target_pc = *reinterpret_cast(operands + 1); + if (target_pc >= ste.program->size()) { + handle_error("Invalid jump address"); + return 1; + } + if (!ste.regs[operands[0]].b) ste.pc = target_pc; + else ste.pc++; + break; + } + case FUNC_CREATE: { + while (ste.pc < ste.program->size() && ste.program->operator[](ste.pc).op != FUNC_END) { + ste.pc++; + } + if (ste.pc < ste.program->size()) { + ste.pc++; + } + break; + } + case FUNC_END: { + ste.pc++; + break; + } + case LOCAL_GET: { + if (!is_valid_register(operands[0])) { + handle_error("Invalid register index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + if (operands[1] >= ste.stack_frames.size()) { + handle_error("Invalid stack frame index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + uint16_t local_index = *(uint16_t*)(operands + 2); + if (local_index >= ste.stack_frames[operands[1]]->locals.size()) { + handle_error("Invalid local variable index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + const uint8_t dst_reg = operands[0]; + const uint8_t frame_idx = operands[1]; + ste.regs[dst_reg] = ste.stack_frames[frame_idx]->locals[local_index]; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Load local variable " << local_index << " from frame " << (int)frame_idx << " to register r" << (int)dst_reg << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to " << ste.regs[dst_reg].i64 << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed LOCAL_GET instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case LOCAL_SET: { + if (!is_valid_register(operands[3])) { + handle_error("Invalid register index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + if (operands[0] >= ste.stack_frames.size()) { + handle_error("Invalid stack frame index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + uint16_t local_index = *(uint16_t*)(operands + 1); + if (local_index >= ste.stack_frames[operands[0]]->locals.size()) { + handle_error("Invalid local variable index"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + const uint8_t frame_idx = operands[0]; + const uint8_t src_reg = operands[3]; + ste.stack_frames[frame_idx]->locals[local_index] = ste.regs[src_reg]; + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Store register r" << (int)src_reg << " value to local variable " << local_index << " in frame " << (int)frame_idx << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: frame[" << (int)frame_idx << "]->locals[" << local_index << "] = " << ste.regs[src_reg].i64 << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_REGS(ste.regs); + std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed LOCAL_SET instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + break; + } + case AND: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + ste.regs[operands[0]].b = ste.regs[operands[1]].b && ste.regs[operands[2]].b; + ste.pc++; + break; + } + case OR: { + if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { + handle_error("Invalid register index"); + return 1; + } + ste.regs[operands[0]].b = ste.regs[operands[1]].b || ste.regs[operands[2]].b; + ste.pc++; + break; + } + case VMC: { + uint16_t vmcall_index = *(uint16_t*)operands; + if (vmcall_index >= VMCall::vmcall_count) { + handle_error("Invalid VMCall index"); + return 1; + } + VMCall::vmcall_table[vmcall_index](this); + ste.pc++; + break; + } + case DEC: { + if (!is_valid_register(operands[0])) { + handle_error("Invalid register index"); + return 1; + } + ste.regs[operands[0]].i64--; + ste.pc++; + break; + } + case PUSH: { + if (!is_valid_register(operands[0])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t src_reg = operands[0]; + ste.stack.push_back(ste.regs[src_reg]); + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Push register r" << (int)src_reg << " to stack" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Stack size: " << ste.stack.size() << std::endl; + break; + } + case CREATE_VECTOR: { + if (!is_valid_register(operands[0])) { + handle_error("Invalid register index"); + return 1; + } + const uint8_t dst_reg = operands[0]; + const uint8_t count = operands[1]; + + // 检查栈中是否有足够的元素 + if (ste.stack.size() < count) { + handle_error("Not enough elements on stack for CREATE_VECTOR"); + return 1; + } + + // 1. 计算需要的堆空间: 1个长度 + count个元素 + size_t slots = 1 + count; + + // 2. 在堆上分配内存 + size_t vec_addr = ste.heap.size(); + for (size_t i = 0; i < slots; i++) { + Value value; + value.type = ValueType::Null; + value.null = nullptr; + ste.heap.push_back(value); + } + + // 3. 存长度到第一个槽位 + ste.heap[vec_addr].type = ValueType::Int; + ste.heap[vec_addr].i64 = count; + + // 4. 从栈顶取元素(从最后压入的到最先压入的) + for (size_t i = 0; i < count; i++) { + // 从栈中取元素(栈顶是最后压入的元素) + ste.heap[vec_addr + 1 + i] = ste.stack[ste.stack.size() - count + i]; + } + + // 5. 调整栈(弹出元素) + for (size_t i = 0; i < count; i++) { + ste.stack.pop_back(); + } + + // 6. 返回向量地址到目标寄存器 + ste.regs[dst_reg].type = ValueType::Ptr; + ste.regs[dst_reg].u64 = vec_addr; + + ste.pc++; + std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Create vector with " << (int)count << " elements" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Result: Vector at heap[" << vec_addr << "]" << std::endl; + std::cerr << COLOR_YELLOW << "[EXEC] | Stack size after: " << ste.stack.size() << std::endl; + break; + } + default: + ste.pc++; + break; + } } + DEBUG_LOG("PC out of bounds"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + DEBUG_LEAVE_FUNC(); return 1; } diff --git a/runtime/vm.hpp b/runtime/vm.hpp index e5ddbba..6cf5e36 100644 --- a/runtime/vm.hpp +++ b/runtime/vm.hpp @@ -17,53 +17,95 @@ namespace lmx::runtime { +// VM执行状态 struct LMVM_API LMXState { - size_t pc{0}; - std::array regs{}; + size_t pc{0}; // 程序计数器 + std::array regs{}; // 寄存器数组 + std::vector heap{}; + std::vector ret_addr_stack; // 返回地址栈 + std::vector* program{}; // 程序指令 + std::vector> stack_frames; // 栈帧 + std::vector stack; // 操作数栈 - std::vector ret_addr_stack; - //void* const_pool_top; - std::vector* program{}; - - std::vector> cur; LMXState() = default; - // 2. 删除拷贝构造函数和拷贝赋值运算符 LMXState(const LMXState&) = delete; LMXState& operator=(const LMXState&) = delete; - - // 3. 允许移动构造函数和移动赋值运算符 LMXState(LMXState&&) = delete; LMXState& operator=(LMXState&&) = delete; - LMXState(LMXState&); - // 4. 析构函数 ~LMXState() = default; }; -class LMVM_API VirtualCore { - void* const_pool_top; - LMXState ste; +// 虚拟机核心类 +class LMVM_API VirtualCore { + void* const_pool_top; // 常量池顶部指针 + LMXState ste; // VM执行状态 - [[nodiscard]] Value *get_value_from_pool(size_t offest) const; + // 从常量池获取值 + [[nodiscard]] Value* get_value_from_pool(size_t offest) const; + + // 检查寄存器索引是否有效 + [[nodiscard]] bool is_valid_register(uint8_t reg) const; + + // 统一错误处理函数 + void handle_error(const char* error_message) const; + + // 验证多个寄存器索引 + [[nodiscard]] bool validate_registers(const uint8_t* regs, size_t count) const; + + // 验证跳转地址 + [[nodiscard]] bool validate_jump_address(uint64_t address) const; + + // 验证栈帧和局部变量索引 + [[nodiscard]] bool validate_stack_frame(size_t frame_index, size_t local_index) const; + + // 从常量池获取字符串 + [[nodiscard]] const char* get_constant_string(uint64_t offset) const; public: - std::vector> libs; + std::vector> libs; // 加载的动态库 + VirtualCore(); + ~VirtualCore(); + + // 禁止拷贝和移动 VirtualCore(const VirtualCore&) = delete; VirtualCore& operator=(const VirtualCore&) = delete; VirtualCore(VirtualCore&&) = delete; + + // 带状态的构造函数 explicit VirtualCore(LMXState ste); + + // 带状态和常量池的构造函数 explicit VirtualCore(LMXState ste, void* const_pool_top); + + // 运行VM int run(); - [[nodiscard]] std::vector *get_program() const { return ste.program; } - void set_program(std::vector *program) { ste.pc = 0;ste.program = program; } + // 获取程序指令 + [[nodiscard]] std::vector* get_program() const { return ste.program; } + + // 设置程序指令 + void set_program(std::vector* program) { ste.pc = 0; ste.program = program; } + + // 查看寄存器值 [[nodiscard]] int64_t look_register(const size_t r) const { return ste.regs[r].i64; } + // 获取寄存器引用 [[nodiscard]] Value& get_register(const size_t r) { return ste.regs[r]; } + // 获取常量池指针 [[nodiscard]] void* get_constant() const { return const_pool_top; } + + // 设置常量池指针 void set_constant(void* const_pool) { const_pool_top = const_pool; } + // 设置寄存器指针值 void set_reg_ptr(const size_t idx, void* np) { ste.regs[idx].ptr = np; } + + // 堆内存管理方法 + size_t heap_size() const { return ste.heap.size(); } + Value& heap_at(size_t index) { return ste.heap[index]; } + const Value& heap_at(size_t index) const { return ste.heap[index]; } + void heap_push_back(const Value& value) { ste.heap.push_back(value); } }; } diff --git a/runtime/vmcall.cpp b/runtime/vmcall.cpp index deebafe..681129d 100644 --- a/runtime/vmcall.cpp +++ b/runtime/vmcall.cpp @@ -1,5 +1,8 @@ #include "vmcall.hpp" +#include "vm.hpp" #include + +#include "debug.hpp" #include "libloader.hpp" #include "../compiler/generator/generator.hpp" @@ -69,3 +72,61 @@ VMC_REGISTER(dyn_call) { ); } +/* + * VMC_alloc_memory(6) + * arg1 : size(0) + * + * return: memory_ptr in r0 + */ +// VMC 6: 分配内存 +VMC_REGISTER(alloc_memory) { + size_t slots = self->get_register(0).u64; + + size_t memory_start = self->heap_size(); + + // 分配 slots 个 Value,初始化为 Null + for (size_t i = 0; i < slots; i++) { + Value value; + value.type = ValueType::Null; + value.null = nullptr; + self->heap_push_back(value); + } + + // 返回起始索引(指针) + Value memory_ptr; + memory_ptr.type = ValueType::Ptr; + memory_ptr.u64 = memory_start; // 存的是堆索引 + self->get_register(0) = memory_ptr; + + DEBUG_LOG("VMC[6]: allocated " << slots << " slots at heap[" << memory_start << "]"); +} + +/* + * VMC_store_memory(7) + * arg1 : memory_ptr(0) + * arg2 : offset(1) + * arg3 : value(2) + * + * 存储值到指定内存地址 + */ +VMC_REGISTER(store_memory) { + size_t memory_ptr = self->get_register(0).u64; + size_t offset = self->get_register(1).u64; + Value value = self->get_register(2); + + // 检查内存指针是否有效 + if (memory_ptr >= self->heap_size()) { + // 无效的内存指针 + return; + } + + // 检查偏移量是否有效 + if (memory_ptr + offset >= self->heap_size()) { + // 无效的偏移量 + return; + } + + // 存储值 + self->heap_at(memory_ptr + offset) = value; +} + diff --git a/tools/lm/common/repl.cpp b/tools/lm/common/repl.cpp index b478140..427f205 100644 --- a/tools/lm/common/repl.cpp +++ b/tools/lm/common/repl.cpp @@ -1,54 +1,264 @@ -#include "repl.hpp" -#include "../compiler/lexer.hpp" -#include "../compiler/parser.hpp" -#include "../compiler/generator/generator.hpp" -#include "../compiler/generator/emit.hpp" -#include "../runtime/vm.hpp" -#include "../compiler/ast.hpp" -#include - -int run_repl() { - std::string expr; - lmx::Lexer l(expr); - lmx::Generator gener; - lmx::runtime::VirtualCore core; - core.set_program(&gener.ops); - - std::string prompt = ">>>"; - while (true) { - std::cout << std::flush << prompt << std::flush; - if (!std::getline(std::cin, expr)) break; - //switch (ss.view().back()) { - // case '+': case '-': case '*': case '/': case '=': case '!': case '~': case '{' :case '[': prompt = "..."; continue; - // default: break; - //} - if (expr == ":lastret") std::cout << core.look_register(0) << std::endl; - else if (expr == ":exit") break; - else if (expr == ":op") gener.print_ops(); - else if (expr == ":vars") gener.print_vars(); - else { - std::vector tks = l.tokenize(expr); - lmx::Parser parser(tks); - auto node = parser.parse(); - if (!node || parser.error()) continue; - const auto op = gener.gen(node); - if (lmx::Generator::node_has_error) continue; - gener.ops.emplace_back(lmx::runtime::Opcode::HALT); - //gener.print_ops(); - //continue; - core.set_constant(gener.constant_pool.data()); - //const auto start = std::chrono::high_resolution_clock::now(); - core.run(); - //const auto end = std::chrono::high_resolution_clock::now(); - - if (op != -1) { - gener.regs.free(op); - std::cout << "Result: " << core.look_register(op) << std::endl; - } - //std::cout << "time " << std::chrono::duration_cast(end - start) << std::endl; - if (gener.ops.back().op == lmx::runtime::Opcode::HALT) gener.ops.pop_back(); - } - } - return 0; - -} +#include "repl.hpp" +#include "../compiler/lexer.hpp" +#include "../compiler/parser.hpp" +#include "../compiler/generator/generator.hpp" +#include "../compiler/generator/emit.hpp" +#include "../runtime/vm.hpp" +#include "../compiler/ast.hpp" +#include "../../../include/debug.hpp" + +// Function to print AST nodes +void print_ast(const std::shared_ptr& node, int indent = 0) { + if (!node) return; + + // Print indentation + for (int i = 0; i < indent; i++) { + std::cerr << " "; + } + + // Print node type and information based on kind + switch (node->kind) { + case lmx::ASTKind::Program: + std::cerr << "Program" << std::endl; + for (const auto& child : dynamic_cast(node.get())->children) { + print_ast(child, indent + 1); + } + break; + case lmx::ASTKind::NumLiteral: + std::cerr << "NumLiteral(" << dynamic_cast(node.get())->num << ")" << std::endl; + break; + case lmx::ASTKind::StringLiteral: + std::cerr << "StringLiteral(\"" << dynamic_cast(node.get())->str << "\")" << std::endl; + break; + case lmx::ASTKind::BoolLiteral: + std::cerr << "BoolLiteral(" << (dynamic_cast(node.get())->b ? "true" : "false") << ")" << std::endl; + break; + case lmx::ASTKind::VectorLiteral: { + const auto elem_vec = (dynamic_cast(node.get())->elements); + std::cerr << "VectorLiteral(" << std::endl; + for (auto const& k : elem_vec) { + print_ast(k, indent + 1); + } + std::cerr << ")" << std::endl; + break; + } + case lmx::ASTKind::VarDecl: + { + auto decl = dynamic_cast(node.get()); + std::cerr << "VarDecl(" << decl->name << ", mutable=" << (decl->is_mut ? "true" : "false") << ")" << std::endl; + if (decl->value) { + print_ast(decl->value, indent + 1); + } + } + break; + case lmx::ASTKind::VarRef: + std::cerr << "VarRef(" << dynamic_cast(node.get())->name << ")" << std::endl; + break; + case lmx::ASTKind::FuncDecl: + { + auto func = dynamic_cast(node.get()); + std::cerr << "FuncDecl(" << func->name << ")" << std::endl; + if (func->body) { + print_ast(func->body, indent + 1); + } + } + break; + case lmx::ASTKind::FuncCallExpr: + { + auto call = dynamic_cast(node.get()); + std::cerr << "FuncCallExpr(" << call->name << ")" << std::endl; + for (const auto& arg : call->args) { + print_ast(arg, indent + 1); + } + } + break; + case lmx::ASTKind::Binary: + { + auto bin = dynamic_cast(node.get()); + std::cerr << "Binary(" << bin->op << ")" << std::endl; + print_ast(bin->left, indent + 1); + print_ast(bin->right, indent + 1); + } + break; + case lmx::ASTKind::Unary: + { + auto unary = dynamic_cast(node.get()); + std::cerr << "Unary(" << unary->op << ")" << std::endl; + print_ast(unary->operand, indent + 1); + } + break; + case lmx::ASTKind::BlockStmt: + { + std::cerr << "BlockStmt" << std::endl; + for (const auto& child : dynamic_cast(node.get())->children) { + print_ast(child, indent + 1); + } + } + break; + case lmx::ASTKind::IfStmt: + { + auto if_stmt = dynamic_cast(node.get()); + std::cerr << "IfStmt" << std::endl; + std::cerr << " Condition:" << std::endl; + print_ast(if_stmt->condition, indent + 2); + std::cerr << " Then:" << std::endl; + print_ast(if_stmt->thenBlock, indent + 2); + if (if_stmt->elseBlock) { + std::cerr << " Else:" << std::endl; + print_ast(if_stmt->elseBlock, indent + 2); + } + } + break; + case lmx::ASTKind::Return: + { + auto ret = dynamic_cast(node.get()); + std::cerr << "Return" << std::endl; + if (ret->expr) { + print_ast(ret->expr, indent + 1); + } + } + break; + case lmx::ASTKind::VMCall: + { + auto vmcall = dynamic_cast(node.get()); + std::cerr << "VMCall(" << vmcall->idx << ")" << std::endl; + for (const auto& arg : vmcall->args) { + print_ast(arg, indent + 1); + } + } + break; + case lmx::ASTKind::Module: + { + auto module = dynamic_cast(node.get()); + std::cerr << "Module(" << module->name << ")" << std::endl; + // Print children if needed + } + break; + case lmx::ASTKind::Use: + { + auto use = dynamic_cast(node.get()); + std::cerr << "Use(" << use->path->str << ")" << std::endl; + } + break; + case lmx::ASTKind::Loop: + { + auto loop = dynamic_cast(node.get()); + std::cerr << "Loop" << std::endl; + std::cerr << " Condition:" << std::endl; + print_ast(loop->condition, indent + 2); + std::cerr << " Body:" << std::endl; + print_ast(loop->body, indent + 2); + } + break; + case lmx::ASTKind::Break: + std::cerr << "Break" << std::endl; + break; + case lmx::ASTKind::Continue: + std::cerr << "Continue" << std::endl; + break; + default: + std::cerr << "Unknown AST node type" << std::endl; + break; + } +} + +int run_repl() { + std::string expr; + lmx::Lexer l(expr); + lmx::Generator gener; + lmx::runtime::VirtualCore core; + core.set_program(&gener.ops); + + const std::string prompt = ">>> "; + while (true) { + std::cout << prompt << std::flush; + if (!std::getline(std::cin, expr)) break; + if (expr == ":lastret") std::cout << core.look_register(0) << std::endl; + else if (expr == ":exit") break; + else if (expr == ":op") gener.print_ops(); + else if (expr == ":vars") gener.print_vars(); + else { + // Reset error flag before processing each input + lmx::Generator::node_has_error = false; + + // Tokenize and display tokens + std::vector tks = l.tokenize(expr); + DEBUG_TOKEN_LIST(tks); + + // Parse and display AST + lmx::Parser parser(tks); + auto node = parser.parse(); + if (!node || parser.error()) continue; + + DEBUG_SEPARATOR("ABSTRACT SYNTAX TREE"); + std::cerr << COLOR_MAGENTA; + print_ast(node); + std::cerr << COLOR_RESET; + DEBUG_SEPARATOR("AST END"); + + // Generate bytecode and display it + const auto op = gener.gen(node); + if (lmx::Generator::node_has_error) continue; + + DEBUG_SEPARATOR("GENERATED BYTECODE"); + std::cerr << COLOR_CYAN; + gener.print_ops(); + std::cerr << COLOR_RESET; + DEBUG_SEPARATOR("BYTECODE END"); + + // Execute + gener.ops.emplace_back(lmx::runtime::Opcode::HALT); + core.set_constant(gener.constant_pool.data()); + int result = core.run(); + + if (op != -1 && result == 0) { + gener.regs.free(op); + // 检查返回值的类型 + auto& value = core.get_register(op); + if (value.type == lmx::runtime::ValueType::Null) { + // 如果是null,则不显示 + } else if (value.type == lmx::runtime::ValueType::Ptr) { + // 对于向量类型,打印向量的地址和长度 + size_t vector_ptr = value.i64; + size_t vector_size = core.heap_at(vector_ptr).i64; + std::cout << "vec["; + for (size_t i = 0; i < vector_size; i++) { + if (i > 0) std::cout << ", "; + // 根据元素类型显示 + auto& elem = core.heap_at(vector_ptr + 1 + i); + switch (elem.type) { + case lmx::runtime::ValueType::Int: + std::cout << elem.i64; + break; + case lmx::runtime::ValueType::Str: + std::cout << "\"" << elem.str << "\""; + break; + case lmx::runtime::ValueType::Bool: + std::cout << (elem.b ? "true" : "false"); + break; + case lmx::runtime::ValueType::Float: + std::cout << elem.f64; + break; + case lmx::runtime::ValueType::Ptr: + std::cout << "ptr(" << elem.u64 << ")"; + break; + case lmx::runtime::ValueType::Null: + std::cout << "null"; + break; + default: + std::cout << ""; + break; + } + } + std::cout << "]" << std::endl; + } else { + // 对于其他类型,使用默认的输出 + std::cout << core.look_register(op) << std::endl; + } + } + if (gener.ops.back().op == lmx::runtime::Opcode::HALT) gener.ops.pop_back(); + } + } + return 0; + +} From fb67de0fe98cded727fd106add9d5fbcf98a82fc Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Tue, 24 Mar 2026 21:18:56 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=B8=B8=E9=87=8F?= =?UTF-8?q?=E5=88=9D=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- compiler/CMakeLists.txt | 3 + compiler/generator/generator.cpp | 28 ++- compiler/generator/generator.hpp | 13 +- runtime/CMakeLists.txt | 3 +- runtime/builtins.cpp | 17 ++ runtime/builtins.hpp | 20 ++ runtime/libloader.cpp | 11 +- runtime/value/value.cpp | 5 +- runtime/value/value.hpp | 9 +- runtime/vm.cpp | 366 ++++++++++++++++++------------- runtime/vm.hpp | 6 +- tools/lm/common/repl.cpp | 117 +++++++--- 13 files changed, 385 insertions(+), 217 deletions(-) create mode 100644 runtime/builtins.cpp create mode 100644 runtime/builtins.hpp diff --git a/.gitignore b/.gitignore index e992330..99f56cb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,4 @@ Terminal ios-obj-log/* build/* obj/* -rm-win-r.sh -当前的MyLamina.md -当前的MyLamina_详细版.md \ No newline at end of file +rm-win-r.sh \ No newline at end of file diff --git a/compiler/CMakeLists.txt b/compiler/CMakeLists.txt index 60d533c..21b9213 100644 --- a/compiler/CMakeLists.txt +++ b/compiler/CMakeLists.txt @@ -9,3 +9,6 @@ endif() # Include common headers target_include_directories(lmc PUBLIC ${CMAKE_SOURCE_DIR}/include) + +# Link against runtime library +target_link_libraries(lmc lmvm) diff --git a/compiler/generator/generator.cpp b/compiler/generator/generator.cpp index 5d7473b..5c698e0 100644 --- a/compiler/generator/generator.cpp +++ b/compiler/generator/generator.cpp @@ -16,6 +16,7 @@ #include "opcode.hpp" #include "vmcall.hpp" #include "../common.hpp" +#include "../../runtime/builtins.hpp" namespace lmx { bool Generator::node_has_error = false; @@ -49,8 +50,26 @@ bool Allocator::is_free(size_t i) { return bitset.test(i); } +void Generator::add_builtins() const { + // 从 builtins 命名空间添加内置常量到编译帧 + size_t base_index = 64; // 从索引 64 开始 + for (size_t i = 0; i < runtime::builtins::builtin_constants_count; i++) { + const auto& constant = runtime::builtins::builtin_constants[i]; + cur.back()->new_var(constant.name, false, base_index); + base_index++; + } +} + Generator::Generator() { cur.push_back(std::make_unique("global")); + + add_builtins(); + + DEBUG_LOG("Added builtin constants to compiling frame"); + DEBUG_LOG("Builtin constants in compiling frame:"); + for (const auto& [name, info] : cur.back()->locals) { + DEBUG_LOG_FMT(" %s: index=%d, mutable=%s", name.c_str(), info.second, info.first ? "true" : "false"); + } } void Generator::write(runtime::Op& op) { ops.push_back(op); @@ -575,7 +594,7 @@ void Generator::write_binary_file(const std::string& path) { void Generator::print_ops(std::vector& ops) { size_t i = 0; for (auto &op: ops) { - printf("[0x%zx]\t", i++); // fix [0x%llx] the warning caused by + printf("[0x%zx]\t", i++); switch (op.op) { using enum runtime::Opcode; case MOV_RI: { @@ -680,11 +699,11 @@ void Generator::print_ops(std::vector& ops) { break; } case LOCAL_GET: { - printf("LOCAL_GET: %u, [%u, 0x%x]\n", op.operands[0], op.operands[1], *(uint16_t*)(op.operands + 2)); + printf("LOCAL_GET: %u, [%u, 0x%x]\n", op.operands[0], op.operands[1], *reinterpret_cast(op.operands + 2)); break; } case LOCAL_SET: { - printf("LOCAL_SET: [%u, 0x%x], %u\n", op.operands[0], *(uint16_t*)(op.operands + 1), op.operands[3]); + printf("LOCAL_SET: [%u, 0x%x], %u\n", op.operands[0], *reinterpret_cast(op.operands + 1), op.operands[3]); break; } case FUNC_CREATE: { @@ -704,12 +723,13 @@ void Generator::print_ops(std::vector& ops) { break; } case VMC: { - printf("VMC: %d\n", *(uint16_t*)op.operands); + printf("VMC: %d\n", *reinterpret_cast(op.operands)); break; } case DEC: { printf("DEC: %u\n", op.operands[0]); } + default: ; } } std::cout << std::flush; diff --git a/compiler/generator/generator.hpp b/compiler/generator/generator.hpp index 2422a8b..9178c2b 100644 --- a/compiler/generator/generator.hpp +++ b/compiler/generator/generator.hpp @@ -168,10 +168,12 @@ class LMC_API Generator { */ std::unordered_map< std::string, - std::pair > - >> extern_funcs; - static inline runtime::CBasicTypes lmtype2ctype(std::string& lmt) { + std::pair< + size_t, + std::vector> + > + > extern_funcs; + static runtime::CBasicTypes lmtype2ctype(std::string& lmt) { if (lmt.empty()) return runtime::Void; if (lmt == "bool") return runtime::CBasicTypes::Bool; if (lmt == "num") return runtime::CBasicTypes::LongLong; @@ -188,6 +190,9 @@ class LMC_API Generator { public: static bool node_has_error; Allocator regs; + + void add_builtins() const; + Generator(); ~Generator() = default; diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 300f395..4db4ca8 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -3,7 +3,8 @@ set(CMAKE_CXX_STANDARD 23) set(CMAKE_POLICY_VERSION_MINIMUM 3.5) file(GLOB_RECURSE RUNTIME_SRC *.cpp */*.cpp) -add_library(lmvm SHARED ${RUNTIME_SRC}) +add_library(lmvm SHARED ${RUNTIME_SRC} + builtins.cpp) # Define cmake-build-debug macro for DLL export if(WIN32) diff --git a/runtime/builtins.cpp b/runtime/builtins.cpp new file mode 100644 index 0000000..3775f2d --- /dev/null +++ b/runtime/builtins.cpp @@ -0,0 +1,17 @@ +#include "builtins.hpp" + +namespace lmx::runtime::builtins { + const BuiltinConstant builtin_constants[] = { + {"pi", 3.14159265358979323846}, + {"e", 2.71828182845904523536}, + {"phi", 1.61803398874989484820}, + {"gamma", 0.5772156649015328606065120900824024310421} + }; + size_t builtin_constants_count = std::size(builtin_constants); + size_t get_builtin_constant_index(const std::string& name) { + for (size_t i = 0; i < builtin_constants_count; i++) + if (builtin_constants[i].name == name) + return i + builtin_start; + return -1; + } +} \ No newline at end of file diff --git a/runtime/builtins.hpp b/runtime/builtins.hpp new file mode 100644 index 0000000..2c10c07 --- /dev/null +++ b/runtime/builtins.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "value/value.hpp" +#include "../include/lmx_export.hpp" + +namespace lmx::runtime::builtins { + +// 内置常量定义 +struct BuiltinConstant { + const char* name; + Value value; +}; + +// 内置常量数量 +inline int builtin_start = 64; +extern LMVM_API size_t builtin_constants_count; +extern LMVM_API const BuiltinConstant builtin_constants[]; + +LMVM_API size_t get_builtin_constant_index(const std::string& name); + +} // namespace lmx::runtime::builtins \ No newline at end of file diff --git a/runtime/libloader.cpp b/runtime/libloader.cpp index ea7c859..2167358 100644 --- a/runtime/libloader.cpp +++ b/runtime/libloader.cpp @@ -42,14 +42,13 @@ void DynFunc::call(VirtualCore* vm) const { switch (ret_type) { case Void: vm->get_register(0) = (void*)nullptr; dcCallVoid(caller, func); break; - case Char: vm->get_register(0) = (uint8_t)dcCallChar(caller, func); break; - case Short: vm->get_register(0) = (uint64_t)dcCallShort(caller, func); break; - case Int: vm->get_register(0) = (uint64_t)dcCallInt(caller, func); break; - case LongLong: vm->get_register(0) = (uint64_t)dcCallLongLong(caller, func); break; - case Float: vm->get_register(0) = dcCallFloat(caller, func); break; + case Char: vm->get_register(0) = static_cast(dcCallChar(caller, func)); break; + case Short: vm->get_register(0) = static_cast(dcCallShort(caller, func)); break; + case Int: vm->get_register(0) = static_cast(dcCallInt(caller, func)); break; + case LongLong: vm->get_register(0) = static_cast(dcCallLongLong(caller, func)); break; + case Bool: vm->get_register(0) = static_cast(dcCallBool(caller, func)); break; case Double: vm->get_register(0) = dcCallDouble(caller, func); break; case Ptr: vm->get_register(0) = dcCallPointer(caller, func); break; - case Bool: vm->get_register(0) = (bool)dcCallBool(caller, func); break; default: dcArgPointer(caller, vm->get_register(reg).ptr); break; diff --git a/runtime/value/value.cpp b/runtime/value/value.cpp index af591ba..4787825 100644 --- a/runtime/value/value.cpp +++ b/runtime/value/value.cpp @@ -14,7 +14,10 @@ namespace lmx::runtime { Value::Value() : null(nullptr), type(ValueType::Ptr) { } -Value::Value(void* p) : i64(*static_cast(p)), type(ValueType::Ptr) { +Value::Value(double n) : type(ValueType::Float), f64(n) { +} + +Value::Value(void* p) : type(ValueType::Ptr), i64(*static_cast(p)) { } Value& Value::operator=(void* new_ptr) { diff --git a/runtime/value/value.hpp b/runtime/value/value.hpp index 79eceb7..b117437 100644 --- a/runtime/value/value.hpp +++ b/runtime/value/value.hpp @@ -35,10 +35,11 @@ struct LMVM_API Value { void* ptr; char* str; }; - explicit Value(void* p); - Value(); - Value(const Value& other) = default; - template + explicit Value(void* p); + Value(); + Value(double n); + Value(const Value& other) = default; + template T& get(); Value &operator=(void* new_ptr); diff --git a/runtime/vm.cpp b/runtime/vm.cpp index 031091d..68c01ad 100644 --- a/runtime/vm.cpp +++ b/runtime/vm.cpp @@ -7,6 +7,7 @@ #include #include +#include "builtins.hpp" #include "value/value.hpp" #include "vmcall.hpp" #include "../compiler/generator/generator.hpp" @@ -14,20 +15,14 @@ namespace lmx::runtime { -VirtualCore::VirtualCore() : const_pool_top(nullptr), ste() { +VirtualCore::VirtualCore() : const_pool_top(nullptr) { ste.program = nullptr; ste.pc = 0; ste.stack_frames.push_back(std::make_unique()); ste.stack_frames.back()->locals.resize(64); + insert_builtins(); } -/*VirtualCore::VirtualCore(LMXState ste) : const_pool_top(nullptr), ste(std::move(ste)) {} - -VirtualCore::VirtualCore(LMXState ste, void* const_pool_top) : - const_pool_top(const_pool_top), - ste(std::move(ste)) { -}*/ - Value* VirtualCore::get_value_from_pool(const size_t offest) const { return static_cast(const_pool_top) + offest; } @@ -98,164 +93,163 @@ int VirtualCore::run() { const auto& operands = ste.program->operator[](ste.pc).operands; // 显示当前执行的字节码行 - std::cerr << COLOR_YELLOW << "[EXEC] " << ste.pc << " | " << std::flush; + DEBUG_EXEC_STEP(ste.pc, op, ""); // 根据指令类型显示详细信息 switch (op) { using enum Opcode; case MOV_RI: { - std::cerr << "MOVRI: r" << (int)operands[0] << ", " << *reinterpret_cast(operands + 1); + DEBUG_LOG_FMT("MOVRI: r%d, %lld", static_cast(operands[0]), *reinterpret_cast(operands + 1)); break; } case MOV_RM: { - std::cerr << "MOVRM: r" << (int)operands[0] << ", 0x" << std::hex << (uint64_t)operands[1] << std::dec; + DEBUG_LOG_FMT("MOVRM: r%d, 0x%llx", static_cast(operands[0]), static_cast(operands[1])); break; } case MOV_RR: { - std::cerr << "MOVRR: r" << (int)operands[0] << ", r" << (int)operands[1]; + DEBUG_LOG_FMT("MOVRR: r%d, r%d", static_cast(operands[0]), static_cast(operands[1])); break; } case MOV_RC: { - std::cerr << "MOVRC: r" << (int)operands[0] << ", const[" << *(uint64_t*)(operands + 1) << "]"; + DEBUG_LOG_FMT("MOVRC: r%d, const[%llu]", static_cast(operands[0]), *(uint64_t*)(operands + 1)); break; } case MOV_MI: { - std::cerr << "MOVMI: 0x" << std::hex << (uint64_t)operands[0] << std::dec << ", " << *reinterpret_cast(operands + 1); + DEBUG_LOG_FMT("MOVMI: 0x%llx, %lld", static_cast(operands[0]), *reinterpret_cast(operands + 1)); break; } case MOV_MM: { - std::cerr << "MOVMM: 0x" << std::hex << (uint64_t)operands[0] << ", 0x" << (uint64_t)operands[1] << std::dec; + DEBUG_LOG_FMT("MOVMM: 0x%llx, 0x%llx", static_cast(operands[0]), static_cast(operands[1])); break; } case MOV_MR: { - std::cerr << "MOVMR: 0x" << std::hex << (uint64_t)operands[0] << std::dec << ", r" << (int)operands[1]; + DEBUG_LOG_FMT("MOVMR: 0x%llx, r%d", static_cast(operands[0]), static_cast(operands[1])); break; } case MOV_MC: { - std::cerr << "MOVMC: 0x" << std::hex << (uint64_t)operands[0] << std::dec << ", const[" << (uint64_t)operands[1] << "]"; + DEBUG_LOG_FMT("MOVMC: 0x%llx, const[%llu]", static_cast(operands[0]), static_cast(operands[1])); break; } case ADD: { - std::cerr << "ADD: r" << (int)operands[0] << " = r" << (int)operands[1] << " + r" << (int)operands[2]; + DEBUG_LOG_FMT("ADD: r%d = r%d + r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case SUB: { - std::cerr << "SUB: r" << (int)operands[0] << " = r" << (int)operands[1] << " - r" << (int)operands[2]; + DEBUG_LOG_FMT("SUB: r%d = r%d - r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case MUL: { - std::cerr << "MUL: r" << (int)operands[0] << " = r" << (int)operands[1] << " * r" << (int)operands[2]; + DEBUG_LOG_FMT("MUL: r%d = r%d * r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case DIV: { - std::cerr << "DIV: r" << (int)operands[0] << " = r" << (int)operands[1] << " / r" << (int)operands[2]; + DEBUG_LOG_FMT("DIV: r%d = r%d / r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case MOD: { - std::cerr << "MOD: r" << (int)operands[0] << " = r" << (int)operands[1] << " % r" << (int)operands[2]; + DEBUG_LOG_FMT("MOD: r%d = r%d %% r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case POW: { - std::cerr << "POW: r" << (int)operands[0] << " = pow(r" << (int)operands[1] << ", r" << (int)operands[2] << ")"; + DEBUG_LOG_FMT("POW: r%d = pow(r%d, r%d)", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case FCALL: { - std::cerr << "FCALL: func=0x" << std::hex << *reinterpret_cast(operands) << std::dec << ", args=" << (int)operands[8]; + DEBUG_LOG_FMT("FCALL: func=0x%llx, args=%d", *reinterpret_cast(operands), static_cast(operands[8])); break; } case FRET: { - std::cerr << "FRET: Return from function"; + DEBUG_LOG("FRET: Return from function"); break; } case HALT: { - std::cerr << "HALT: Terminate execution"; + DEBUG_LOG("HALT: Terminate execution"); break; } case DEBUG_LOG: { - std::cerr << "DEBUG_LOG: const[" << *reinterpret_cast(operands) << "]"; + DEBUG_LOG_FMT("DEBUG_LOG: const[%llu]", *reinterpret_cast(operands)); break; } case JMP: { - std::cerr << "JMP: to " << *reinterpret_cast(operands); + DEBUG_LOG_FMT("JMP: to %llu", *reinterpret_cast(operands)); break; } case CMP_GE: { - std::cerr << "CMP_GE: r" << (int)operands[0] << " = r" << (int)operands[1] << " >= r" << (int)operands[2]; + DEBUG_LOG_FMT("CMP_GE: r%d = r%d >= r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case CMP_LT: { - std::cerr << "CMP_LT: r" << (int)operands[0] << " = r" << (int)operands[1] << " < r" << (int)operands[2]; + DEBUG_LOG_FMT("CMP_LT: r%d = r%d < r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case CMP_LE: { - std::cerr << "CMP_LE: r" << (int)operands[0] << " = r" << (int)operands[1] << " <= r" << (int)operands[2]; + DEBUG_LOG_FMT("CMP_LE: r%d = r%d <= r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case CMP_GT: { - std::cerr << "CMP_GT: r" << (int)operands[0] << " = r" << (int)operands[1] << " > r" << (int)operands[2]; + DEBUG_LOG_FMT("CMP_GT: r%d = r%d > r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case CMP_EQ: { - std::cerr << "CMP_EQ: r" << (int)operands[0] << " = r" << (int)operands[1] << " == r" << (int)operands[2]; + DEBUG_LOG_FMT("CMP_EQ: r%d = r%d == r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case CMP_NE: { - std::cerr << "CMP_NE: r" << (int)operands[0] << " = r" << (int)operands[1] << " != r" << (int)operands[2]; + DEBUG_LOG_FMT("CMP_NE: r%d = r%d != r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case IF_TRUE: { - std::cerr << "IF_TRUE: r" << (int)operands[0] << " ? to " << *reinterpret_cast(operands + 1); + DEBUG_LOG_FMT("IF_TRUE: r%d ? to %llu", static_cast(operands[0]), *reinterpret_cast(operands + 1)); break; } case IF_FALSE: { - std::cerr << "IF_FALSE: r" << (int)operands[0] << " ? to " << *reinterpret_cast(operands + 1); + DEBUG_LOG_FMT("IF_FALSE: r%d ? to %llu", static_cast(operands[0]), *reinterpret_cast(operands + 1)); break; } case FUNC_CREATE: { - std::cerr << "FUNC_CREATE: Function definition"; + DEBUG_LOG("FUNC_CREATE: Function definition"); break; } case FUNC_END: { - std::cerr << "FUNC_END: Function end"; + DEBUG_LOG("FUNC_END: Function end"); break; } case LOCAL_GET: { - std::cerr << "LOCAL_GET: r" << (int)operands[0] << " = frame[" << (int)operands[1] << "]->locals[" << *(uint16_t*)(operands + 2) << "]"; + DEBUG_LOG_FMT("LOCAL_GET: r%d = frame[%d]->locals[%d]", (int)operands[0], (int)operands[1], *(uint16_t*)(operands + 2)); break; } case LOCAL_SET: { - std::cerr << "LOCAL_SET: frame[" << (int)operands[0] << "]->locals[" << *(uint16_t*)(operands + 1) << "] = r" << (int)operands[3]; + DEBUG_LOG_FMT("LOCAL_SET: frame[%d]->locals[%d] = r%d", (int)operands[0], *(uint16_t*)(operands + 1), (int)operands[3]); break; } case AND: { - std::cerr << "AND: r" << (int)operands[0] << " = r" << (int)operands[1] << " && r" << (int)operands[2]; + DEBUG_LOG_FMT("AND: r%d = r%d && r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case OR: { - std::cerr << "OR: r" << (int)operands[0] << " = r" << (int)operands[1] << " || r" << (int)operands[2]; + DEBUG_LOG_FMT("OR: r%d = r%d || r%d", static_cast(operands[0]), static_cast(operands[1]), static_cast(operands[2])); break; } case VMC: { - std::cerr << "VMC: Call vmcall[" << *(uint16_t*)operands << "]"; + DEBUG_LOG_FMT("VMC: Call vmcall[%d]", *(uint16_t*)operands); break; } case DEC: { - std::cerr << "DEC: r" << (int)operands[0] << "--"; + DEBUG_LOG_FMT("DEC: r%d--", static_cast(operands[0])); break; } case PUSH: { - std::cerr << "PUSH: r" << (int)operands[0]; + DEBUG_LOG_FMT("PUSH: r%d", static_cast(operands[0])); break; } case CREATE_VECTOR: { - std::cerr << "CREATE_VECTOR: r" << (int)operands[0] << ", " << (int)operands[1]; + DEBUG_LOG_FMT("CREATE_VECTOR: r%d, %d", static_cast(operands[0]), static_cast(operands[1])); break; } default: { - std::cerr << "Unknown opcode: " << (int)op; + DEBUG_LOG_FMT("Unknown opcode: %d", static_cast(op)); break; } } - std::cerr << COLOR_RESET << std::endl; // 执行指令 switch (op) { @@ -270,11 +264,11 @@ int VirtualCore::run() { const int64_t imm_val = *reinterpret_cast(operands + 1); ste.regs[dst_reg] = imm_val; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move immediate value " << imm_val << " to register r" << (int)dst_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to " << imm_val << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Move immediate value %lld to register r%d", imm_val, static_cast(dst_reg)); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(dst_reg), imm_val); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVRI instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MOVRI instruction, PC increased by 1, continuing to next instruction"); break; } case MOV_RM: { @@ -292,11 +286,11 @@ int VirtualCore::run() { } ste.regs[dst_reg] = *reinterpret_cast(mem_addr); ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from memory address 0x" << std::hex << mem_addr << std::dec << " to register r" << (int)dst_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to " << ste.regs[dst_reg].i64 << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Move value from memory address 0x%llx to register r%d", mem_addr, static_cast(dst_reg)); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(dst_reg), ste.regs[dst_reg].i64); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVRM instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MOVRM instruction, PC increased by 1, continuing to next instruction"); break; } case MOV_RR: { @@ -309,11 +303,11 @@ int VirtualCore::run() { const uint8_t src_reg = operands[1]; ste.regs[dst_reg] = ste.regs[src_reg]; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from register r" << (int)src_reg << " to register r" << (int)dst_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to " << ste.regs[dst_reg].i64 << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Move value from register r%d to register r%d", static_cast(src_reg), static_cast(dst_reg)); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(dst_reg), ste.regs[dst_reg].i64); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVRR instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MOVRR instruction, PC increased by 1, continuing to next instruction"); break; } case MOV_RC: { @@ -331,11 +325,11 @@ int VirtualCore::run() { const uint64_t const_idx = *(uint64_t*)(operands + 1); ste.regs[dst_reg] = (char*)get_constant() + const_idx; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from constant pool at index " << const_idx << " to register r" << (int)dst_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to constant[" << const_idx << "]" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Move value from constant pool at index %llu to register r%d", const_idx, static_cast(dst_reg)); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to constant[%llu]", static_cast(dst_reg), const_idx); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVRC instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MOVRC instruction, PC increased by 1, continuing to next instruction"); break; } case MOV_MI: { @@ -343,11 +337,11 @@ int VirtualCore::run() { const int64_t imm_val = *reinterpret_cast(operands + 1); ste.heap[mem_addr] = imm_val; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move immediate value " << imm_val << " to memory address 0x" << std::hex << mem_addr << std::dec << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Memory at 0x" << std::hex << mem_addr << std::dec << " set to " << imm_val << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Move immediate value %lld to memory address 0x%llx", imm_val, mem_addr); + DEBUG_LOG_FMT("[EXEC] | Result: Memory at 0x%llx set to %lld", mem_addr, imm_val); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVMI instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MOVMI instruction, PC increased by 1, continuing to next instruction"); break; } case MOV_MM: { @@ -355,11 +349,11 @@ int VirtualCore::run() { const uint64_t src_addr = operands[1]; ste.heap[dst_addr] = ste.heap[src_addr]; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from memory address 0x" << std::hex << src_addr << std::dec << " to memory address 0x" << std::hex << dst_addr << std::dec << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Memory at 0x" << std::hex << dst_addr << std::dec << " set to value from 0x" << std::hex << src_addr << std::dec << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Move value from memory address 0x%llx to memory address 0x%llx", src_addr, dst_addr); + DEBUG_LOG_FMT("[EXEC] | Result: Memory at 0x%llx set to value from 0x%llx", dst_addr, src_addr); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVMM instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MOVMM instruction, PC increased by 1, continuing to next instruction"); break; } case MOV_MR: { @@ -371,11 +365,11 @@ int VirtualCore::run() { const uint8_t src_reg = operands[1]; ste.heap[mem_addr] = ste.regs[src_reg]; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from register r" << (int)src_reg << " to memory address 0x" << std::hex << mem_addr << std::dec << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Memory at 0x" << std::hex << mem_addr << std::dec << " set to value from r" << (int)src_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Move value from register r%d to memory address 0x%llx", static_cast(src_reg), mem_addr); + DEBUG_LOG_FMT("[EXEC] | Result: Memory at 0x%llx set to value from r%d", mem_addr, static_cast(src_reg)); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVMR instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MOVMR instruction, PC increased by 1, continuing to next instruction"); break; } case MOV_MC: { @@ -387,11 +381,11 @@ int VirtualCore::run() { const uint64_t const_idx = operands[1]; ste.heap[mem_addr] = (char*)get_constant() + const_idx; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Move value from constant pool at index " << const_idx << " to memory address 0x" << std::hex << mem_addr << std::dec << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Memory at 0x" << std::hex << mem_addr << std::dec << " set to constant[" << const_idx << "]" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Move value from constant pool at index %llu to memory address 0x%llx", const_idx, mem_addr); + DEBUG_LOG_FMT("[EXEC] | Result: Memory at 0x%llx set to constant[%llu]", mem_addr, const_idx); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOVMC instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MOVMC instruction, PC increased by 1, continuing to next instruction"); break; } case ADD: { @@ -426,8 +420,8 @@ int VirtualCore::run() { const int64_t add_result = ste.regs[add_src1_reg].i64 + ste.regs[add_src2_reg].i64; ste.regs[add_dst_reg] = add_result; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Add registers r" << (int)add_src1_reg << " + r" << (int)add_src2_reg << " = " << add_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)add_dst_reg << " value set to " << add_result << std::endl; + DEBUG_LOG_FMT("[EXEC] | Operation: Add registers r%d + r%d = %lld", static_cast(add_src1_reg), static_cast(add_src2_reg), add_result); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(add_dst_reg), add_result); } else if (type1 == ValueType::Ptr) { DEBUG_LOG("Adding ptr..."); // 向量加法:对应元素相加 @@ -478,16 +472,16 @@ int VirtualCore::run() { ste.regs[add_dst_reg].type = ValueType::Ptr; ste.regs[add_dst_reg].u64 = vec_result_addr; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Add vectors r" << (int)add_src1_reg << " + r" << (int)add_src2_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)add_dst_reg << " value set to vector of length " << vec1_len << std::endl; + DEBUG_LOG_FMT("[EXEC] | Operation: Add vectors r%d + r%d", static_cast(add_src1_reg), static_cast(add_src2_reg)); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to vector of length %llu", static_cast(add_dst_reg), vec1_len); } else { handle_error("Unsupported type for addition"); return 1; } - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed ADD instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed ADD instruction, PC increased by 1, continuing to next instruction"); break; } case SUB: { @@ -501,11 +495,11 @@ int VirtualCore::run() { const int64_t sub_result = ste.regs[sub_src1_reg].i64 - ste.regs[sub_src2_reg].i64; ste.regs[sub_dst_reg] = sub_result; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Subtract registers r" << (int)sub_src1_reg << " - r" << (int)sub_src2_reg << " = " << sub_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)sub_dst_reg << " value set to " << sub_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Subtract registers r%d - r%d = %lld", static_cast(sub_src1_reg), static_cast(sub_src2_reg), sub_result); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(sub_dst_reg), sub_result); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed SUB instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed SUB instruction, PC increased by 1, continuing to next instruction"); break; } case MUL: { @@ -519,11 +513,11 @@ int VirtualCore::run() { const int64_t mul_result = ste.regs[mul_src1_reg].i64 * ste.regs[mul_src2_reg].i64; ste.regs[mul_dst_reg] = mul_result; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Multiply registers r" << (int)mul_src1_reg << " * r" << (int)mul_src2_reg << " = " << mul_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)mul_dst_reg << " value set to " << mul_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Multiply registers r%d * r%d = %lld", static_cast(mul_src1_reg), static_cast(mul_src2_reg), mul_result); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(mul_dst_reg), mul_result); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MUL instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MUL instruction, PC increased by 1, continuing to next instruction"); break; } case DIV: { @@ -541,11 +535,11 @@ int VirtualCore::run() { const int64_t div_result = ste.regs[div_src1_reg].i64 / ste.regs[div_src2_reg].i64; ste.regs[div_dst_reg] = div_result; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Divide registers r" << (int)div_src1_reg << " / r" << (int)div_src2_reg << " = " << div_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)div_dst_reg << " value set to " << div_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Divide registers r%d / r%d = %lld", static_cast(div_src1_reg), static_cast(div_src2_reg), div_result); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(div_dst_reg), div_result); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed DIV instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed DIV instruction, PC increased by 1, continuing to next instruction"); break; } case MOD: { @@ -563,11 +557,11 @@ int VirtualCore::run() { const int64_t mod_result = ste.regs[mod_src1_reg].i64 % ste.regs[mod_src2_reg].i64; ste.regs[mod_dst_reg] = mod_result; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Modulo registers r" << (int)mod_src1_reg << " % r" << (int)mod_src2_reg << " = " << mod_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)mod_dst_reg << " value set to " << mod_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Modulo registers r%d %% r%d = %lld", static_cast(mod_src1_reg), static_cast(mod_src2_reg), mod_result); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(mod_dst_reg), mod_result); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed MOD instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed MOD instruction, PC increased by 1, continuing to next instruction"); break; } case POW: { @@ -581,11 +575,11 @@ int VirtualCore::run() { const double pow_result = std::pow(ste.regs[pow_src1_reg].f64, ste.regs[pow_src2_reg].f64); ste.regs[pow_dst_reg] = pow_result; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Power registers r" << (int)pow_src1_reg << " ^ r" << (int)pow_src2_reg << " = " << pow_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)pow_dst_reg << " value set to " << pow_result << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Power registers r%d ^ r%d = %f", static_cast(pow_src1_reg), static_cast(pow_src2_reg), pow_result); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %f", static_cast(pow_dst_reg), pow_result); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed POW instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed POW instruction, PC increased by 1, continuing to next instruction"); break; } case FCALL: { @@ -606,11 +600,11 @@ int VirtualCore::run() { } ste.stack_frames.back()->locals[i] = ste.regs[REG_COUNT_INDEX_MAX - i]; } - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Call function at address " << target_pc << " with " << (int)args_count << " arguments" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: PC set to " << target_pc << ", return address pushed to stack, new stack frame created" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Call function at address %llu with %d arguments", target_pc, static_cast(args_count)); + DEBUG_LOG_FMT("[EXEC] | Result: PC set to %llu, return address pushed to stack, new stack frame created", target_pc); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed FCALL instruction, jumping to function address" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed FCALL instruction, jumping to function address"); break; } case FRET: { @@ -622,19 +616,19 @@ int VirtualCore::run() { ste.pc = return_addr; //返回地址 ste.ret_addr_stack.pop_back(); ste.stack_frames.pop_back(); // 恢复栈帧 - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Return from function" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: PC set to return address " << return_addr << ", stack frame popped" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG("[EXEC] | Operation: Return from function"); + DEBUG_LOG_FMT("[EXEC] | Result: PC set to return address %llu, stack frame popped", return_addr); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed FRET instruction, returning to caller" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed FRET instruction, returning to caller"); break; } case HALT: { - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Terminate VM execution" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: VM execution terminated normally" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG("[EXEC] | Operation: Terminate VM execution"); + DEBUG_LOG("[EXEC] | Result: VM execution terminated normally"); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed HALT instruction, VM stopped running" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed HALT instruction, VM stopped running"); DEBUG_SEPARATOR("VM EXECUTION END (SUCCESS)"); DEBUG_LEAVE_FUNC(); return 0; @@ -645,13 +639,13 @@ int VirtualCore::run() { DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); return 1; } - fprintf(stderr,"[LogInfo]: %s\n", static_cast(const_pool_top) + *reinterpret_cast(operands)); + DEBUG_LOG_FMT("[LogInfo]: %s", static_cast(const_pool_top) + *reinterpret_cast(operands)); ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Print debug log" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Log printed to console" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG("[EXEC] | Operation: Print debug log"); + DEBUG_LOG("[EXEC] | Result: Log printed to console"); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed DEBUG_LOG instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed DEBUG_LOG instruction, PC increased by 1, continuing to next instruction"); break; } case JMP: { @@ -662,11 +656,11 @@ int VirtualCore::run() { return 1; } ste.pc = target_pc; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Jump to address " << target_pc << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Program counter set to " << target_pc << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Jump to address %llu", target_pc); + DEBUG_LOG_FMT("[EXEC] | Result: Program counter set to %llu", target_pc); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed JMP instruction, PC set to target address, continuing execution" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed JMP instruction, PC set to target address, continuing execution"); break; } case CMP_GE: { @@ -681,11 +675,11 @@ int VirtualCore::run() { bool result = ste.regs[src1_reg].i64 >= ste.regs[src2_reg].i64; ste.regs[dst_reg].b = result; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Compare registers r" << (int)src1_reg << " >= r" << (int)src2_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " set to " << (result ? "true" : "false") << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Compare registers r%d >= r%d", static_cast(src1_reg), static_cast(src2_reg)); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d set to %s", static_cast(dst_reg), (result ? "true" : "false")); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed CMP_GE instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed CMP_GE instruction, PC increased by 1, continuing to next instruction"); break; } case CMP_LT: { @@ -699,11 +693,11 @@ int VirtualCore::run() { bool cmp_result = ste.regs[cmp_src1_reg].i64 < ste.regs[cmp_src2_reg].i64; ste.regs[cmp_dst_reg].b = cmp_result; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Compare registers r" << (int)cmp_src1_reg << " < r" << (int)cmp_src2_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)cmp_dst_reg << " set to " << (cmp_result ? "true" : "false") << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Compare registers r%d < r%d", static_cast(cmp_src1_reg), static_cast(cmp_src2_reg)); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d set to %s", static_cast(cmp_dst_reg), (cmp_result ? "true" : "false")); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed CMP_LT instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed CMP_LT instruction, PC increased by 1, continuing to next instruction"); break; } case CMP_LE: { @@ -717,11 +711,11 @@ int VirtualCore::run() { bool cmp_result = ste.regs[cmp_src1_reg].i64 <= ste.regs[cmp_src2_reg].i64; ste.regs[cmp_dst_reg].b = cmp_result; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Compare registers r" << (int)cmp_src1_reg << " <= r" << (int)cmp_src2_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)cmp_dst_reg << " set to " << (cmp_result ? "true" : "false") << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Compare registers r%d <= r%d", static_cast(cmp_src1_reg), static_cast(cmp_src2_reg)); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d set to %s", static_cast(cmp_dst_reg), (cmp_result ? "true" : "false")); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed CMP_LE instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed CMP_LE instruction, PC increased by 1, continuing to next instruction"); break; } case CMP_GT: { @@ -767,16 +761,16 @@ int VirtualCore::run() { bool condition = ste.regs[cond_reg].b; if (condition) { ste.pc = target_pc; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Jump to address " << target_pc << " if condition is true" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Condition is true, PC set to " << target_pc << std::endl; + DEBUG_LOG_FMT("[EXEC] | Operation: Jump to address %llu if condition is true", target_pc); + DEBUG_LOG_FMT("[EXEC] | Result: Condition is true, PC set to %llu", target_pc); } else { ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Jump to address " << target_pc << " if condition is true" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Condition is false, PC increased by 1" << std::endl; + DEBUG_LOG_FMT("[EXEC] | Operation: Jump to address %llu if condition is true", target_pc); + DEBUG_LOG("[EXEC] | Result: Condition is false, PC increased by 1"); } - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed IF_TRUE instruction, " << (condition ? "jumping to target address" : "continuing to next instruction") << COLOR_RESET << std::endl; + DEBUG_LOG_FMT("[EXEC] | Because: Executed IF_TRUE instruction, %s", (condition ? "jumping to target address" : "continuing to next instruction")); break; } case IF_FALSE: { @@ -825,13 +819,26 @@ int VirtualCore::run() { } const uint8_t dst_reg = operands[0]; const uint8_t frame_idx = operands[1]; + + // 打印变量表信息 + DEBUG_LOG("[EXEC] | Variable table before LOCAL_GET:"); + for (size_t i = 0; i < ste.stack_frames[frame_idx]->locals.size(); i++) { + const auto& val = ste.stack_frames[frame_idx]->locals[i]; + DEBUG_LOG_FMT("[EXEC] | Index %zu: Type=%s, Value=%s", i, val.type_name(), val.to_string().c_str()); + } + + // 执行加载操作 ste.regs[dst_reg] = ste.stack_frames[frame_idx]->locals[local_index]; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Load local variable " << local_index << " from frame " << (int)frame_idx << " to register r" << (int)dst_reg << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Register r" << (int)dst_reg << " value set to " << ste.regs[dst_reg].i64 << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + + // 打印详细信息 + const auto& loaded_val = ste.stack_frames[frame_idx]->locals[local_index]; + DEBUG_LOG_FMT("[EXEC] | Operation: Load local variable at index %d from frame %d to register r%d", local_index, static_cast(frame_idx), static_cast(dst_reg)); + DEBUG_LOG_FMT("[EXEC] | Loaded value: Type=%s, Value=%s", loaded_val.type_name(), loaded_val.to_string().c_str()); + DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %s", static_cast(dst_reg), ste.regs[dst_reg].to_string().c_str()); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed LOCAL_GET instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed LOCAL_GET instruction, PC increased by 1, continuing to next instruction"); break; } case LOCAL_SET: { @@ -855,11 +862,11 @@ int VirtualCore::run() { const uint8_t src_reg = operands[3]; ste.stack_frames[frame_idx]->locals[local_index] = ste.regs[src_reg]; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Store register r" << (int)src_reg << " value to local variable " << local_index << " in frame " << (int)frame_idx << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: frame[" << (int)frame_idx << "]->locals[" << local_index << "] = " << ste.regs[src_reg].i64 << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Current state: " << COLOR_RESET; + DEBUG_LOG_FMT("[EXEC] | Operation: Store register r%d value to local variable %d in frame %d", static_cast(src_reg), local_index, static_cast(frame_idx)); + DEBUG_LOG_FMT("[EXEC] | Result: frame[%d]->locals[%d] = %lld", static_cast(frame_idx), local_index, ste.regs[src_reg].i64); + DEBUG_LOG("[EXEC] | Current state:"); DEBUG_REGS(ste.regs); - std::cerr << COLOR_YELLOW << "[EXEC] | Because: Executed LOCAL_SET instruction, PC increased by 1, continuing to next instruction" << COLOR_RESET << std::endl; + DEBUG_LOG("[EXEC] | Because: Executed LOCAL_SET instruction, PC increased by 1, continuing to next instruction"); break; } case AND: { @@ -907,8 +914,8 @@ int VirtualCore::run() { const uint8_t src_reg = operands[0]; ste.stack.push_back(ste.regs[src_reg]); ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Push register r" << (int)src_reg << " to stack" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Stack size: " << ste.stack.size() << std::endl; + DEBUG_LOG_FMT("[EXEC] | Operation: Push register r%d to stack", static_cast(src_reg)); + DEBUG_LOG_FMT("[EXEC] | Result: Stack size: %llu", ste.stack.size()); break; } case CREATE_VECTOR: { @@ -957,9 +964,9 @@ int VirtualCore::run() { ste.regs[dst_reg].u64 = vec_addr; ste.pc++; - std::cerr << COLOR_YELLOW << "[EXEC] | Operation: Create vector with " << (int)count << " elements" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Result: Vector at heap[" << vec_addr << "]" << std::endl; - std::cerr << COLOR_YELLOW << "[EXEC] | Stack size after: " << ste.stack.size() << std::endl; + DEBUG_LOG_FMT("[EXEC] | Operation: Create vector with %d elements", static_cast(count)); + DEBUG_LOG_FMT("[EXEC] | Result: Vector at heap[%llu]", vec_addr); + DEBUG_LOG_FMT("[EXEC] | Stack size after: %llu", ste.stack.size()); break; } default: @@ -974,4 +981,47 @@ int VirtualCore::run() { return 1; } +void VirtualCore::insert_builtins() { + DEBUG_LOG("insert builtins..."); + + DEBUG_LOG("Before inserting builtins - Main stack frame locals:"); + for (size_t i = 0; i < ste.stack_frames[0]->locals.size(); i++) { + const auto& val = ste.stack_frames[0]->locals[i]; + DEBUG_LOG_FMT(" Index %zu: Type=%s, Value=%s", i, val.type_name(), val.to_string().c_str()); + } + + const auto old_program = ste.program; + const auto old_pc = ste.pc; + + // 使用 builtins 命名空间中的内置常量 + size_t base_index = 64; // 从索引 64 开始 + for (size_t i = 0; i < builtins::builtin_constants_count; i++) { + const auto& constant = builtins::builtin_constants[i]; + + // 确保栈帧的 locals 数组足够大 + if (ste.stack_frames[0]->locals.size() <= base_index) { + ste.stack_frames[0]->locals.resize(base_index + 1); + } + + // 设置内置常量值 + ste.stack_frames[0]->locals[base_index] = constant.value; + + DEBUG_LOG_FMT("Added builtin constant %s = %s at index %zu", + constant.name, + constant.value.to_string().c_str(), + base_index); + base_index++; + } + + // 打印之后的变量表 + DEBUG_LOG("After inserting builtins - Main stack frame locals:"); + for (size_t i = 64; i < ste.stack_frames[0]->locals.size(); i++) { + const auto& val = ste.stack_frames[0]->locals[i]; + DEBUG_LOG_FMT(" Index %zu: Type=%s, Value=%s", i, val.type_name(), val.to_string().c_str()); + } + + // 恢复 ste 状态 + ste.program = old_program; + ste.pc = old_pc; +} } diff --git a/runtime/vm.hpp b/runtime/vm.hpp index 6cf5e36..a08ffa4 100644 --- a/runtime/vm.hpp +++ b/runtime/vm.hpp @@ -102,10 +102,12 @@ class LMVM_API VirtualCore { void set_reg_ptr(const size_t idx, void* np) { ste.regs[idx].ptr = np; } // 堆内存管理方法 - size_t heap_size() const { return ste.heap.size(); } + [[nodiscard]] size_t heap_size() const { return ste.heap.size(); } Value& heap_at(size_t index) { return ste.heap[index]; } - const Value& heap_at(size_t index) const { return ste.heap[index]; } + [[nodiscard]] const Value& heap_at(size_t index) const { return ste.heap[index]; } void heap_push_back(const Value& value) { ste.heap.push_back(value); } + + void insert_builtins(); }; } diff --git a/tools/lm/common/repl.cpp b/tools/lm/common/repl.cpp index 427f205..678f074 100644 --- a/tools/lm/common/repl.cpp +++ b/tools/lm/common/repl.cpp @@ -165,9 +165,9 @@ void print_ast(const std::shared_ptr& node, int indent = 0) { int run_repl() { std::string expr; lmx::Lexer l(expr); - lmx::Generator gener; + lmx::Generator generator; lmx::runtime::VirtualCore core; - core.set_program(&gener.ops); + core.set_program(&generator.ops); const std::string prompt = ">>> "; while (true) { @@ -175,8 +175,8 @@ int run_repl() { if (!std::getline(std::cin, expr)) break; if (expr == ":lastret") std::cout << core.look_register(0) << std::endl; else if (expr == ":exit") break; - else if (expr == ":op") gener.print_ops(); - else if (expr == ":vars") gener.print_vars(); + else if (expr == ":op") generator.print_ops(); + else if (expr == ":vars") generator.print_vars(); else { // Reset error flag before processing each input lmx::Generator::node_has_error = false; @@ -197,22 +197,22 @@ int run_repl() { DEBUG_SEPARATOR("AST END"); // Generate bytecode and display it - const auto op = gener.gen(node); + const auto op = generator.gen(node); if (lmx::Generator::node_has_error) continue; DEBUG_SEPARATOR("GENERATED BYTECODE"); std::cerr << COLOR_CYAN; - gener.print_ops(); + generator.print_ops(); std::cerr << COLOR_RESET; DEBUG_SEPARATOR("BYTECODE END"); // Execute - gener.ops.emplace_back(lmx::runtime::Opcode::HALT); - core.set_constant(gener.constant_pool.data()); + generator.ops.emplace_back(lmx::runtime::Opcode::HALT); + core.set_constant(generator.constant_pool.data()); int result = core.run(); if (op != -1 && result == 0) { - gener.regs.free(op); + generator.regs.free(op); // 检查返回值的类型 auto& value = core.get_register(op); if (value.type == lmx::runtime::ValueType::Null) { @@ -226,37 +226,86 @@ int run_repl() { if (i > 0) std::cout << ", "; // 根据元素类型显示 auto& elem = core.heap_at(vector_ptr + 1 + i); - switch (elem.type) { - case lmx::runtime::ValueType::Int: - std::cout << elem.i64; - break; - case lmx::runtime::ValueType::Str: - std::cout << "\"" << elem.str << "\""; - break; - case lmx::runtime::ValueType::Bool: - std::cout << (elem.b ? "true" : "false"); - break; - case lmx::runtime::ValueType::Float: - std::cout << elem.f64; - break; - case lmx::runtime::ValueType::Ptr: - std::cout << "ptr(" << elem.u64 << ")"; - break; - case lmx::runtime::ValueType::Null: - std::cout << "null"; - break; - default: - std::cout << ""; - break; + if (elem.type == lmx::runtime::ValueType::Ptr) { + // 检查是否是向量 + size_t elem_ptr = elem.u64; + size_t elem_size = core.heap_at(elem_ptr).i64; + // 递归显示向量 + std::cout << "vec["; + for (size_t j = 0; j < elem_size; j++) { + if (j > 0) std::cout << ", "; + auto& nested_elem = core.heap_at(elem_ptr + 1 + j); + switch (nested_elem.type) { + case lmx::runtime::ValueType::Int: + std::cout << nested_elem.i64; + break; + case lmx::runtime::ValueType::Str: + std::cout << "\"" << nested_elem.str << "\""; + break; + case lmx::runtime::ValueType::Bool: + std::cout << (nested_elem.b ? "true" : "false"); + break; + case lmx::runtime::ValueType::Float: + std::cout << nested_elem.f64; + break; + case lmx::runtime::ValueType::Ptr: + std::cout << "ptr(" << nested_elem.u64 << ")"; + break; + case lmx::runtime::ValueType::Null: + std::cout << "null"; + break; + default: + std::cout << ""; + break; + } + } + std::cout << "]"; + } else { + switch (elem.type) { + case lmx::runtime::ValueType::Int: + std::cout << elem.i64; + break; + case lmx::runtime::ValueType::Str: + std::cout << "\"" << elem.str << "\""; + break; + case lmx::runtime::ValueType::Bool: + std::cout << (elem.b ? "true" : "false"); + break; + case lmx::runtime::ValueType::Float: + std::cout << elem.f64; + break; + case lmx::runtime::ValueType::Null: + std::cout << "null"; + break; + default: + std::cout << ""; + break; + } } } std::cout << "]" << std::endl; } else { - // 对于其他类型,使用默认的输出 - std::cout << core.look_register(op) << std::endl; + // 对于其他类型,根据类型正确显示 + switch (value.type) { + case lmx::runtime::ValueType::Int: + std::cout << value.i64 << std::endl; + break; + case lmx::runtime::ValueType::Float: + std::cout << value.f64 << std::endl; + break; + case lmx::runtime::ValueType::Bool: + std::cout << (value.b ? "true" : "false") << std::endl; + break; + case lmx::runtime::ValueType::Str: + std::cout << "\"" << value.str << "\"" << std::endl; + break; + default: + std::cout << value.to_string() << std::endl; + break; + } } } - if (gener.ops.back().op == lmx::runtime::Opcode::HALT) gener.ops.pop_back(); + if (generator.ops.back().op == lmx::runtime::Opcode::HALT) generator.ops.pop_back(); } } return 0; From f010eea15067abd66f5659fa8dd3d299f48a680b Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Wed, 25 Mar 2026 21:10:19 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=A0=87=E5=87=86?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=EF=BC=8C=E6=B8=85=E7=90=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/ast.hpp | 3 - compiler/common.hpp | 2 +- compiler/generator/generator.cpp | 19 +- compiler/generator/generator.hpp | 2 +- compiler/lexer.cpp | 23 +-- include/lmx_export.hpp | 4 +- include/opcode.hpp | 10 +- runtime/builtins.cpp | 28 ++- runtime/builtins.hpp | 2 +- runtime/frame/frame.hpp | 4 +- runtime/libloader.cpp | 10 +- runtime/object/base.hpp | 1 - runtime/value/value.cpp | 2 +- runtime/value/value.hpp | 10 +- runtime/vm.cpp | 320 ++++++++----------------------- runtime/vm.hpp | 2 +- tools/lm/main.cpp | 4 +- 17 files changed, 153 insertions(+), 293 deletions(-) diff --git a/compiler/ast.hpp b/compiler/ast.hpp index d3dde5d..1f50455 100644 --- a/compiler/ast.hpp +++ b/compiler/ast.hpp @@ -3,12 +3,9 @@ // #pragma once -#include -#include #include #include #include -#include #include "../include/lmx_export.hpp" diff --git a/compiler/common.hpp b/compiler/common.hpp index 43bc517..cc942df 100644 --- a/compiler/common.hpp +++ b/compiler/common.hpp @@ -26,7 +26,7 @@ namespace lmx { std::cerr << "Failed to open file " << path << std::endl; return {}; } - return std::string(std::istreambuf_iterator{file}, std::istreambuf_iterator{}); + return {std::istreambuf_iterator{file}, std::istreambuf_iterator{}}; } inline std::shared_ptr compile(const std::string &path) { std::string code = read_file(path); diff --git a/compiler/generator/generator.cpp b/compiler/generator/generator.cpp index 5c698e0..831ec45 100644 --- a/compiler/generator/generator.cpp +++ b/compiler/generator/generator.cpp @@ -46,16 +46,16 @@ void Allocator::free(size_t i) { } } -bool Allocator::is_free(size_t i) { +bool Allocator::is_free(const size_t i) const { return bitset.test(i); } void Generator::add_builtins() const { // 从 builtins 命名空间添加内置常量到编译帧 - size_t base_index = 64; // 从索引 64 开始 + size_t base_index = runtime::builtins::builtin_start; for (size_t i = 0; i < runtime::builtins::builtin_constants_count; i++) { - const auto& constant = runtime::builtins::builtin_constants[i]; - cur.back()->new_var(constant.name, false, base_index); + const auto&[name, value] = runtime::builtins::builtin_constants[i]; + cur.back()->new_var(name, false, base_index); base_index++; } } @@ -121,7 +121,7 @@ size_t Generator::gen_program(std::shared_ptr &n) { return last_ret; } size_t Generator::gen_loop(const std::shared_ptr &shared) { - const auto node = std::static_pointer_cast(std::move(shared)); + const auto node = std::static_pointer_cast(shared); size_t loop_cond = -1; if (node->condition) loop_cond = gen(node->condition); @@ -614,13 +614,20 @@ void Generator::print_ops(std::vector& ops) { break; } case MOV_MI: { - + printf("MOVMI: 0x%llu, %lld\n", *reinterpret_cast(op.operands), *reinterpret_cast(op.operands + 1)); + break; } case MOV_MM: { + printf("MOVMM: 0x%llu, 0x%llu\n", *reinterpret_cast(op.operands), *reinterpret_cast(op.operands + 1)); + break; } case MOV_MR: { + printf("MOVMR: 0x%llu, %u\n", *reinterpret_cast(op.operands), op.operands[1]); + break; } case MOV_MC: { + printf("MOVMC: 0x%llu, 0x%llu\n", *reinterpret_cast(op.operands), *reinterpret_cast(op.operands + 1)); + break; } case ADD: { printf("ADD: %u, %u, %u\n", op.operands[0], op.operands[1], op.operands[2]); diff --git a/compiler/generator/generator.hpp b/compiler/generator/generator.hpp index 9178c2b..cc0bc06 100644 --- a/compiler/generator/generator.hpp +++ b/compiler/generator/generator.hpp @@ -34,7 +34,7 @@ class LMC_API Allocator { size_t alloc(); size_t alloc(size_t i); void free(size_t i); - bool is_free(size_t i); + bool is_free(size_t i) const; void print_regs() const { std::string regs_str = "Allocated registers: "; for (size_t i = 0; i < REG_COUNT; i++) { diff --git a/compiler/lexer.cpp b/compiler/lexer.cpp index 9911b2a..0c84d76 100644 --- a/compiler/lexer.cpp +++ b/compiler/lexer.cpp @@ -75,7 +75,7 @@ struct TokenPattern { // 优先级从高到低排序 static const std::vector token_patterns = { {TokenType::COMMENT, "^#.*?$"}, - {TokenType::STRING_LITERAL, "^\"(\\.|[^\\\"])*\""}, + {TokenType::STRING_LITERAL, R"(^"(\.|[^\"])*")"}, {TokenType::EQ, "^=="}, {TokenType::NE, "^!="}, {TokenType::GE, "^>="}, @@ -124,8 +124,6 @@ static const std::unordered_map keywords = { {"false", TokenType::FALSE_LITERAL}, }; -// 移除advance方法,因为我们将使用正则表达式匹配来更新位置 - Token Lexer::next() { // 跳过空白字符 while (pos < src.size() && isspace(src[pos])) { @@ -143,21 +141,21 @@ Token Lexer::next() { } // 提取当前位置开始的子串 - std::string remaining = src.substr(pos); + const std::string remaining = src.substr(pos); // 尝试匹配所有token模式 for (const auto& pattern : token_patterns) { std::smatch match; if (std::regex_search(remaining, match, pattern.pattern)) { - std::string matched_text = match.str(0); - size_t match_length = matched_text.size(); + const std::string matched_text = match.str(0); + const size_t match_length = matched_text.size(); // 保存当前位置信息 - size_t token_line = line; - size_t token_col = col; + const size_t token_line = line; + const size_t token_col = col; // 更新位置信息 - for (char c : matched_text) { + for (const char c : matched_text) { if (c == '\n') { line++; col = 1; @@ -178,7 +176,7 @@ Token Lexer::next() { // 处理字符串字面量(去除引号) if (pattern.type == TokenType::STRING_LITERAL) { // 去除首尾引号 - std::string unquoted = matched_text.substr(1, matched_text.size() - 2); + const std::string unquoted = matched_text.substr(1, matched_text.size() - 2); // 处理转义字符 std::string processed; for (size_t i = 0; i < unquoted.size(); i++) { @@ -222,7 +220,7 @@ Token Lexer::next() { } // 无法识别的字符 - char unknown_char = src[pos]; + const char unknown_char = src[pos]; Token token = {TokenType::UNKNOWN, std::string(1, unknown_char), line, col}; pos++; col++; @@ -242,8 +240,7 @@ std::vector Lexer::tokenize(const std::string& new_src) { tokens.push_back(t); } } - - // Add EOF token at the end + tokens.push_back({TokenType::END_OF_FILE, "", line, col}); return tokens; diff --git a/include/lmx_export.hpp b/include/lmx_export.hpp index af2fdad..ad7f151 100644 --- a/include/lmx_export.hpp +++ b/include/lmx_export.hpp @@ -24,5 +24,5 @@ #define LMX_VERSION 0x00000001 #define LMX_MAGIC_NUM 0x4d4c5451 -const unsigned int lmx_magic = LMX_MAGIC_NUM; -const unsigned int lmx_version = LMX_VERSION; +constexpr unsigned int lmx_magic = LMX_MAGIC_NUM; +constexpr unsigned int lmx_version = LMX_VERSION; diff --git a/include/opcode.hpp b/include/opcode.hpp index 27a4527..ace0322 100644 --- a/include/opcode.hpp +++ b/include/opcode.hpp @@ -34,7 +34,7 @@ enum class Opcode : uint8_t { CREATE_VECTOR, // 创建向量指令 }; -inline uint8_t opcode_len(Opcode op) { +inline uint8_t opcode_len(const Opcode op) { switch (op) { using enum Opcode; case MOV_RI: @@ -79,13 +79,13 @@ inline uint8_t opcode_len(Opcode op) { } struct Op { - Opcode op; + Opcode op{}; uint8_t operands[12]{}; - explicit inline Op(const Opcode op, const uint8_t* operand): op(op) { + explicit Op(const Opcode op, const uint8_t* operand): op(op) { memcpy(operands, operand, 12); } - explicit inline Op(const Opcode op): op(op) {} - explicit inline Op() = default; + explicit Op(const Opcode op): op(op) {} + explicit Op() = default; }; } // namespace lmx diff --git a/runtime/builtins.cpp b/runtime/builtins.cpp index 3775f2d..5f2022b 100644 --- a/runtime/builtins.cpp +++ b/runtime/builtins.cpp @@ -2,16 +2,34 @@ namespace lmx::runtime::builtins { const BuiltinConstant builtin_constants[] = { - {"pi", 3.14159265358979323846}, - {"e", 2.71828182845904523536}, - {"phi", 1.61803398874989484820}, - {"gamma", 0.5772156649015328606065120900824024310421} + // 物理常量 + {"EARTH_GRAVITY", 9.80665}, + {"MOON_GRAVITY", 1.625}, + {"MARS_GRAVITY", 3.72076}, + {"WATER_DENSITY", 1000.0}, + {"STANDARD_PRESSURE", 101325.0}, + {"STANDARD_TEMPERATURE", 273.15}, + {"AIR_DENSITY", 1.225}, + {"C", 2.99792458e8}, + {"G", 6.67430e-11}, + {"H", 6.62607015e-34}, + {"KB", 1.380649e-23}, + {"EPSILON_0", 8.8541878128e-12}, + {"MU_0", 1.25663706212e-6}, + // 化学常量 + {"AVOGADRO", 6.02214076e23}, + {"R", 8.314462618}, + {"FARADAY", 9.648533212e4}, + {"AMU", 1.66053906660e-27}, + {"MOLAR_VOLUME_IDEAL", 0.024465}, + {"ROOM_PRESSURE", 1.0e5}, + {"ROOM_TEMPERATURE", 297.15} }; size_t builtin_constants_count = std::size(builtin_constants); size_t get_builtin_constant_index(const std::string& name) { for (size_t i = 0; i < builtin_constants_count; i++) if (builtin_constants[i].name == name) return i + builtin_start; - return -1; + return SIZE_MAX; } } \ No newline at end of file diff --git a/runtime/builtins.hpp b/runtime/builtins.hpp index 2c10c07..aae11db 100644 --- a/runtime/builtins.hpp +++ b/runtime/builtins.hpp @@ -11,7 +11,7 @@ struct BuiltinConstant { }; // 内置常量数量 -inline int builtin_start = 64; +inline int builtin_start = 0; extern LMVM_API size_t builtin_constants_count; extern LMVM_API const BuiltinConstant builtin_constants[]; diff --git a/runtime/frame/frame.hpp b/runtime/frame/frame.hpp index f2d27af..85fb886 100644 --- a/runtime/frame/frame.hpp +++ b/runtime/frame/frame.hpp @@ -8,13 +8,11 @@ namespace lmx::runtime { struct StackFrame { - // size_t local_pc{}; std::vector locals{}; - // size_t ret_addr{}; StackFrame() { locals.resize(56); } - void new_var(const uint16_t addr, Value& value) { + void new_var(const uint16_t addr, const Value& value) { if (locals.size() <= addr) locals.resize(addr + 1); locals[addr] = value; } diff --git a/runtime/libloader.cpp b/runtime/libloader.cpp index 2167358..5588a45 100644 --- a/runtime/libloader.cpp +++ b/runtime/libloader.cpp @@ -42,10 +42,10 @@ void DynFunc::call(VirtualCore* vm) const { switch (ret_type) { case Void: vm->get_register(0) = (void*)nullptr; dcCallVoid(caller, func); break; - case Char: vm->get_register(0) = static_cast(dcCallChar(caller, func)); break; - case Short: vm->get_register(0) = static_cast(dcCallShort(caller, func)); break; - case Int: vm->get_register(0) = static_cast(dcCallInt(caller, func)); break; - case LongLong: vm->get_register(0) = static_cast(dcCallLongLong(caller, func)); break; + case Char: vm->get_register(0) = static_cast(dcCallChar(caller, func)); break; + case Short: vm->get_register(0) = static_cast(dcCallShort(caller, func)); break; + case Int: vm->get_register(0) = static_cast(dcCallInt(caller, func)); break; + case LongLong: vm->get_register(0) = static_cast(dcCallLongLong(caller, func)); break; case Bool: vm->get_register(0) = static_cast(dcCallBool(caller, func)); break; case Double: vm->get_register(0) = dcCallDouble(caller, func); break; case Ptr: vm->get_register(0) = dcCallPointer(caller, func); break; @@ -64,7 +64,7 @@ size_t DynFunc::max_size() const { #else 0; #endif - for (const auto& at : arg_type) + for ([[maybe_unused]] const auto& at : arg_type) size += 8; return size; } diff --git a/runtime/object/base.hpp b/runtime/object/base.hpp index 5960d71..dc42473 100644 --- a/runtime/object/base.hpp +++ b/runtime/object/base.hpp @@ -1,6 +1,5 @@ #pragma once #include -#include namespace lmx::runtime { enum class LMXObjType: uint8_t { diff --git a/runtime/value/value.cpp b/runtime/value/value.cpp index 4787825..7ef4a16 100644 --- a/runtime/value/value.cpp +++ b/runtime/value/value.cpp @@ -11,7 +11,7 @@ namespace lmx::runtime { -Value::Value() : null(nullptr), type(ValueType::Ptr) { +Value::Value() : type(ValueType::Ptr), null(nullptr) { } Value::Value(double n) : type(ValueType::Float), f64(n) { diff --git a/runtime/value/value.hpp b/runtime/value/value.hpp index b117437..ffecfcd 100644 --- a/runtime/value/value.hpp +++ b/runtime/value/value.hpp @@ -35,11 +35,11 @@ struct LMVM_API Value { void* ptr; char* str; }; - explicit Value(void* p); - Value(); - Value(double n); - Value(const Value& other) = default; - template + explicit Value(void* p); + Value(); + explicit Value(double n); + Value(const Value& other) = default; + template T& get(); Value &operator=(void* new_ptr); diff --git a/runtime/vm.cpp b/runtime/vm.cpp index 68c01ad..8fd78e2 100644 --- a/runtime/vm.cpp +++ b/runtime/vm.cpp @@ -23,8 +23,8 @@ VirtualCore::VirtualCore() : const_pool_top(nullptr) { insert_builtins(); } -Value* VirtualCore::get_value_from_pool(const size_t offest) const { - return static_cast(const_pool_top) + offest; +Value* VirtualCore::get_value_from_pool(const size_t offset) const { + return static_cast(const_pool_top) + offset; } bool VirtualCore::is_valid_register(uint8_t reg) const { @@ -63,15 +63,10 @@ void VirtualCore::handle_error(const char* error_message) const { } VirtualCore::~VirtualCore() { - // 清理栈帧 ste.stack_frames.clear(); - // 清理返回地址栈 ste.ret_addr_stack.clear(); - // 程序指针设为nullptr ste.program = nullptr; - // 常量池指针设为nullptr const_pool_top = nullptr; - // 清理加载的库 - 库的析构函数会自动释放动态库句柄 libs.clear(); } @@ -92,9 +87,8 @@ int VirtualCore::run() { const Opcode& op = ste.program->operator[](ste.pc).op; const auto& operands = ste.program->operator[](ste.pc).operands; - // 显示当前执行的字节码行 DEBUG_EXEC_STEP(ste.pc, op, ""); - // 根据指令类型显示详细信息 + switch (op) { using enum Opcode; case MOV_RI: { @@ -250,8 +244,7 @@ int VirtualCore::run() { break; } } - - // 执行指令 + switch (op) { using enum Opcode; case MOV_RI: { @@ -264,11 +257,7 @@ int VirtualCore::run() { const int64_t imm_val = *reinterpret_cast(operands + 1); ste.regs[dst_reg] = imm_val; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Move immediate value %lld to register r%d", imm_val, static_cast(dst_reg)); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(dst_reg), imm_val); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MOVRI instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MOVRI: r%d = %lld", static_cast(dst_reg), imm_val); break; } case MOV_RM: { @@ -286,11 +275,7 @@ int VirtualCore::run() { } ste.regs[dst_reg] = *reinterpret_cast(mem_addr); ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Move value from memory address 0x%llx to register r%d", mem_addr, static_cast(dst_reg)); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(dst_reg), ste.regs[dst_reg].i64); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MOVRM instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MOVRM: r%d = mem[0x%llx]", static_cast(dst_reg), mem_addr); break; } case MOV_RR: { @@ -303,11 +288,7 @@ int VirtualCore::run() { const uint8_t src_reg = operands[1]; ste.regs[dst_reg] = ste.regs[src_reg]; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Move value from register r%d to register r%d", static_cast(src_reg), static_cast(dst_reg)); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(dst_reg), ste.regs[dst_reg].i64); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MOVRR instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MOVRR: r%d = r%d", static_cast(dst_reg), static_cast(src_reg)); break; } case MOV_RC: { @@ -325,11 +306,7 @@ int VirtualCore::run() { const uint64_t const_idx = *(uint64_t*)(operands + 1); ste.regs[dst_reg] = (char*)get_constant() + const_idx; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Move value from constant pool at index %llu to register r%d", const_idx, static_cast(dst_reg)); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to constant[%llu]", static_cast(dst_reg), const_idx); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MOVRC instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MOVRC: r%d = const[%llu]", static_cast(dst_reg), const_idx); break; } case MOV_MI: { @@ -337,11 +314,7 @@ int VirtualCore::run() { const int64_t imm_val = *reinterpret_cast(operands + 1); ste.heap[mem_addr] = imm_val; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Move immediate value %lld to memory address 0x%llx", imm_val, mem_addr); - DEBUG_LOG_FMT("[EXEC] | Result: Memory at 0x%llx set to %lld", mem_addr, imm_val); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MOVMI instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MOVMI: mem[0x%llx] = %lld", mem_addr, imm_val); break; } case MOV_MM: { @@ -349,11 +322,7 @@ int VirtualCore::run() { const uint64_t src_addr = operands[1]; ste.heap[dst_addr] = ste.heap[src_addr]; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Move value from memory address 0x%llx to memory address 0x%llx", src_addr, dst_addr); - DEBUG_LOG_FMT("[EXEC] | Result: Memory at 0x%llx set to value from 0x%llx", dst_addr, src_addr); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MOVMM instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MOVMM: mem[0x%llx] = mem[0x%llx]", dst_addr, src_addr); break; } case MOV_MR: { @@ -365,11 +334,7 @@ int VirtualCore::run() { const uint8_t src_reg = operands[1]; ste.heap[mem_addr] = ste.regs[src_reg]; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Move value from register r%d to memory address 0x%llx", static_cast(src_reg), mem_addr); - DEBUG_LOG_FMT("[EXEC] | Result: Memory at 0x%llx set to value from r%d", mem_addr, static_cast(src_reg)); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MOVMR instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MOVMR: mem[0x%llx] = r%d", mem_addr, static_cast(src_reg)); break; } case MOV_MC: { @@ -381,11 +346,7 @@ int VirtualCore::run() { const uint64_t const_idx = operands[1]; ste.heap[mem_addr] = (char*)get_constant() + const_idx; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Move value from constant pool at index %llu to memory address 0x%llx", const_idx, mem_addr); - DEBUG_LOG_FMT("[EXEC] | Result: Memory at 0x%llx set to constant[%llu]", mem_addr, const_idx); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MOVMC instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MOVMC: mem[0x%llx] = const[%llu]", mem_addr, const_idx); break; } case ADD: { @@ -396,67 +357,56 @@ int VirtualCore::run() { const uint8_t add_dst_reg = operands[0]; const uint8_t add_src1_reg = operands[1]; const uint8_t add_src2_reg = operands[2]; - - // 类型检查 + const ValueType::ValueType type1 = ste.regs[add_src1_reg].type; const ValueType::ValueType type2 = ste.regs[add_src2_reg].type; DEBUG_LOG("type1: " << type1 << ", type2: " << type2); - - // 禁止向量与数字相加 - if ((type1 == ValueType::Ptr && type2 == ValueType::Int) || + + if ((type1 == ValueType::Ptr && type2 == ValueType::Int) || (type1 == ValueType::Int && type2 == ValueType::Ptr)) { handle_error("Cannot add vector and number"); return 1; } - - // 只允许相同类型的加法 + if (type1 != type2) { handle_error("Cannot add different types"); return 1; } - - // 处理不同类型的加法 + if (type1 == ValueType::Int) { const int64_t add_result = ste.regs[add_src1_reg].i64 + ste.regs[add_src2_reg].i64; ste.regs[add_dst_reg] = add_result; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Add registers r%d + r%d = %lld", static_cast(add_src1_reg), static_cast(add_src2_reg), add_result); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(add_dst_reg), add_result); + DEBUG_LOG_FMT("ADD: r%d = r%d + r%d = %lld", static_cast(add_dst_reg), + static_cast(add_src1_reg), static_cast(add_src2_reg), add_result); } else if (type1 == ValueType::Ptr) { DEBUG_LOG("Adding ptr..."); - // 向量加法:对应元素相加 const size_t vec1_addr = ste.regs[add_src1_reg].u64; const size_t vec2_addr = ste.regs[add_src2_reg].u64; - - // 检查向量长度是否相同 + const size_t vec1_len = ste.heap[vec1_addr].i64; const size_t vec2_len = ste.heap[vec2_addr].i64; - + if (vec1_len != vec2_len) { handle_error("Vectors must have the same length for addition"); return 1; } - - // 分配新向量 + const size_t vec_result_addr = ste.heap.size(); ste.heap.resize(vec_result_addr + 1 + vec1_len); - - // 存储长度 + ste.heap[vec_result_addr].type = ValueType::Int; ste.heap[vec_result_addr].i64 = vec1_len; - - // 对应元素相加 + for (size_t i = 0; i < vec1_len; i++) { const Value& elem1 = ste.heap[vec1_addr + 1 + i]; const Value& elem2 = ste.heap[vec2_addr + 1 + i]; - - // 确保元素类型相同 + if (elem1.type != elem2.type) { handle_error("Vector elements must have the same type for addition"); return 1; } - - // 执行元素加法 + Value result_elem; if (elem1.type == ValueType::Int) { result_elem = elem1.i64 + elem2.i64; @@ -464,24 +414,19 @@ int VirtualCore::run() { handle_error("Unsupported vector element type for addition"); return 1; } - + ste.heap[vec_result_addr + 1 + i] = result_elem; } - - // 设置结果 + ste.regs[add_dst_reg].type = ValueType::Ptr; ste.regs[add_dst_reg].u64 = vec_result_addr; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Add vectors r%d + r%d", static_cast(add_src1_reg), static_cast(add_src2_reg)); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to vector of length %llu", static_cast(add_dst_reg), vec1_len); + DEBUG_LOG_FMT("ADD: vector r%d + r%d, result len=%llu", + static_cast(add_src1_reg), static_cast(add_src2_reg), vec1_len); } else { handle_error("Unsupported type for addition"); return 1; } - - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed ADD instruction, PC increased by 1, continuing to next instruction"); break; } case SUB: { @@ -495,11 +440,8 @@ int VirtualCore::run() { const int64_t sub_result = ste.regs[sub_src1_reg].i64 - ste.regs[sub_src2_reg].i64; ste.regs[sub_dst_reg] = sub_result; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Subtract registers r%d - r%d = %lld", static_cast(sub_src1_reg), static_cast(sub_src2_reg), sub_result); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(sub_dst_reg), sub_result); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed SUB instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("SUB: r%d = r%d - r%d = %lld", static_cast(sub_dst_reg), + static_cast(sub_src1_reg), static_cast(sub_src2_reg), sub_result); break; } case MUL: { @@ -513,11 +455,8 @@ int VirtualCore::run() { const int64_t mul_result = ste.regs[mul_src1_reg].i64 * ste.regs[mul_src2_reg].i64; ste.regs[mul_dst_reg] = mul_result; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Multiply registers r%d * r%d = %lld", static_cast(mul_src1_reg), static_cast(mul_src2_reg), mul_result); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(mul_dst_reg), mul_result); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MUL instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MUL: r%d = r%d * r%d = %lld", static_cast(mul_dst_reg), + static_cast(mul_src1_reg), static_cast(mul_src2_reg), mul_result); break; } case DIV: { @@ -535,11 +474,8 @@ int VirtualCore::run() { const int64_t div_result = ste.regs[div_src1_reg].i64 / ste.regs[div_src2_reg].i64; ste.regs[div_dst_reg] = div_result; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Divide registers r%d / r%d = %lld", static_cast(div_src1_reg), static_cast(div_src2_reg), div_result); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(div_dst_reg), div_result); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed DIV instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("DIV: r%d = r%d / r%d = %lld", static_cast(div_dst_reg), + static_cast(div_src1_reg), static_cast(div_src2_reg), div_result); break; } case MOD: { @@ -557,11 +493,8 @@ int VirtualCore::run() { const int64_t mod_result = ste.regs[mod_src1_reg].i64 % ste.regs[mod_src2_reg].i64; ste.regs[mod_dst_reg] = mod_result; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Modulo registers r%d %% r%d = %lld", static_cast(mod_src1_reg), static_cast(mod_src2_reg), mod_result); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %lld", static_cast(mod_dst_reg), mod_result); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed MOD instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("MOD: r%d = r%d %% r%d = %lld", static_cast(mod_dst_reg), + static_cast(mod_src1_reg), static_cast(mod_src2_reg), mod_result); break; } case POW: { @@ -575,11 +508,8 @@ int VirtualCore::run() { const double pow_result = std::pow(ste.regs[pow_src1_reg].f64, ste.regs[pow_src2_reg].f64); ste.regs[pow_dst_reg] = pow_result; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Power registers r%d ^ r%d = %f", static_cast(pow_src1_reg), static_cast(pow_src2_reg), pow_result); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %f", static_cast(pow_dst_reg), pow_result); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed POW instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("POW: r%d = pow(r%d, r%d) = %f", static_cast(pow_dst_reg), + static_cast(pow_src1_reg), static_cast(pow_src2_reg), pow_result); break; } case FCALL: { @@ -588,10 +518,10 @@ int VirtualCore::run() { handle_error("Invalid jump address"); return 1; } - const auto args_count = operands[8]; // 传参数量 - ste.ret_addr_stack.push_back(ste.pc + 1); // 返回地址 - ste.pc = target_pc; // 跳转地址 - ste.stack_frames.push_back(std::make_unique()); //新建栈帧 + const auto args_count = operands[8]; + ste.ret_addr_stack.push_back(ste.pc + 1); + ste.pc = target_pc; + ste.stack_frames.push_back(std::make_unique()); ste.stack_frames.back()->locals.resize(args_count + 1); for (uint8_t i = 0; i != args_count; i++) { if (REG_COUNT_INDEX_MAX - i >= REG_COUNT) { @@ -600,11 +530,7 @@ int VirtualCore::run() { } ste.stack_frames.back()->locals[i] = ste.regs[REG_COUNT_INDEX_MAX - i]; } - DEBUG_LOG_FMT("[EXEC] | Operation: Call function at address %llu with %d arguments", target_pc, static_cast(args_count)); - DEBUG_LOG_FMT("[EXEC] | Result: PC set to %llu, return address pushed to stack, new stack frame created", target_pc); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed FCALL instruction, jumping to function address"); + DEBUG_LOG_FMT("FCALL: addr=%llu, args=%d", target_pc, static_cast(args_count)); break; } case FRET: { @@ -613,22 +539,14 @@ int VirtualCore::run() { return 1; } const size_t return_addr = ste.ret_addr_stack.back(); - ste.pc = return_addr; //返回地址 + ste.pc = return_addr; ste.ret_addr_stack.pop_back(); - ste.stack_frames.pop_back(); // 恢复栈帧 - DEBUG_LOG("[EXEC] | Operation: Return from function"); - DEBUG_LOG_FMT("[EXEC] | Result: PC set to return address %llu, stack frame popped", return_addr); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed FRET instruction, returning to caller"); + ste.stack_frames.pop_back(); + DEBUG_LOG_FMT("FRET: return to %llu", return_addr); break; } case HALT: { - DEBUG_LOG("[EXEC] | Operation: Terminate VM execution"); - DEBUG_LOG("[EXEC] | Result: VM execution terminated normally"); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed HALT instruction, VM stopped running"); + DEBUG_LOG("HALT"); DEBUG_SEPARATOR("VM EXECUTION END (SUCCESS)"); DEBUG_LEAVE_FUNC(); return 0; @@ -641,11 +559,6 @@ int VirtualCore::run() { } DEBUG_LOG_FMT("[LogInfo]: %s", static_cast(const_pool_top) + *reinterpret_cast(operands)); ste.pc++; - DEBUG_LOG("[EXEC] | Operation: Print debug log"); - DEBUG_LOG("[EXEC] | Result: Log printed to console"); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed DEBUG_LOG instruction, PC increased by 1, continuing to next instruction"); break; } case JMP: { @@ -656,11 +569,7 @@ int VirtualCore::run() { return 1; } ste.pc = target_pc; - DEBUG_LOG_FMT("[EXEC] | Operation: Jump to address %llu", target_pc); - DEBUG_LOG_FMT("[EXEC] | Result: Program counter set to %llu", target_pc); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed JMP instruction, PC set to target address, continuing execution"); + DEBUG_LOG_FMT("JMP: %llu", target_pc); break; } case CMP_GE: { @@ -675,11 +584,8 @@ int VirtualCore::run() { bool result = ste.regs[src1_reg].i64 >= ste.regs[src2_reg].i64; ste.regs[dst_reg].b = result; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Compare registers r%d >= r%d", static_cast(src1_reg), static_cast(src2_reg)); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d set to %s", static_cast(dst_reg), (result ? "true" : "false")); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed CMP_GE instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("CMP_GE: r%d = (r%d >= r%d) = %s", static_cast(dst_reg), + static_cast(src1_reg), static_cast(src2_reg), result ? "true" : "false"); break; } case CMP_LT: { @@ -693,11 +599,8 @@ int VirtualCore::run() { bool cmp_result = ste.regs[cmp_src1_reg].i64 < ste.regs[cmp_src2_reg].i64; ste.regs[cmp_dst_reg].b = cmp_result; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Compare registers r%d < r%d", static_cast(cmp_src1_reg), static_cast(cmp_src2_reg)); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d set to %s", static_cast(cmp_dst_reg), (cmp_result ? "true" : "false")); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed CMP_LT instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("CMP_LT: r%d = (r%d < r%d) = %s", static_cast(cmp_dst_reg), + static_cast(cmp_src1_reg), static_cast(cmp_src2_reg), cmp_result ? "true" : "false"); break; } case CMP_LE: { @@ -711,11 +614,8 @@ int VirtualCore::run() { bool cmp_result = ste.regs[cmp_src1_reg].i64 <= ste.regs[cmp_src2_reg].i64; ste.regs[cmp_dst_reg].b = cmp_result; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Compare registers r%d <= r%d", static_cast(cmp_src1_reg), static_cast(cmp_src2_reg)); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d set to %s", static_cast(cmp_dst_reg), (cmp_result ? "true" : "false")); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed CMP_LE instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("CMP_LE: r%d = (r%d <= r%d) = %s", static_cast(cmp_dst_reg), + static_cast(cmp_src1_reg), static_cast(cmp_src2_reg), cmp_result ? "true" : "false"); break; } case CMP_GT: { @@ -761,16 +661,11 @@ int VirtualCore::run() { bool condition = ste.regs[cond_reg].b; if (condition) { ste.pc = target_pc; - DEBUG_LOG_FMT("[EXEC] | Operation: Jump to address %llu if condition is true", target_pc); - DEBUG_LOG_FMT("[EXEC] | Result: Condition is true, PC set to %llu", target_pc); + DEBUG_LOG_FMT("IF_TRUE: r%d is true, jump to %llu", static_cast(cond_reg), target_pc); } else { ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Jump to address %llu if condition is true", target_pc); - DEBUG_LOG("[EXEC] | Result: Condition is false, PC increased by 1"); + DEBUG_LOG_FMT("IF_TRUE: r%d is false, continue", static_cast(cond_reg)); } - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG_FMT("[EXEC] | Because: Executed IF_TRUE instruction, %s", (condition ? "jumping to target address" : "continuing to next instruction")); break; } case IF_FALSE: { @@ -819,26 +714,13 @@ int VirtualCore::run() { } const uint8_t dst_reg = operands[0]; const uint8_t frame_idx = operands[1]; - - // 打印变量表信息 - DEBUG_LOG("[EXEC] | Variable table before LOCAL_GET:"); - for (size_t i = 0; i < ste.stack_frames[frame_idx]->locals.size(); i++) { - const auto& val = ste.stack_frames[frame_idx]->locals[i]; - DEBUG_LOG_FMT("[EXEC] | Index %zu: Type=%s, Value=%s", i, val.type_name(), val.to_string().c_str()); - } - - // 执行加载操作 + ste.regs[dst_reg] = ste.stack_frames[frame_idx]->locals[local_index]; ste.pc++; - - // 打印详细信息 - const auto& loaded_val = ste.stack_frames[frame_idx]->locals[local_index]; - DEBUG_LOG_FMT("[EXEC] | Operation: Load local variable at index %d from frame %d to register r%d", local_index, static_cast(frame_idx), static_cast(dst_reg)); - DEBUG_LOG_FMT("[EXEC] | Loaded value: Type=%s, Value=%s", loaded_val.type_name(), loaded_val.to_string().c_str()); - DEBUG_LOG_FMT("[EXEC] | Result: Register r%d value set to %s", static_cast(dst_reg), ste.regs[dst_reg].to_string().c_str()); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed LOCAL_GET instruction, PC increased by 1, continuing to next instruction"); + + DEBUG_LOG_FMT("LOCAL_GET: r%d = frame[%d].locals[%d] = %s", static_cast(dst_reg), + static_cast(frame_idx), local_index, + ste.regs[dst_reg].to_string().c_str()); break; } case LOCAL_SET: { @@ -862,11 +744,8 @@ int VirtualCore::run() { const uint8_t src_reg = operands[3]; ste.stack_frames[frame_idx]->locals[local_index] = ste.regs[src_reg]; ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Store register r%d value to local variable %d in frame %d", static_cast(src_reg), local_index, static_cast(frame_idx)); - DEBUG_LOG_FMT("[EXEC] | Result: frame[%d]->locals[%d] = %lld", static_cast(frame_idx), local_index, ste.regs[src_reg].i64); - DEBUG_LOG("[EXEC] | Current state:"); - DEBUG_REGS(ste.regs); - DEBUG_LOG("[EXEC] | Because: Executed LOCAL_SET instruction, PC increased by 1, continuing to next instruction"); + DEBUG_LOG_FMT("LOCAL_SET: frame[%d].locals[%d] = r%d (%s)", static_cast(frame_idx), + local_index, static_cast(src_reg), ste.regs[src_reg].to_string().c_str()); break; } case AND: { @@ -914,8 +793,7 @@ int VirtualCore::run() { const uint8_t src_reg = operands[0]; ste.stack.push_back(ste.regs[src_reg]); ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Push register r%d to stack", static_cast(src_reg)); - DEBUG_LOG_FMT("[EXEC] | Result: Stack size: %llu", ste.stack.size()); + DEBUG_LOG_FMT("PUSH: r%d, stack size=%llu", static_cast(src_reg), ste.stack.size()); break; } case CREATE_VECTOR: { @@ -925,48 +803,31 @@ int VirtualCore::run() { } const uint8_t dst_reg = operands[0]; const uint8_t count = operands[1]; - - // 检查栈中是否有足够的元素 + if (ste.stack.size() < count) { handle_error("Not enough elements on stack for CREATE_VECTOR"); return 1; } - - // 1. 计算需要的堆空间: 1个长度 + count个元素 - size_t slots = 1 + count; - - // 2. 在堆上分配内存 + size_t vec_addr = ste.heap.size(); - for (size_t i = 0; i < slots; i++) { - Value value; - value.type = ValueType::Null; - value.null = nullptr; - ste.heap.push_back(value); - } - - // 3. 存长度到第一个槽位 + ste.heap.resize(vec_addr + 1 + count); ste.heap[vec_addr].type = ValueType::Int; ste.heap[vec_addr].i64 = count; - - // 4. 从栈顶取元素(从最后压入的到最先压入的) + for (size_t i = 0; i < count; i++) { - // 从栈中取元素(栈顶是最后压入的元素) ste.heap[vec_addr + 1 + i] = ste.stack[ste.stack.size() - count + i]; } - - // 5. 调整栈(弹出元素) + for (size_t i = 0; i < count; i++) { ste.stack.pop_back(); } - - // 6. 返回向量地址到目标寄存器 + ste.regs[dst_reg].type = ValueType::Ptr; ste.regs[dst_reg].u64 = vec_addr; - + ste.pc++; - DEBUG_LOG_FMT("[EXEC] | Operation: Create vector with %d elements", static_cast(count)); - DEBUG_LOG_FMT("[EXEC] | Result: Vector at heap[%llu]", vec_addr); - DEBUG_LOG_FMT("[EXEC] | Stack size after: %llu", ste.stack.size()); + DEBUG_LOG_FMT("CREATE_VECTOR: r%d = vec[%d] at heap[%llu]", static_cast(dst_reg), + static_cast(count), vec_addr); break; } default: @@ -984,43 +845,26 @@ int VirtualCore::run() { void VirtualCore::insert_builtins() { DEBUG_LOG("insert builtins..."); - DEBUG_LOG("Before inserting builtins - Main stack frame locals:"); - for (size_t i = 0; i < ste.stack_frames[0]->locals.size(); i++) { - const auto& val = ste.stack_frames[0]->locals[i]; - DEBUG_LOG_FMT(" Index %zu: Type=%s, Value=%s", i, val.type_name(), val.to_string().c_str()); - } - const auto old_program = ste.program; const auto old_pc = ste.pc; - // 使用 builtins 命名空间中的内置常量 - size_t base_index = 64; // 从索引 64 开始 + size_t base_index = builtins::builtin_start; for (size_t i = 0; i < builtins::builtin_constants_count; i++) { const auto& constant = builtins::builtin_constants[i]; - - // 确保栈帧的 locals 数组足够大 + if (ste.stack_frames[0]->locals.size() <= base_index) { ste.stack_frames[0]->locals.resize(base_index + 1); } - - // 设置内置常量值 + ste.stack_frames[0]->locals[base_index] = constant.value; - - DEBUG_LOG_FMT("Added builtin constant %s = %s at index %zu", - constant.name, - constant.value.to_string().c_str(), + + DEBUG_LOG_FMT("builtin %s = %s at %zu", + constant.name, + constant.value.to_string().c_str(), base_index); base_index++; } - // 打印之后的变量表 - DEBUG_LOG("After inserting builtins - Main stack frame locals:"); - for (size_t i = 64; i < ste.stack_frames[0]->locals.size(); i++) { - const auto& val = ste.stack_frames[0]->locals[i]; - DEBUG_LOG_FMT(" Index %zu: Type=%s, Value=%s", i, val.type_name(), val.to_string().c_str()); - } - - // 恢复 ste 状态 ste.program = old_program; ste.pc = old_pc; } diff --git a/runtime/vm.hpp b/runtime/vm.hpp index a08ffa4..7e36a15 100644 --- a/runtime/vm.hpp +++ b/runtime/vm.hpp @@ -41,7 +41,7 @@ class LMVM_API VirtualCore { LMXState ste; // VM执行状态 // 从常量池获取值 - [[nodiscard]] Value* get_value_from_pool(size_t offest) const; + [[nodiscard]] Value* get_value_from_pool(size_t offset) const; // 检查寄存器索引是否有效 [[nodiscard]] bool is_valid_register(uint8_t reg) const; diff --git a/tools/lm/main.cpp b/tools/lm/main.cpp index 21ae4e2..b2015d7 100644 --- a/tools/lm/main.cpp +++ b/tools/lm/main.cpp @@ -18,9 +18,9 @@ std::filesystem::path get_executable_path() { #ifdef _WIN32 char buffer[MAX_PATH]; - DWORD length = GetModuleFileNameA(nullptr, buffer, MAX_PATH); + const DWORD length = GetModuleFileNameA(nullptr, buffer, MAX_PATH); if (length > 0) { - return std::filesystem::path(buffer); + return {buffer}; } #elif defined(__APPLE__) From c537a482d4ca5d2101f5fbe8bf3cf656373d1467 Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Wed, 25 Mar 2026 21:35:08 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/common.hpp | 4 +++- compiler/parser.cpp | 3 ++- runtime/builtins.cpp | 40 ++++++++++++++++++------------------ runtime/libloader.cpp | 6 +++--- runtime/loader.cpp | 4 ++-- tools/lm/common/file_run.cpp | 3 ++- 6 files changed, 32 insertions(+), 28 deletions(-) diff --git a/compiler/common.hpp b/compiler/common.hpp index cc942df..d36eda4 100644 --- a/compiler/common.hpp +++ b/compiler/common.hpp @@ -12,6 +12,8 @@ #include #include +#include "../include/error.hpp" + #include "parser.hpp" namespace lmx { @@ -23,7 +25,7 @@ namespace lmx { inline std::string read_file(const std::string& path) { std::ifstream file(path); if (!file.is_open()) { - std::cerr << "Failed to open file " << path << std::endl; + LM_ERROR("Failed to open file " + path); return {}; } return {std::istreambuf_iterator{file}, std::istreambuf_iterator{}}; diff --git a/compiler/parser.cpp b/compiler/parser.cpp index 898c737..4a14b03 100644 --- a/compiler/parser.cpp +++ b/compiler/parser.cpp @@ -3,6 +3,7 @@ // #include "parser.hpp" +#include "../include/error.hpp" namespace lmx { @@ -68,7 +69,7 @@ void Parser::check_eof() { } void Parser::error(const std::string& msg) { has_err = true; - std::cerr << "Error: " << msg << " at " << cur().line << ":" << cur().col << std::endl; + LM_ERROR(msg + " at " + std::to_string(cur().line) + ":" + std::to_string(cur().col)); } std::shared_ptr Parser::parse_block() { if (!match(TokenType::LBRACE)) error("expected '{'"); diff --git a/runtime/builtins.cpp b/runtime/builtins.cpp index 5f2022b..41db5b4 100644 --- a/runtime/builtins.cpp +++ b/runtime/builtins.cpp @@ -3,27 +3,27 @@ namespace lmx::runtime::builtins { const BuiltinConstant builtin_constants[] = { // 物理常量 - {"EARTH_GRAVITY", 9.80665}, - {"MOON_GRAVITY", 1.625}, - {"MARS_GRAVITY", 3.72076}, - {"WATER_DENSITY", 1000.0}, - {"STANDARD_PRESSURE", 101325.0}, - {"STANDARD_TEMPERATURE", 273.15}, - {"AIR_DENSITY", 1.225}, - {"C", 2.99792458e8}, - {"G", 6.67430e-11}, - {"H", 6.62607015e-34}, - {"KB", 1.380649e-23}, - {"EPSILON_0", 8.8541878128e-12}, - {"MU_0", 1.25663706212e-6}, + {"EARTH_GRAVITY", Value(9.80665)}, + {"MOON_GRAVITY", Value(1.625)}, + {"MARS_GRAVITY", Value(3.72076)}, + {"WATER_DENSITY", Value(1000.0)}, + {"STANDARD_PRESSURE", Value(101325.0)}, + {"STANDARD_TEMPERATURE", Value(273.15)}, + {"AIR_DENSITY", Value(1.225)}, + {"C", Value(2.99792458e8)}, + {"G", Value(6.67430e-11)}, + {"H", Value(6.62607015e-34)}, + {"KB", Value(1.380649e-23)}, + {"EPSILON_0", Value(8.8541878128e-12)}, + {"MU_0", Value(1.25663706212e-6)}, // 化学常量 - {"AVOGADRO", 6.02214076e23}, - {"R", 8.314462618}, - {"FARADAY", 9.648533212e4}, - {"AMU", 1.66053906660e-27}, - {"MOLAR_VOLUME_IDEAL", 0.024465}, - {"ROOM_PRESSURE", 1.0e5}, - {"ROOM_TEMPERATURE", 297.15} + {"AVOGADRO", Value(6.02214076e23)}, + {"R", Value(8.314462618)}, + {"FARADAY", Value(9.648533212e4)}, + {"AMU", Value(1.66053906660e-27)}, + {"MOLAR_VOLUME_IDEAL", Value(0.024465)}, + {"ROOM_PRESSURE", Value(1.0e5)}, + {"ROOM_TEMPERATURE", Value(297.15)} }; size_t builtin_constants_count = std::size(builtin_constants); size_t get_builtin_constant_index(const std::string& name) { diff --git a/runtime/libloader.cpp b/runtime/libloader.cpp index 5588a45..93808c0 100644 --- a/runtime/libloader.cpp +++ b/runtime/libloader.cpp @@ -79,7 +79,7 @@ DynLib::DynLib(const std::string& name) { handle = dlopen(this->name.c_str(), RTLD_LAZY | RTLD_GLOBAL); #endif if (!handle) { - std::cerr << "error: cannot load lib: '" << this->name << '\'' << std::endl; + LM_ERROR("error: cannot load lib: '" + this->name + '\''); exit(1); } } @@ -94,7 +94,7 @@ void DynLib::set_func(const char* n, std::vector args_type, CBasicT dlsym(handle, n); #endif if (!fp) { - std::cerr << "the dynamic symbol '" << n << "' does not exist" << std::endl; + LM_ERROR("the dynamic symbol '" + std::string(n) + "' does not exist"); exit(1); } if (!funcs.contains(n)) { @@ -112,7 +112,7 @@ bool DynLib::contain(const char* n) const { const DynFunc* DynLib::find(const char* n) const { const auto it = funcs.find(n); if (it == funcs.end()) { - std::cerr << "the func `" << n << "` is not found in lib `" << name << "`" << std::endl; + LM_ERROR("the func `" + std::string(n) + "` is not found in lib `" + name + "`"); return nullptr; } return &it->second; diff --git a/runtime/loader.cpp b/runtime/loader.cpp index 6d19283..fb6ffcf 100644 --- a/runtime/loader.cpp +++ b/runtime/loader.cpp @@ -7,6 +7,7 @@ #include #include +#include "error.hpp" #include "lmx_export.hpp" #include "opcode.hpp" @@ -33,12 +34,11 @@ bool BinaryLoader::check_head() { void BinaryLoader::load() { if (!check_head()) { - std::cerr << "Loader: binary file format bad" << std::endl; + LM_ERROR("Loader: binary file format bad"); exit(-1); } while (true) { Op op; - //std::cout << (int)op.op << std::endl; op.op = static_cast(file.get()); file.read(reinterpret_cast(op.operands), opcode_len(op.op)); ops.push_back(op); diff --git a/tools/lm/common/file_run.cpp b/tools/lm/common/file_run.cpp index a0537a6..a120bb9 100644 --- a/tools/lm/common/file_run.cpp +++ b/tools/lm/common/file_run.cpp @@ -8,6 +8,7 @@ #include "../compiler/parser.hpp" #include "../compiler/generator/generator.hpp" #include "../runtime/vm.hpp" +#include "../include/error.hpp" int binary_run(std::fstream&& file) { lmx::runtime::BinaryLoader loader{std::move(file)}; @@ -21,7 +22,7 @@ int file_run(const std::string& file_name) { uint32_t magic = 0; std::fstream file(file_name); if (!file.is_open()) { - std::cerr << "File not found: " << file_name << std::endl; + LM_ERROR("File not found: " + file_name); file.close(); return -1; } From 50c5a651b5c62142df470e58a266a26a7778bafb Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Wed, 25 Mar 2026 21:41:53 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=9C=AA=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/error.hpp | 31 ++++++++++++++++++++++++++++++ runtime/error.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 include/error.hpp create mode 100644 runtime/error.cpp diff --git a/include/error.hpp b/include/error.hpp new file mode 100644 index 0000000..d222262 --- /dev/null +++ b/include/error.hpp @@ -0,0 +1,31 @@ +// +// 错误报告系统 +// 提供标准的错误报告接口 +// + +#pragma once + +#include +#include + +#include "lmx_export.hpp" + +namespace lmx { + +// 错误类型枚举 +enum class ErrorType { + ERR +}; + +// 错误报告函数 +// 参数: +// type: 错误类型 +// message: 错误消息 +inline void error_reporter(const ErrorType type, const std::string& message) { + if (type == ErrorType::ERR) std::cerr << "Error: " << message << std::endl; +} + +// 便捷宏 +#define LM_ERROR(msg) error_reporter(lmx::ErrorType::ERR, msg) + +} // lmx diff --git a/runtime/error.cpp b/runtime/error.cpp new file mode 100644 index 0000000..9173844 --- /dev/null +++ b/runtime/error.cpp @@ -0,0 +1,48 @@ +// +// 错误报告系统实现 +// + +#include "../include/error.hpp" +#include +#include + +namespace lmx { + +// 错误报告函数实现 +void error_reporter(ErrorType type, const std::string& message, + const std::source_location& loc) { + // 根据错误类型选择前缀和颜色 + std::string prefix; + std::string color; + std::string reset_color = "\033[0m"; + + switch (type) { + case ErrorType::ERR: + prefix = "[ERROR]"; + color = "\033[31m"; // 红色 + break; + case ErrorType::WARNING: + prefix = "[WARNING]"; + color = "\033[33m"; // 黄色 + break; + case ErrorType::DEBUG: + prefix = "[DEBUG]"; + color = "\033[36m"; // 青色 + break; + case ErrorType::INFO: + prefix = "[INFO]"; + color = "\033[32m"; // 绿色 + break; + default: + prefix = "[UNKNOWN]"; + color = "\033[37m"; // 白色 + break; + } + + // 输出错误信息 + std::cerr << color << prefix << " " + << loc.file_name() << ":" << loc.line() << " - " + << message << reset_color << std::endl; +} + +} // lmx From 64df25c77adb138ed989e4be78b3307d24f4d113 Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Fri, 27 Mar 2026 18:07:53 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E7=BE=8E=E5=8C=96=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E5=88=9D=E6=AD=A5=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/common.hpp | 2 +- compiler/parser.cpp | 211 ++++++++++++++++++++--------------- compiler/parser.hpp | 3 +- include/error.hpp | 22 ++-- tools/lm/common/file_run.cpp | 4 +- tools/lm/common/repl.cpp | 2 +- 6 files changed, 141 insertions(+), 103 deletions(-) diff --git a/compiler/common.hpp b/compiler/common.hpp index d36eda4..517aab7 100644 --- a/compiler/common.hpp +++ b/compiler/common.hpp @@ -36,7 +36,7 @@ namespace lmx { Lexer lexer(code); auto tks = lexer.tokenize(code); - Parser parser(tks); + Parser parser(tks, code); if (auto node = parser.parse_program(); node && !parser.error()) return node; return nullptr; } diff --git a/compiler/parser.cpp b/compiler/parser.cpp index 4a14b03..fff89b7 100644 --- a/compiler/parser.cpp +++ b/compiler/parser.cpp @@ -3,6 +3,8 @@ // #include "parser.hpp" + +#include "debug.hpp" #include "../include/error.hpp" namespace lmx { @@ -56,20 +58,35 @@ bool Parser::match(TokenType t) const { } bool Parser::is_eof() const { - return pos >= tokens.size(); + DEBUG_LOG(ITIS(pos, std::to_string) << ", " << ITIS(tokens.size(), std::to_string)); + return pos >= tokens.size() - 1; } void Parser::check_eof() { while (!is_eof() && match(TokenType::END_OF_FILE)) { advance(); } - //if (!is_eof()) { - // error("Expected end of file"); - //} } void Parser::error(const std::string& msg) { has_err = true; - LM_ERROR(msg + " at " + std::to_string(cur().line) + ":" + std::to_string(cur().col)); + const auto this_line = [&] { + std::istringstream ss(code); + std::string l; + for (size_t i = 0; i < cur().col; i ++) + std::getline(ss, l); return l; + }(); + DEBUG_LOG(ITIS(code, ) << ", " << ITIS(this_line, )); + LM_ERROR(msg + + "\nat line " + + std::to_string(cur().line) + + ", column " + + std::to_string(cur().col) + + "\n>>> " + + this_line + + "\n" + + std::string(cur().col + 3, ' ') + + "^" + ); } std::shared_ptr Parser::parse_block() { if (!match(TokenType::LBRACE)) error("expected '{'"); @@ -118,10 +135,18 @@ std::shared_ptr Parser::parse_logical_or() { std::shared_ptr Parser::parse_relational() { std::shared_ptr node = expr(); while (match(TokenType::EQ) || match(TokenType::LT) || match(TokenType::GT) || - match(TokenType::LE) || match(TokenType::GE) || match(TokenType::NE) ) { + match(TokenType::LE) || match(TokenType::GE) || match(TokenType::NE)) { auto op = cur().text; + DEBUG_LOG(ITIS(op, )); advance(); - node = std::make_shared(node, parse_expr(), op); + DEBUG_LOG(ITIS(cur().text, )); + if (is_eof()) { + throw ParserError("Not expected: eof"); + } + DEBUG_LOG("not eof, it's: " + cur().text + "type: " + std::to_string(static_cast(cur().type)) + + ", eof type: " + std::to_string(static_cast(TokenType::END_OF_FILE))); + auto a = parse_expr(); + node = std::make_shared(node, a, op); } return node; } @@ -214,87 +239,91 @@ std::shared_ptr Parser::parse() { static bool in_func = false; static bool in_loop = false; std::shared_ptr node; - re_parse: - switch (cur().type) { - case TokenType::COMMENT: advance(); goto re_parse; - case TokenType::KW_LET: { - advance(); - if (!match(TokenType::IDENTIFIER)) error("expected identifier"); - auto name = cur().text; - advance(); - if (!match(TokenType::ASSIGN)) error("expected assignment"); - advance(); - node = std::make_shared(name, parse_expr(), false); - break; - } - case TokenType::KW_FUNC: { - advance(); - in_func = true; - node = parse_funcdecl(true); - in_func = false; - break; - } - case TokenType::KW_RETURN: { - if (!in_func) error("expected 'return'"); + try { + re_parse: + switch (cur().type) { + case TokenType::COMMENT: advance(); goto re_parse; + case TokenType::KW_LET: { + advance(); + if (!match(TokenType::IDENTIFIER)) error("expected identifier"); + auto name = cur().text; + advance(); + if (!match(TokenType::ASSIGN)) error("expected assignment"); + advance(); + node = std::make_shared(name, parse_expr(), false); + break; + } + case TokenType::KW_FUNC: { + advance(); + in_func = true; + node = parse_funcdecl(true); + in_func = false; + break; + } + case TokenType::KW_RETURN: { + if (!in_func) error("expected 'return'"); - auto line = cur().line; - advance(); - if (cur().line > line) { - node = std::make_shared(nullptr); - } else { - auto e = parse_expr(); + auto line = cur().line; + advance(); + if (cur().line > line) { + node = std::make_shared(nullptr); + } else { + auto e = parse_expr(); - node = std::make_shared(e); - } - break; - } - case TokenType::KW_LOOP: { - advance(); - std::shared_ptr cond = nullptr; - if (!match(TokenType::LBRACE)) - cond = parse_expr(); - in_loop = true; - auto block = parse_block(); - node = std::make_shared(cond, block); - in_loop = false; - break; - } - case TokenType::KW_BREAK: { - advance(); - if (!in_loop) error("expected 'break', but not in loop"); - node = std::make_shared(); - break; - } - case TokenType::KW_CONTINUE: { - advance(); - if (!in_loop) error("expected 'continue', but not in loop"); - node = std::make_shared(); - break; - } - case TokenType::KW_IF: { - advance(); - node = parse_if(); - break; - } - case TokenType::KW_MODULE: { - advance(); - node = parse_module(); - break; - } - case TokenType::KW_USE: { - advance(); - auto path = parse_string(); - break; - } - default: { - if (match(TokenType::IDENTIFIER) && peek_match(TokenType::ASSIGN)) { - auto name = cur().text; - advance(); - advance(); - node = std::make_shared(name, parse_expr()); - } else node = parse_expr(); - break; - } + node = std::make_shared(e); + } + break; + } + case TokenType::KW_LOOP: { + advance(); + std::shared_ptr cond = nullptr; + if (!match(TokenType::LBRACE)) + cond = parse_expr(); + in_loop = true; + auto block = parse_block(); + node = std::make_shared(cond, block); + in_loop = false; + break; + } + case TokenType::KW_BREAK: { + advance(); + if (!in_loop) error("expected 'break', but not in loop"); + node = std::make_shared(); + break; + } + case TokenType::KW_CONTINUE: { + advance(); + if (!in_loop) error("expected 'continue', but not in loop"); + node = std::make_shared(); + break; + } + case TokenType::KW_IF: { + advance(); + node = parse_if(); + break; + } + case TokenType::KW_MODULE: { + advance(); + node = parse_module(); + break; + } + case TokenType::KW_USE: { + advance(); + auto path = parse_string(); + break; + } + default: { + if (match(TokenType::IDENTIFIER) && peek_match(TokenType::ASSIGN)) { + auto name = cur().text; + advance(); + advance(); + node = std::make_shared(name, parse_expr()); + } else node = parse_expr(); + break; + } + } + } catch (ParserError &e) { + error("ParserError: " + std::string(e.what())); } return node; } @@ -453,10 +482,16 @@ std::shared_ptr Parser::term() { return node; } std::shared_ptr Parser::parse_program() { + DEBUG_ENTER_FUNC(); std::vector> stmts; - while (!match(TokenType::RBRACE) && !is_eof()) { - if (const auto stmt = parse()) stmts.push_back(stmt); + try { + while (!is_eof()) { + if (const auto stmt = parse()) stmts.push_back(stmt); + } + } catch (ParserError& e) { + error("ParserError:" + std::string(e.what())); } + DEBUG_LEAVE_FUNC(); return std::make_shared(stmts); } diff --git a/compiler/parser.hpp b/compiler/parser.hpp index ce65bcb..de6b2e4 100644 --- a/compiler/parser.hpp +++ b/compiler/parser.hpp @@ -16,6 +16,7 @@ class LMC_API Parser { bool in_module{false}; bool has_err{false}; std::vector& tokens; + std::string code; size_t pos{0}; void parse_args(std::vector> &args); @@ -44,7 +45,7 @@ class LMC_API Parser { std::shared_ptr parse_funcdecl(bool has_block); public: - explicit Parser(std::vector& tokens): tokens(tokens) {} + explicit Parser(std::vector& tokens, const std::string& code): tokens(tokens), code(code) {} std::shared_ptr parse(); std::shared_ptr parse_module(); diff --git a/include/error.hpp b/include/error.hpp index d222262..54ef249 100644 --- a/include/error.hpp +++ b/include/error.hpp @@ -1,14 +1,7 @@ -// -// 错误报告系统 -// 提供标准的错误报告接口 -// - #pragma once #include -#include - -#include "lmx_export.hpp" +#include namespace lmx { @@ -25,7 +18,16 @@ inline void error_reporter(const ErrorType type, const std::string& message) { if (type == ErrorType::ERR) std::cerr << "Error: " << message << std::endl; } -// 便捷宏 -#define LM_ERROR(msg) error_reporter(lmx::ErrorType::ERR, msg) +inline void LM_ERROR(const std::string& msg) { + error_reporter(ErrorType::ERR, msg); +} + +class ParserError final : public std::runtime_error { +public: + explicit ParserError( + const std::string& msg + ): std::runtime_error(msg) {} +}; +#define ITIS(x, convert) (std::string(#x " = <") + convert(x) + std::string(">")) } // lmx diff --git a/tools/lm/common/file_run.cpp b/tools/lm/common/file_run.cpp index a120bb9..bfb7bb1 100644 --- a/tools/lm/common/file_run.cpp +++ b/tools/lm/common/file_run.cpp @@ -22,7 +22,7 @@ int file_run(const std::string& file_name) { uint32_t magic = 0; std::fstream file(file_name); if (!file.is_open()) { - LM_ERROR("File not found: " + file_name); + lmx::LM_ERROR("File not found: " + file_name); file.close(); return -1; } @@ -32,7 +32,7 @@ int file_run(const std::string& file_name) { auto src = std::string(std::istreambuf_iterator(file), std::istreambuf_iterator()); lmx::Lexer lexer(src); auto ts = lexer.tokenize(src); - lmx::Parser parser(ts); + lmx::Parser parser(ts, src); lmx::Generator gener; std::shared_ptr node = parser.parse_program(); if (!node || parser.error()) return -1; diff --git a/tools/lm/common/repl.cpp b/tools/lm/common/repl.cpp index 678f074..b5bf507 100644 --- a/tools/lm/common/repl.cpp +++ b/tools/lm/common/repl.cpp @@ -186,7 +186,7 @@ int run_repl() { DEBUG_TOKEN_LIST(tks); // Parse and display AST - lmx::Parser parser(tks); + lmx::Parser parser(tks, expr); auto node = parser.parse(); if (!node || parser.error()) continue; From 8f55c7366fea72e7de4d838e333d43d7649cb1a5 Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Fri, 27 Mar 2026 18:46:24 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E8=BF=9B=E4=B8=80=E6=AD=A5=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/common.hpp | 2 +- compiler/parser.cpp | 17 ++++++++++--- compiler/parser.hpp | 7 +++++- include/error.hpp | 1 - runtime/error.cpp | 48 ------------------------------------ tools/lm/common/file_run.cpp | 6 ++--- tools/lm/common/repl.cpp | 4 +-- 7 files changed, 24 insertions(+), 61 deletions(-) delete mode 100644 runtime/error.cpp diff --git a/compiler/common.hpp b/compiler/common.hpp index 517aab7..69a6285 100644 --- a/compiler/common.hpp +++ b/compiler/common.hpp @@ -36,7 +36,7 @@ namespace lmx { Lexer lexer(code); auto tks = lexer.tokenize(code); - Parser parser(tks, code); + Parser parser(tks, code, path); if (auto node = parser.parse_program(); node && !parser.error()) return node; return nullptr; } diff --git a/compiler/parser.cpp b/compiler/parser.cpp index fff89b7..750a1f9 100644 --- a/compiler/parser.cpp +++ b/compiler/parser.cpp @@ -67,7 +67,8 @@ void Parser::check_eof() { advance(); } } -void Parser::error(const std::string& msg) { + +void Parser::print_error(const std::string& msg) { has_err = true; const auto this_line = [&] { std::istringstream ss(code); @@ -81,6 +82,8 @@ void Parser::error(const std::string& msg) { + std::to_string(cur().line) + ", column " + std::to_string(cur().col) + + ", in " + + src + "\n>>> " + this_line + "\n" @@ -99,6 +102,11 @@ std::shared_ptr Parser::parse_block() { advance(); return std::make_shared(stmts); } + +void Parser::error(const std::string& msg) { + throw ParserError(msg); +} + std::shared_ptr Parser::parse_expr() { std::shared_ptr node = parse_logical_and(); std::shared_ptr type; @@ -141,7 +149,7 @@ std::shared_ptr Parser::parse_relational() { advance(); DEBUG_LOG(ITIS(cur().text, )); if (is_eof()) { - throw ParserError("Not expected: eof"); + error("Not expected: eof"); } DEBUG_LOG("not eof, it's: " + cur().text + "type: " + std::to_string(static_cast(cur().type)) + ", eof type: " + std::to_string(static_cast(TokenType::END_OF_FILE))); @@ -323,7 +331,7 @@ std::shared_ptr Parser::parse() { } } } catch (ParserError &e) { - error("ParserError: " + std::string(e.what())); + print_error("ParserError: " + std::string(e.what())); } return node; } @@ -477,6 +485,7 @@ std::shared_ptr Parser::term() { while (match(TokenType::OPER_MUL) || match(TokenType::OPER_DIV) || match(TokenType::OPER_MOD) || match(TokenType::OPER_POW)) { auto op = cur().text; advance(); + if (is_eof()) error("Unexpected eof"); node = std::make_shared(node, factor(), op); } return node; @@ -489,7 +498,7 @@ std::shared_ptr Parser::parse_program() { if (const auto stmt = parse()) stmts.push_back(stmt); } } catch (ParserError& e) { - error("ParserError:" + std::string(e.what())); + print_error("ParserError:" + std::string(e.what())); } DEBUG_LEAVE_FUNC(); return std::make_shared(stmts); diff --git a/compiler/parser.hpp b/compiler/parser.hpp index de6b2e4..edb5659 100644 --- a/compiler/parser.hpp +++ b/compiler/parser.hpp @@ -5,6 +5,7 @@ #pragma once #include #include +#include #include "../include/lmx_export.hpp" #include "lexer.hpp" @@ -17,6 +18,7 @@ class LMC_API Parser { bool has_err{false}; std::vector& tokens; std::string code; + std::string src; size_t pos{0}; void parse_args(std::vector> &args); @@ -32,6 +34,9 @@ class LMC_API Parser { bool peek_match(TokenType type) const; void check_eof(); + + void print_error(const std::string &msg); + void error(const std::string& msg); std::shared_ptr parse_block(); @@ -45,7 +50,7 @@ class LMC_API Parser { std::shared_ptr parse_funcdecl(bool has_block); public: - explicit Parser(std::vector& tokens, const std::string& code): tokens(tokens), code(code) {} + explicit Parser(std::vector& tokens, std::string code, std::string src = ""): tokens(tokens), code(std::move(code)), src(std::move(src)) {} std::shared_ptr parse(); std::shared_ptr parse_module(); diff --git a/include/error.hpp b/include/error.hpp index 54ef249..1def5e2 100644 --- a/include/error.hpp +++ b/include/error.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include namespace lmx { diff --git a/runtime/error.cpp b/runtime/error.cpp deleted file mode 100644 index 9173844..0000000 --- a/runtime/error.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// -// 错误报告系统实现 -// - -#include "../include/error.hpp" -#include -#include - -namespace lmx { - -// 错误报告函数实现 -void error_reporter(ErrorType type, const std::string& message, - const std::source_location& loc) { - // 根据错误类型选择前缀和颜色 - std::string prefix; - std::string color; - std::string reset_color = "\033[0m"; - - switch (type) { - case ErrorType::ERR: - prefix = "[ERROR]"; - color = "\033[31m"; // 红色 - break; - case ErrorType::WARNING: - prefix = "[WARNING]"; - color = "\033[33m"; // 黄色 - break; - case ErrorType::DEBUG: - prefix = "[DEBUG]"; - color = "\033[36m"; // 青色 - break; - case ErrorType::INFO: - prefix = "[INFO]"; - color = "\033[32m"; // 绿色 - break; - default: - prefix = "[UNKNOWN]"; - color = "\033[37m"; // 白色 - break; - } - - // 输出错误信息 - std::cerr << color << prefix << " " - << loc.file_name() << ":" << loc.line() << " - " - << message << reset_color << std::endl; -} - -} // lmx diff --git a/tools/lm/common/file_run.cpp b/tools/lm/common/file_run.cpp index bfb7bb1..34195a6 100644 --- a/tools/lm/common/file_run.cpp +++ b/tools/lm/common/file_run.cpp @@ -26,13 +26,13 @@ int file_run(const std::string& file_name) { file.close(); return -1; } - file.read((char*)&magic, sizeof(magic)); + file.read(reinterpret_cast(&magic), sizeof(magic)); if (magic == LMX_MAGIC_NUM) return binary_run(std::move(file)); file.seekg(0, std::ios::beg); auto src = std::string(std::istreambuf_iterator(file), std::istreambuf_iterator()); lmx::Lexer lexer(src); auto ts = lexer.tokenize(src); - lmx::Parser parser(ts, src); + lmx::Parser parser(ts, src, file_name); lmx::Generator gener; std::shared_ptr node = parser.parse_program(); if (!node || parser.error()) return -1; @@ -40,8 +40,6 @@ int file_run(const std::string& file_name) { if (lmx::Generator::node_has_error)return -1; gener.ops.emplace_back(lmx::runtime::Opcode::HALT); gener.write_binary_file(file_name); - //gener.print_ops(); - //return 0; lmx::runtime::VirtualCore vm; vm.set_program(&gener.ops); vm.set_constant(gener.constant_pool.data()); diff --git a/tools/lm/common/repl.cpp b/tools/lm/common/repl.cpp index b5bf507..8b8129b 100644 --- a/tools/lm/common/repl.cpp +++ b/tools/lm/common/repl.cpp @@ -169,7 +169,7 @@ int run_repl() { lmx::runtime::VirtualCore core; core.set_program(&generator.ops); - const std::string prompt = ">>> "; + const std::string prompt = std::string(COLOR_MAGENTA) + ">>> " + COLOR_RESET; while (true) { std::cout << prompt << std::flush; if (!std::getline(std::cin, expr)) break; @@ -186,7 +186,7 @@ int run_repl() { DEBUG_TOKEN_LIST(tks); // Parse and display AST - lmx::Parser parser(tks, expr); + lmx::Parser parser(tks, expr, ""); auto node = parser.parse(); if (!node || parser.error()) continue; From b17c8bab02a196c30e4775a403789fe33a75f71d Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Sun, 29 Mar 2026 12:23:23 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8DVM=E7=9A=84=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/generator/emit.cpp | 2 + compiler/generator/generator.cpp | 12 +- compiler/generator/generator.hpp | 16 +- runtime/loader.hpp | 2 +- runtime/vm.cpp | 252 +++++++++++++++++++------------ runtime/vm.hpp | 11 +- tools/lm/common/file_run.cpp | 9 +- 7 files changed, 198 insertions(+), 106 deletions(-) diff --git a/compiler/generator/emit.cpp b/compiler/generator/emit.cpp index cf392a7..b9405e2 100644 --- a/compiler/generator/emit.cpp +++ b/compiler/generator/emit.cpp @@ -7,6 +7,8 @@ #include #include +#include "debug.hpp" + namespace lmx { LMXOpcodeEmitter::Ret_Type LMXOpcodeEmitter::ret_type = None; template diff --git a/compiler/generator/generator.cpp b/compiler/generator/generator.cpp index 831ec45..b586d19 100644 --- a/compiler/generator/generator.cpp +++ b/compiler/generator/generator.cpp @@ -71,7 +71,7 @@ Generator::Generator() { DEBUG_LOG_FMT(" %s: index=%d, mutable=%s", name.c_str(), info.second, info.first ? "true" : "false"); } } -void Generator::write(runtime::Op& op) { +void Generator::write(const runtime::Op& op) { ops.push_back(op); } @@ -84,7 +84,9 @@ std::vector &Generator::get_ops() { } size_t Generator::gen(std::shared_ptr &n) { + DEBUG_LOG("Gen: " << cur.back()->to_string()); switch (n->kind) { + DEBUG_LOG(ITIS(n->kind, std::to_string)); case Program: return gen_program(n); case Binary: return gen_binary(n); case Unary: return gen_unary(n); @@ -95,7 +97,7 @@ size_t Generator::gen(std::shared_ptr &n) { case NumLiteral: return gen_num(n); case StringLiteral: return gen_string(n); case BoolLiteral: return gen_bool(n); - case VectorLiteral: return this->gen_vector(n); + case VectorLiteral: return gen_vector(n); case BlockStmt: return gen_block(n); case IfStmt: return gen_if(n); case FuncDecl: return gen_function(n); @@ -253,9 +255,15 @@ size_t Generator::gen_binary(std::shared_ptr& n) { expr_release = true; return expr_ret_reg; } + DEBUG_LOG("Try to gen node->right"); volatile size_t rr = gen(node->right); + if (rr == -1) { + regs.free(lr); + return -1; + } tmp = regs.alloc(); LMXOpcodeEmitter::emit_mov_rr(ops, tmp, rr); + DEBUG_LOG(ITIS(tmp, std::to_string) << ", " << ITIS(rr, std::to_string)); if (expr_release) regs.free(rr); rr = tmp; expr_ret_reg = regs.alloc(); diff --git a/compiler/generator/generator.hpp b/compiler/generator/generator.hpp index cc0bc06..9f3db8f 100644 --- a/compiler/generator/generator.hpp +++ b/compiler/generator/generator.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include #include @@ -34,7 +35,7 @@ class LMC_API Allocator { size_t alloc(); size_t alloc(size_t i); void free(size_t i); - bool is_free(size_t i) const; + [[nodiscard]] bool is_free(size_t i) const; void print_regs() const { std::string regs_str = "Allocated registers: "; for (size_t i = 0; i < REG_COUNT; i++) { @@ -124,9 +125,20 @@ class LMC_API Generator { } else error("redefined var: `" + n + "`"); return local_count; } + uint16_t new_var(const std::string& n, bool is_mut) { return new_var(n, is_mut, ++local_count); } + + std::string to_string() const { + auto result = std::format("CallingFrame {}(\n local_count: {}\n", name, local_count); + for (auto [var_name, pack] : locals) { + auto& [mut, here] = pack; + result.append(std::format("\t{}: {}, at {}\n", var_name, (mut ? "mutable" : "immutable"), here)); + } + result.append(")"); + return result; + } }; std::vector> cur; /* ====================================== * @@ -197,7 +209,7 @@ class LMC_API Generator { ~Generator() = default; std::vector ops; - void write(runtime::Op& op); + void write(const runtime::Op& op); std::vector &get_ops(); std::vector constant_pool; diff --git a/runtime/loader.hpp b/runtime/loader.hpp index 440faa0..ac86903 100644 --- a/runtime/loader.hpp +++ b/runtime/loader.hpp @@ -10,7 +10,7 @@ struct Op; class LMVM_API BinaryLoader { std::vector ops; std::vector data; - std::remove_reference::type file; + std::remove_reference_t file; struct Header { uint32_t magic, version; }; diff --git a/runtime/vm.cpp b/runtime/vm.cpp index 8fd78e2..cbad74d 100644 --- a/runtime/vm.cpp +++ b/runtime/vm.cpp @@ -27,11 +27,12 @@ Value* VirtualCore::get_value_from_pool(const size_t offset) const { return static_cast(const_pool_top) + offset; } -bool VirtualCore::is_valid_register(uint8_t reg) const { +bool VirtualCore::is_valid_register(const uint8_t reg) { + DEBUG_LOG(ITIS(reg, std::to_string) << ", " << ITIS(REG_COUNT, std::to_string)); return reg < REG_COUNT; } -bool VirtualCore::validate_registers(const uint8_t* regs, size_t count) const { +bool VirtualCore::validate_registers(const uint8_t* regs, size_t count) { for (size_t i = 0; i < count; i++) { if (!is_valid_register(regs[i])) { return false; @@ -40,26 +41,26 @@ bool VirtualCore::validate_registers(const uint8_t* regs, size_t count) const { return true; } -bool VirtualCore::validate_jump_address(uint64_t address) const { +bool VirtualCore::validate_jump_address(const uint64_t address) const { return address < ste.program->size(); } -bool VirtualCore::validate_stack_frame(size_t frame_index, size_t local_index) const { +bool VirtualCore::validate_stack_frame(const size_t frame_index, const size_t local_index) const { if (frame_index >= ste.stack_frames.size()) { return false; } return local_index < ste.stack_frames[frame_index]->locals.size(); } -const char* VirtualCore::get_constant_string(uint64_t offset) const { +const char* VirtualCore::get_constant_string(const uint64_t offset) const { if (const_pool_top == nullptr) { return nullptr; } return static_cast(const_pool_top) + offset; } -void VirtualCore::handle_error(const char* error_message) const { - fprintf(stderr, "[Error]: %s\n", error_message); +void VirtualCore::handle_error(const char* error_message) { + LM_ERROR(error_message); } VirtualCore::~VirtualCore() { @@ -70,26 +71,8 @@ VirtualCore::~VirtualCore() { libs.clear(); } -int VirtualCore::run() { - DEBUG_ENTER_FUNC(); - DEBUG_SEPARATOR("VM EXECUTION START"); - - if (ste.program == nullptr) { - handle_error("Program is null"); - DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; - } - - DEBUG_LOG_FMT("Program size: %zu instructions", ste.program->size()); - DEBUG_LOG("Starting VM execution"); - - while (ste.pc < ste.program->size()) { - const Opcode& op = ste.program->operator[](ste.pc).op; - const auto& operands = ste.program->operator[](ste.pc).operands; - - DEBUG_EXEC_STEP(ste.pc, op, ""); - - switch (op) { +void VirtualCore::log_op(const Opcode &op, const uint8_t(&operands)[12]) { + switch (op) { using enum Opcode; case MOV_RI: { DEBUG_LOG_FMT("MOVRI: r%d, %lld", static_cast(operands[0]), *reinterpret_cast(operands + 1)); @@ -243,15 +226,18 @@ int VirtualCore::run() { DEBUG_LOG_FMT("Unknown opcode: %d", static_cast(op)); break; } - } + } +} - switch (op) { +bool VirtualCore::run_op(const Opcode &op, const uint8_t(&operands)[12], int &result) { + switch (op) { using enum Opcode; case MOV_RI: { if (!is_valid_register(operands[0])) { handle_error("Invalid register index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } const uint8_t dst_reg = operands[0]; const int64_t imm_val = *reinterpret_cast(operands + 1); @@ -264,14 +250,16 @@ int VirtualCore::run() { if (!is_valid_register(operands[0])) { handle_error("Invalid register index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } const uint8_t dst_reg = operands[0]; const uint64_t mem_addr = operands[1]; if (mem_addr == 0) { handle_error("Null memory address in MOV_RM"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } ste.regs[dst_reg] = *reinterpret_cast(mem_addr); ste.pc++; @@ -282,7 +270,8 @@ int VirtualCore::run() { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1])) { handle_error("Invalid register index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } const uint8_t dst_reg = operands[0]; const uint8_t src_reg = operands[1]; @@ -295,12 +284,14 @@ int VirtualCore::run() { if (!is_valid_register(operands[0])) { handle_error("Invalid register index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } if (const_pool_top == nullptr) { handle_error("Constant pool is null"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } const uint8_t dst_reg = operands[0]; const uint64_t const_idx = *(uint64_t*)(operands + 1); @@ -328,7 +319,8 @@ int VirtualCore::run() { case MOV_MR: { if (!is_valid_register(operands[1])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint64_t mem_addr = operands[0]; const uint8_t src_reg = operands[1]; @@ -340,7 +332,8 @@ int VirtualCore::run() { case MOV_MC: { if (const_pool_top == nullptr) { handle_error("Constant pool is null"); - return 1; + result = 1; + return true; } const uint64_t mem_addr = operands[0]; const uint64_t const_idx = operands[1]; @@ -352,7 +345,8 @@ int VirtualCore::run() { case ADD: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t add_dst_reg = operands[0]; const uint8_t add_src1_reg = operands[1]; @@ -365,12 +359,14 @@ int VirtualCore::run() { if ((type1 == ValueType::Ptr && type2 == ValueType::Int) || (type1 == ValueType::Int && type2 == ValueType::Ptr)) { handle_error("Cannot add vector and number"); - return 1; + result = 1; + return true; } if (type1 != type2) { handle_error("Cannot add different types"); - return 1; + result = 1; + return true; } if (type1 == ValueType::Int) { @@ -378,7 +374,7 @@ int VirtualCore::run() { ste.regs[add_dst_reg] = add_result; ste.pc++; DEBUG_LOG_FMT("ADD: r%d = r%d + r%d = %lld", static_cast(add_dst_reg), - static_cast(add_src1_reg), static_cast(add_src2_reg), add_result); + static_cast(add_src1_reg), static_cast(add_src2_reg), add_result); } else if (type1 == ValueType::Ptr) { DEBUG_LOG("Adding ptr..."); const size_t vec1_addr = ste.regs[add_src1_reg].u64; @@ -389,7 +385,8 @@ int VirtualCore::run() { if (vec1_len != vec2_len) { handle_error("Vectors must have the same length for addition"); - return 1; + result = 1; + return true; } const size_t vec_result_addr = ste.heap.size(); @@ -404,7 +401,8 @@ int VirtualCore::run() { if (elem1.type != elem2.type) { handle_error("Vector elements must have the same type for addition"); - return 1; + result = 1; + return true; } Value result_elem; @@ -412,7 +410,8 @@ int VirtualCore::run() { result_elem = elem1.i64 + elem2.i64; } else { handle_error("Unsupported vector element type for addition"); - return 1; + result = 1; + return true; } ste.heap[vec_result_addr + 1 + i] = result_elem; @@ -422,17 +421,19 @@ int VirtualCore::run() { ste.regs[add_dst_reg].u64 = vec_result_addr; ste.pc++; DEBUG_LOG_FMT("ADD: vector r%d + r%d, result len=%llu", - static_cast(add_src1_reg), static_cast(add_src2_reg), vec1_len); + static_cast(add_src1_reg), static_cast(add_src2_reg), vec1_len); } else { handle_error("Unsupported type for addition"); - return 1; + result = 1; + return true; } break; } case SUB: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t sub_dst_reg = operands[0]; const uint8_t sub_src1_reg = operands[1]; @@ -441,13 +442,14 @@ int VirtualCore::run() { ste.regs[sub_dst_reg] = sub_result; ste.pc++; DEBUG_LOG_FMT("SUB: r%d = r%d - r%d = %lld", static_cast(sub_dst_reg), - static_cast(sub_src1_reg), static_cast(sub_src2_reg), sub_result); + static_cast(sub_src1_reg), static_cast(sub_src2_reg), sub_result); break; } case MUL: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t mul_dst_reg = operands[0]; const uint8_t mul_src1_reg = operands[1]; @@ -456,51 +458,56 @@ int VirtualCore::run() { ste.regs[mul_dst_reg] = mul_result; ste.pc++; DEBUG_LOG_FMT("MUL: r%d = r%d * r%d = %lld", static_cast(mul_dst_reg), - static_cast(mul_src1_reg), static_cast(mul_src2_reg), mul_result); + static_cast(mul_src1_reg), static_cast(mul_src2_reg), mul_result); break; } case DIV: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t div_dst_reg = operands[0]; const uint8_t div_src1_reg = operands[1]; const uint8_t div_src2_reg = operands[2]; if (ste.regs[div_src2_reg].i64 == 0) { handle_error("Division by zero"); - return 1; + result = 1; + return true; } const int64_t div_result = ste.regs[div_src1_reg].i64 / ste.regs[div_src2_reg].i64; ste.regs[div_dst_reg] = div_result; ste.pc++; DEBUG_LOG_FMT("DIV: r%d = r%d / r%d = %lld", static_cast(div_dst_reg), - static_cast(div_src1_reg), static_cast(div_src2_reg), div_result); + static_cast(div_src1_reg), static_cast(div_src2_reg), div_result); break; } case MOD: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t mod_dst_reg = operands[0]; const uint8_t mod_src1_reg = operands[1]; const uint8_t mod_src2_reg = operands[2]; if (ste.regs[mod_src2_reg].i64 == 0) { handle_error("Modulo by zero"); - return 1; + result = 1; + return true; } const int64_t mod_result = ste.regs[mod_src1_reg].i64 % ste.regs[mod_src2_reg].i64; ste.regs[mod_dst_reg] = mod_result; ste.pc++; DEBUG_LOG_FMT("MOD: r%d = r%d %% r%d = %lld", static_cast(mod_dst_reg), - static_cast(mod_src1_reg), static_cast(mod_src2_reg), mod_result); + static_cast(mod_src1_reg), static_cast(mod_src2_reg), mod_result); break; } case POW: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t pow_dst_reg = operands[0]; const uint8_t pow_src1_reg = operands[1]; @@ -509,14 +516,15 @@ int VirtualCore::run() { ste.regs[pow_dst_reg] = pow_result; ste.pc++; DEBUG_LOG_FMT("POW: r%d = pow(r%d, r%d) = %f", static_cast(pow_dst_reg), - static_cast(pow_src1_reg), static_cast(pow_src2_reg), pow_result); + static_cast(pow_src1_reg), static_cast(pow_src2_reg), pow_result); break; } case FCALL: { uint64_t target_pc = *reinterpret_cast(operands); if (target_pc >= ste.program->size()) { handle_error("Invalid jump address"); - return 1; + result = 1; + return true; } const auto args_count = operands[8]; ste.ret_addr_stack.push_back(ste.pc + 1); @@ -526,7 +534,8 @@ int VirtualCore::run() { for (uint8_t i = 0; i != args_count; i++) { if (REG_COUNT_INDEX_MAX - i >= REG_COUNT) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } ste.stack_frames.back()->locals[i] = ste.regs[REG_COUNT_INDEX_MAX - i]; } @@ -536,7 +545,8 @@ int VirtualCore::run() { case FRET: { if (ste.ret_addr_stack.empty() || ste.stack_frames.size() <= 1) { handle_error("Invalid return operation"); - return 1; + result = 1; + return true; } const size_t return_addr = ste.ret_addr_stack.back(); ste.pc = return_addr; @@ -549,13 +559,15 @@ int VirtualCore::run() { DEBUG_LOG("HALT"); DEBUG_SEPARATOR("VM EXECUTION END (SUCCESS)"); DEBUG_LEAVE_FUNC(); - return 0; + result = 0; + return true; } case DEBUG_LOG: { if (const_pool_top == nullptr) { handle_error("Constant pool is null"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } DEBUG_LOG_FMT("[LogInfo]: %s", static_cast(const_pool_top) + *reinterpret_cast(operands)); ste.pc++; @@ -566,7 +578,8 @@ int VirtualCore::run() { if (target_pc >= ste.program->size()) { handle_error("Invalid jump address"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } ste.pc = target_pc; DEBUG_LOG_FMT("JMP: %llu", target_pc); @@ -576,7 +589,8 @@ int VirtualCore::run() { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } const uint8_t dst_reg = operands[0]; const uint8_t src1_reg = operands[1]; @@ -585,13 +599,14 @@ int VirtualCore::run() { ste.regs[dst_reg].b = result; ste.pc++; DEBUG_LOG_FMT("CMP_GE: r%d = (r%d >= r%d) = %s", static_cast(dst_reg), - static_cast(src1_reg), static_cast(src2_reg), result ? "true" : "false"); + static_cast(src1_reg), static_cast(src2_reg), result ? "true" : "false"); break; } case CMP_LT: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t cmp_dst_reg = operands[0]; const uint8_t cmp_src1_reg = operands[1]; @@ -600,13 +615,14 @@ int VirtualCore::run() { ste.regs[cmp_dst_reg].b = cmp_result; ste.pc++; DEBUG_LOG_FMT("CMP_LT: r%d = (r%d < r%d) = %s", static_cast(cmp_dst_reg), - static_cast(cmp_src1_reg), static_cast(cmp_src2_reg), cmp_result ? "true" : "false"); + static_cast(cmp_src1_reg), static_cast(cmp_src2_reg), cmp_result ? "true" : "false"); break; } case CMP_LE: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t cmp_dst_reg = operands[0]; const uint8_t cmp_src1_reg = operands[1]; @@ -615,13 +631,14 @@ int VirtualCore::run() { ste.regs[cmp_dst_reg].b = cmp_result; ste.pc++; DEBUG_LOG_FMT("CMP_LE: r%d = (r%d <= r%d) = %s", static_cast(cmp_dst_reg), - static_cast(cmp_src1_reg), static_cast(cmp_src2_reg), cmp_result ? "true" : "false"); + static_cast(cmp_src1_reg), static_cast(cmp_src2_reg), cmp_result ? "true" : "false"); break; } case CMP_GT: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } ste.regs[operands[0]].b = ste.regs[operands[1]].i64 > ste.regs[operands[2]].i64; ste.pc++; @@ -630,7 +647,8 @@ int VirtualCore::run() { case CMP_EQ: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } ste.regs[operands[0]].b = ste.regs[operands[1]].i64 == ste.regs[operands[2]].i64; ste.pc++; @@ -639,7 +657,8 @@ int VirtualCore::run() { case CMP_NE: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } ste.regs[operands[0]].b = ste.regs[operands[1]].i64 != ste.regs[operands[2]].i64; ste.pc++; @@ -649,13 +668,15 @@ int VirtualCore::run() { if (!is_valid_register(operands[0])) { handle_error("Invalid register index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } uint64_t target_pc = *reinterpret_cast(operands + 1); if (target_pc >= ste.program->size()) { handle_error("Invalid jump address"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } const uint8_t cond_reg = operands[0]; bool condition = ste.regs[cond_reg].b; @@ -671,12 +692,14 @@ int VirtualCore::run() { case IF_FALSE: { if (!is_valid_register(operands[0])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } uint64_t target_pc = *reinterpret_cast(operands + 1); if (target_pc >= ste.program->size()) { handle_error("Invalid jump address"); - return 1; + result = 1; + return true; } if (!ste.regs[operands[0]].b) ste.pc = target_pc; else ste.pc++; @@ -699,18 +722,21 @@ int VirtualCore::run() { if (!is_valid_register(operands[0])) { handle_error("Invalid register index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } if (operands[1] >= ste.stack_frames.size()) { handle_error("Invalid stack frame index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } uint16_t local_index = *(uint16_t*)(operands + 2); if (local_index >= ste.stack_frames[operands[1]]->locals.size()) { handle_error("Invalid local variable index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } const uint8_t dst_reg = operands[0]; const uint8_t frame_idx = operands[1]; @@ -719,39 +745,43 @@ int VirtualCore::run() { ste.pc++; DEBUG_LOG_FMT("LOCAL_GET: r%d = frame[%d].locals[%d] = %s", static_cast(dst_reg), - static_cast(frame_idx), local_index, - ste.regs[dst_reg].to_string().c_str()); + static_cast(frame_idx), local_index, + ste.regs[dst_reg].to_string().c_str()); break; } case LOCAL_SET: { if (!is_valid_register(operands[3])) { handle_error("Invalid register index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } if (operands[0] >= ste.stack_frames.size()) { handle_error("Invalid stack frame index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } uint16_t local_index = *(uint16_t*)(operands + 1); if (local_index >= ste.stack_frames[operands[0]]->locals.size()) { handle_error("Invalid local variable index"); DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); - return 1; + result = 1; + return true; } const uint8_t frame_idx = operands[0]; const uint8_t src_reg = operands[3]; ste.stack_frames[frame_idx]->locals[local_index] = ste.regs[src_reg]; ste.pc++; DEBUG_LOG_FMT("LOCAL_SET: frame[%d].locals[%d] = r%d (%s)", static_cast(frame_idx), - local_index, static_cast(src_reg), ste.regs[src_reg].to_string().c_str()); + local_index, static_cast(src_reg), ste.regs[src_reg].to_string().c_str()); break; } case AND: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } ste.regs[operands[0]].b = ste.regs[operands[1]].b && ste.regs[operands[2]].b; ste.pc++; @@ -760,7 +790,8 @@ int VirtualCore::run() { case OR: { if (!is_valid_register(operands[0]) || !is_valid_register(operands[1]) || !is_valid_register(operands[2])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } ste.regs[operands[0]].b = ste.regs[operands[1]].b || ste.regs[operands[2]].b; ste.pc++; @@ -770,7 +801,8 @@ int VirtualCore::run() { uint16_t vmcall_index = *(uint16_t*)operands; if (vmcall_index >= VMCall::vmcall_count) { handle_error("Invalid VMCall index"); - return 1; + result = 1; + return true; } VMCall::vmcall_table[vmcall_index](this); ste.pc++; @@ -779,7 +811,8 @@ int VirtualCore::run() { case DEC: { if (!is_valid_register(operands[0])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } ste.regs[operands[0]].i64--; ste.pc++; @@ -788,7 +821,8 @@ int VirtualCore::run() { case PUSH: { if (!is_valid_register(operands[0])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t src_reg = operands[0]; ste.stack.push_back(ste.regs[src_reg]); @@ -799,14 +833,16 @@ int VirtualCore::run() { case CREATE_VECTOR: { if (!is_valid_register(operands[0])) { handle_error("Invalid register index"); - return 1; + result = 1; + return true; } const uint8_t dst_reg = operands[0]; const uint8_t count = operands[1]; if (ste.stack.size() < count) { handle_error("Not enough elements on stack for CREATE_VECTOR"); - return 1; + result = 1; + return true; } size_t vec_addr = ste.heap.size(); @@ -827,13 +863,39 @@ int VirtualCore::run() { ste.pc++; DEBUG_LOG_FMT("CREATE_VECTOR: r%d = vec[%d] at heap[%llu]", static_cast(dst_reg), - static_cast(count), vec_addr); + static_cast(count), vec_addr); break; } default: + handle_error("unknown opcode"); ste.pc++; break; - } + } + return false; +} + +int VirtualCore::run() { + DEBUG_ENTER_FUNC(); + DEBUG_SEPARATOR("VM EXECUTION START"); + + if (ste.program == nullptr) { + handle_error("Program is null"); + DEBUG_SEPARATOR("VM EXECUTION END (ERROR)"); + return 1; + } + + DEBUG_LOG_FMT("Program size: %zu instructions", ste.program->size()); + DEBUG_LOG("Starting VM execution"); + + while (ste.pc < ste.program->size()) { + const Opcode& op = (*ste.program)[ste.pc].op; + const auto& operands = (*ste.program)[ste.pc].operands; + + DEBUG_EXEC_STEP(ste.pc, op, ""); + + log_op(op, operands); + if (int result; run_op(op, operands, result)) + return result; } DEBUG_LOG("PC out of bounds"); diff --git a/runtime/vm.hpp b/runtime/vm.hpp index 7e36a15..9cae054 100644 --- a/runtime/vm.hpp +++ b/runtime/vm.hpp @@ -44,13 +44,13 @@ class LMVM_API VirtualCore { [[nodiscard]] Value* get_value_from_pool(size_t offset) const; // 检查寄存器索引是否有效 - [[nodiscard]] bool is_valid_register(uint8_t reg) const; + static bool is_valid_register(uint8_t reg) ; // 统一错误处理函数 - void handle_error(const char* error_message) const; + static void handle_error(const char* error_message) ; // 验证多个寄存器索引 - [[nodiscard]] bool validate_registers(const uint8_t* regs, size_t count) const; + [[nodiscard]] static bool validate_registers(const uint8_t* regs, size_t count); // 验证跳转地址 [[nodiscard]] bool validate_jump_address(uint64_t address) const; @@ -60,6 +60,11 @@ class LMVM_API VirtualCore { // 从常量池获取字符串 [[nodiscard]] const char* get_constant_string(uint64_t offset) const; + + static void log_op(const Opcode &op, const uint8_t(&operands)[12]); + + bool run_op(const Opcode &op, const uint8_t(&operands)[12], int &result); + public: std::vector> libs; // 加载的动态库 diff --git a/tools/lm/common/file_run.cpp b/tools/lm/common/file_run.cpp index 34195a6..9c7b2a2 100644 --- a/tools/lm/common/file_run.cpp +++ b/tools/lm/common/file_run.cpp @@ -28,18 +28,21 @@ int file_run(const std::string& file_name) { } file.read(reinterpret_cast(&magic), sizeof(magic)); if (magic == LMX_MAGIC_NUM) return binary_run(std::move(file)); + file.seekg(0, std::ios::beg); - auto src = std::string(std::istreambuf_iterator(file), std::istreambuf_iterator()); + auto src = std::string(std::istreambuf_iterator(file), std::istreambuf_iterator()); lmx::Lexer lexer(src); auto ts = lexer.tokenize(src); lmx::Parser parser(ts, src, file_name); - lmx::Generator gener; std::shared_ptr node = parser.parse_program(); if (!node || parser.error()) return -1; + + lmx::Generator gener; gener.gen(node); - if (lmx::Generator::node_has_error)return -1; + if (lmx::Generator::node_has_error) return -1; gener.ops.emplace_back(lmx::runtime::Opcode::HALT); gener.write_binary_file(file_name); + lmx::runtime::VirtualCore vm; vm.set_program(&gener.ops); vm.set_constant(gener.constant_pool.data()); From ae8bbdf8161b462c57cad519120579e35d60f945 Mon Sep 17 00:00:00 2001 From: CGrakeski Date: Sun, 29 Mar 2026 13:11:46 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E8=A7=84=E8=8C=83=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/generator/emit.cpp | 5 ----- compiler/generator/generator.cpp | 19 +++++-------------- compiler/parser.cpp | 26 ++++++++------------------ runtime/builtins.cpp | 2 -- runtime/vmcall.cpp | 18 +++++------------- tools/lm/common/repl.cpp | 11 ----------- 6 files changed, 18 insertions(+), 63 deletions(-) diff --git a/compiler/generator/emit.cpp b/compiler/generator/emit.cpp index b9405e2..38a580c 100644 --- a/compiler/generator/emit.cpp +++ b/compiler/generator/emit.cpp @@ -34,11 +34,8 @@ void LMXOpcodeEmitter::emit_mov_ri(std::vector &ops, uint8_t r void LMXOpcodeEmitter::emit_mov_rr(std::vector &ops, uint8_t r1, uint8_t r2) { if (r1 == r2) return; - // 只有当ret_type为Reg时才进行优化,并且上一条指令必须是返回Reg类型的指令 if (ret_type == Reg && !ops.empty()) { - // 检查上一条指令是否是返回Reg类型的指令 const auto& last_op = ops.back(); - // 只对返回Reg类型的指令进行优化 bool is_reg_return_op = false; switch (last_op.op) { case lmx::runtime::Opcode::MOV_RI: @@ -65,9 +62,7 @@ void LMXOpcodeEmitter::emit_mov_rr(std::vector &ops, uint8_t r is_reg_return_op = false; break; } - // 只有当上一条指令是返回Reg类型的指令时才进行优化 if (is_reg_return_op) { - // 对于返回Reg类型的指令,operands[0]是目标寄存器 if (last_op.operands[0] == r2) { ops.back().operands[0] = r1; return; diff --git a/compiler/generator/generator.cpp b/compiler/generator/generator.cpp index b586d19..b42429e 100644 --- a/compiler/generator/generator.cpp +++ b/compiler/generator/generator.cpp @@ -51,7 +51,6 @@ bool Allocator::is_free(const size_t i) const { } void Generator::add_builtins() const { - // 从 builtins 命名空间添加内置常量到编译帧 size_t base_index = runtime::builtins::builtin_start; for (size_t i = 0; i < runtime::builtins::builtin_constants_count; i++) { const auto&[name, value] = runtime::builtins::builtin_constants[i]; @@ -170,7 +169,7 @@ size_t Generator::gen_break(std::shared_ptr &n) { size_t Generator::gen_module(std::shared_ptr &shared) { const auto node = std::static_pointer_cast(std::move(shared)); for (const auto& mn : modules) - if (mn == node->name) return -1; //已解析过同名模块,不再解析 + if (mn == node->name) return -1; if (node->type == ModuleNode::Types::dyn) { @@ -365,7 +364,7 @@ size_t Generator::gen_function(std::shared_ptr &n) { error("the function args name `" + arg + "` was defined on last scope"); } } - new_func(node->name, args_count); //函数不做作用域区分,全部全局 + new_func(node->name, args_count); for (size_t i = 0; i < args_count ; i++) { LMXOpcodeEmitter::emit_local_set(ops, cur.size() - 1, i, REG_COUNT_INDEX_MAX - i); cur.back()->new_var(node->args[i], true, i); @@ -488,20 +487,17 @@ size_t Generator::gen_vector(std::shared_ptr &n) { DEBUG_LOG("gen vector"); regs.print_regs(); - // 1. 计算向量的大小 const size_t vector_size = node->elements.size(); DEBUG_LOG("vector_size: " << vector_size); - // 2. 为所有元素生成代码,获取它们的值到寄存器 std::vector elem_regs; elem_regs.reserve(node->elements.size()); for (auto& elem : node->elements) { std::shared_ptr elem_node = elem; DEBUG_LOG("Now processing: " << elem_node->kind << ": " << elem_node); - auto reg = gen(elem_node); // 生成元素代码,返回存放结果的寄存器 + auto reg = gen(elem_node); if (reg == -1) { - // 如果生成元素代码时出错,设置错误标志并返回 node_has_error = true; return -1; } @@ -511,31 +507,26 @@ size_t Generator::gen_vector(std::shared_ptr &n) { regs.print_regs(); } - // 3. 将求解后的值依次压栈 for (auto reg : elem_regs) { LMXOpcodeEmitter::emit_push(ops, reg); DEBUG_LOG("Pushed r" << reg << " to stack"); } - // 4. 调用 CREATE_VECTOR 字节码 - // 参数: 目标寄存器, 元素个数 - auto result_reg = regs.alloc(); // 分配结果寄存器 + auto result_reg = regs.alloc(); LMXOpcodeEmitter::emit_create_vector(ops, result_reg, vector_size); DEBUG_LOG("CREATE_VECTOR r" << result_reg << ", " << vector_size); - // 5. 释放元素寄存器 for (const auto reg : elem_regs) { regs.free(reg); DEBUG_LOG("Freed register: " << reg); regs.print_regs(); } - // 6. 标记返回寄存器需要在使用后释放 expr_release = true; DEBUG_LOG("gen_vector finished, returning result_reg: " << result_reg); regs.print_regs(); - return result_reg; // 返回结果寄存器的索引 + return result_reg; } size_t Generator::gen_block(std::shared_ptr &n) { diff --git a/compiler/parser.cpp b/compiler/parser.cpp index 750a1f9..f8a8ac0 100644 --- a/compiler/parser.cpp +++ b/compiler/parser.cpp @@ -180,34 +180,27 @@ std::shared_ptr Parser::parse_if() { return std::make_shared(condition, then_block, else_block); } std::shared_ptr Parser::parse_vector() { - // 期望 '[' if (!match(TokenType::LBRACK)) { error("expected '[' at start of vector"); return nullptr; } - advance(); // 跳过 '[' + advance(); std::vector> elements; - // 处理空向量情况 if (match(TokenType::RBRACK)) { - advance(); // 跳过 ']' + advance(); return std::make_shared(std::move(elements)); } - // 解析第一个元素 elements.push_back(parse_expr()); - // 继续解析后续元素,直到遇到 ']' while (!match(TokenType::RBRACK) && !is_eof()) { - // 必须有逗号分隔 if (!match(TokenType::COMMA)) { error("expected ',' between vector elements"); - // 错误恢复:尝试找到下一个逗号或右括号 while (!match(TokenType::COMMA) && !match(TokenType::RBRACK) && !is_eof()) { advance(); } - // 如果找到逗号,跳过它并继续解析下一个元素 if (match(TokenType::COMMA)) { advance(); if (!match(TokenType::RBRACK)) { @@ -217,9 +210,8 @@ std::shared_ptr Parser::parse_vector() { continue; } - advance(); // 跳过 ',' + advance(); - // 允许尾随逗号?例如 [1, 2, 3,] if (match(TokenType::RBRACK)) { break; } @@ -227,20 +219,18 @@ std::shared_ptr Parser::parse_vector() { elements.push_back(parse_expr()); } - // 检查是否以 ']' 结尾 if (!match(TokenType::RBRACK)) { error("expected ']' at end of vector"); - // 尝试找到右括号来恢复 while (!match(TokenType::RBRACK) && !is_eof()) { advance(); } if (match(TokenType::RBRACK)) { advance(); } - return std::make_shared(std::move(elements)); // 仍返回已解析的部分 + return std::make_shared(std::move(elements)); } - advance(); // 跳过 ']' + advance(); return std::make_shared(std::move(elements)); } std::shared_ptr Parser::parse() { @@ -446,12 +436,12 @@ std::shared_ptr Parser::parse_funcdecl(const bool has_block = true) { } } check_type(ret_type =) - if (match(TokenType::LBRACE)) { // 一般 定义情况 + if (match(TokenType::LBRACE)) { auto node = std::make_shared(name, params, parse_block()); node->args_type = std::move(args_type); node->ret_type = std::move(ret_type); return node; - } else if (match(TokenType::ASSIGN)) { // 外部导入情况 + } else if (match(TokenType::ASSIGN)) { advance(); if (!match(TokenType::STRING_LITERAL)) { error("expected string literal"); @@ -463,7 +453,7 @@ std::shared_ptr Parser::parse_funcdecl(const bool has_block = true) { node->args_type = std::move(args_type); node->ret_type = std::move(ret_type); return node; - } else { // 仅声明情况 + } else { auto node = std::make_shared(name, params, nullptr); node->args_type = std::move(args_type); node->ret_type = std::move(ret_type); diff --git a/runtime/builtins.cpp b/runtime/builtins.cpp index 41db5b4..685c32b 100644 --- a/runtime/builtins.cpp +++ b/runtime/builtins.cpp @@ -2,7 +2,6 @@ namespace lmx::runtime::builtins { const BuiltinConstant builtin_constants[] = { - // 物理常量 {"EARTH_GRAVITY", Value(9.80665)}, {"MOON_GRAVITY", Value(1.625)}, {"MARS_GRAVITY", Value(3.72076)}, @@ -16,7 +15,6 @@ namespace lmx::runtime::builtins { {"KB", Value(1.380649e-23)}, {"EPSILON_0", Value(8.8541878128e-12)}, {"MU_0", Value(1.25663706212e-6)}, - // 化学常量 {"AVOGADRO", Value(6.02214076e23)}, {"R", Value(8.314462618)}, {"FARADAY", Value(9.648533212e4)}, diff --git a/runtime/vmcall.cpp b/runtime/vmcall.cpp index 681129d..cc8e201 100644 --- a/runtime/vmcall.cpp +++ b/runtime/vmcall.cpp @@ -51,7 +51,7 @@ VMC_REGISTER(dyn_set) { const auto args_type_p = static_cast(self->get_register(REG_COUNT_INDEX_MAX - 2).ptr); static_cast(self->get_register(REG_COUNT_INDEX_MAX).ptr)->set_func( self->get_register(REG_COUNT_INDEX_MAX - 1).str, - std::vector( + std::vector( args_type_p, args_type_p + self->get_register(REG_COUNT_INDEX_MAX - 3).u64), *static_cast(self->get_register(REG_COUNT_INDEX_MAX - 4).ptr) @@ -78,13 +78,11 @@ VMC_REGISTER(dyn_call) { * * return: memory_ptr in r0 */ -// VMC 6: 分配内存 VMC_REGISTER(alloc_memory) { size_t slots = self->get_register(0).u64; size_t memory_start = self->heap_size(); - // 分配 slots 个 Value,初始化为 Null for (size_t i = 0; i < slots; i++) { Value value; value.type = ValueType::Null; @@ -92,10 +90,9 @@ VMC_REGISTER(alloc_memory) { self->heap_push_back(value); } - // 返回起始索引(指针) Value memory_ptr; memory_ptr.type = ValueType::Ptr; - memory_ptr.u64 = memory_start; // 存的是堆索引 + memory_ptr.u64 = memory_start; self->get_register(0) = memory_ptr; DEBUG_LOG("VMC[6]: allocated " << slots << " slots at heap[" << memory_start << "]"); @@ -110,23 +107,18 @@ VMC_REGISTER(alloc_memory) { * 存储值到指定内存地址 */ VMC_REGISTER(store_memory) { - size_t memory_ptr = self->get_register(0).u64; - size_t offset = self->get_register(1).u64; - Value value = self->get_register(2); + const size_t memory_ptr = self->get_register(0).u64; + const size_t offset = self->get_register(1).u64; + const Value value = self->get_register(2); - // 检查内存指针是否有效 if (memory_ptr >= self->heap_size()) { - // 无效的内存指针 return; } - // 检查偏移量是否有效 if (memory_ptr + offset >= self->heap_size()) { - // 无效的偏移量 return; } - // 存储值 self->heap_at(memory_ptr + offset) = value; } diff --git a/tools/lm/common/repl.cpp b/tools/lm/common/repl.cpp index 8b8129b..d166615 100644 --- a/tools/lm/common/repl.cpp +++ b/tools/lm/common/repl.cpp @@ -7,16 +7,13 @@ #include "../compiler/ast.hpp" #include "../../../include/debug.hpp" -// Function to print AST nodes void print_ast(const std::shared_ptr& node, int indent = 0) { if (!node) return; - // Print indentation for (int i = 0; i < indent; i++) { std::cerr << " "; } - // Print node type and information based on kind switch (node->kind) { case lmx::ASTKind::Program: std::cerr << "Program" << std::endl; @@ -131,7 +128,6 @@ void print_ast(const std::shared_ptr& node, int indent = 0) { { auto module = dynamic_cast(node.get()); std::cerr << "Module(" << module->name << ")" << std::endl; - // Print children if needed } break; case lmx::ASTKind::Use: @@ -213,24 +209,18 @@ int run_repl() { if (op != -1 && result == 0) { generator.regs.free(op); - // 检查返回值的类型 auto& value = core.get_register(op); if (value.type == lmx::runtime::ValueType::Null) { - // 如果是null,则不显示 } else if (value.type == lmx::runtime::ValueType::Ptr) { - // 对于向量类型,打印向量的地址和长度 size_t vector_ptr = value.i64; size_t vector_size = core.heap_at(vector_ptr).i64; std::cout << "vec["; for (size_t i = 0; i < vector_size; i++) { if (i > 0) std::cout << ", "; - // 根据元素类型显示 auto& elem = core.heap_at(vector_ptr + 1 + i); if (elem.type == lmx::runtime::ValueType::Ptr) { - // 检查是否是向量 size_t elem_ptr = elem.u64; size_t elem_size = core.heap_at(elem_ptr).i64; - // 递归显示向量 std::cout << "vec["; for (size_t j = 0; j < elem_size; j++) { if (j > 0) std::cout << ", "; @@ -285,7 +275,6 @@ int run_repl() { } std::cout << "]" << std::endl; } else { - // 对于其他类型,根据类型正确显示 switch (value.type) { case lmx::runtime::ValueType::Int: std::cout << value.i64 << std::endl;