Files
Compiler/interpreter.cpp

365 lines
12 KiB
C++
Raw Permalink Normal View History

2025-11-16 21:04:02 +08:00
#include "interpreter.h"
#include <cctype>
#include <sstream>
int IRInterpreter::asInt(const std::string& s) {
if (s.empty()) return 0;
if (isdigit(s[0]) || (s[0] == '-' && s.size() > 1 && isdigit(s[1]))) {
return std::stoi(s);
}
return 0;
}
std::string IRInterpreter::asStr(const std::string& s) {
if (s.size() >= 2 && s.front() == '"' && s.back() == '"') {
return s.substr(1, s.size() - 2);
} else if (memory_.count(s) && std::holds_alternative<std::string>(memory_[s])) {
return std::get<std::string>(memory_[s]);
}
return s;
}
void IRInterpreter::runStepByStep(const std::vector<Quad>& quads) {
// 建立 label -> index 映射 (用于控制流跳转)
std::unordered_map<std::string, int> labelToIndex;
for (int i = 0; i < quads.size(); ++i) {
if (quads[i].op == "label") {
labelToIndex[quads[i].result] = i;
}
}
std::string cmd;
while (pc_ < quads.size()) {
const auto& q = quads[pc_];
if (breakpoints_.count(q.loc.line)) {
std::cout << "🟥 Breakpoint hit at line " << q.loc.line << "\n";
dumpVariables(q.loc.line);
// ⚠️关键修复:命中断点时立刻执行当前指令!
execute(q, quads, labelToIndex);
pc_++;
// 如果下一条指令属于同一行,也立刻执行,避免二次命中断点
while (pc_ < quads.size() && quads[pc_].loc.line == q.loc.line) {
execute(quads[pc_], quads, labelToIndex);
pc_++;
}
continue;
}
// 显示当前指令
std::cout << "[PC " << pc_ << "] " << q.op << " " << q.arg1 << " " << q.arg2 << " -> " << q.result;
std::cout << " @ line " << q.loc.line << "\n";
std::cout << "(step> ";
std::getline(std::cin, cmd);
if (cmd == "next" || cmd == "n") {
execute(q, quads, labelToIndex); pc_++;
}
else if (cmd.starts_with("break ")) {
int line = std::stoi(cmd.substr(6));
breakpoints_.insert(line);
std::cout << "✅ Breakpoint set at line " << line << "\n";
}
else if (cmd == "continue" || cmd == "c") {
// 先执行当前指令
execute(q, quads, labelToIndex); pc_++;
while (pc_ < quads.size()) {
const auto& current = quads[pc_];
if (breakpoints_.count(current.loc.line)) {
std::cout << "🟥 Breakpoint hit at line " << current.loc.line << "\n";
dumpVariables(current.loc.line);
// ⚠️关键修复:命中断点立刻执行当前指令!
execute(current, quads, labelToIndex); pc_++;
// 若下一条同一行,也执行
while (pc_ < quads.size() && quads[pc_].loc.line == current.loc.line) {
execute(quads[pc_], quads, labelToIndex);
pc_++;
}
break;
}
execute(current,quads, labelToIndex);
// 处理控制流
if (current.op == "goto") {
pc_ = labelToIndex[current.result];
} else if (current.op == "ifFalse") {
int cond = memory_.count(current.arg1) ? std::get<int>(memory_[current.arg1]) : asInt(current.arg1);
pc_ = cond ? pc_ + 1 : labelToIndex[current.result];
} else if (current.op == "ifTrue") {
int cond = memory_.count(current.arg1) ? std::get<int>(memory_[current.arg1]) : asInt(current.arg1);
pc_ = cond ? labelToIndex[current.result] : pc_ + 1;
} else {
pc_++;
}
}
}
else if (cmd == "print") {
dumpVariables(q.loc.line);
}
else if (cmd == "exit" || cmd == "q") {
std::cout << "👋 Exiting...\n";
break;
}
else {
std::cout << "❓ Unknown command: " << cmd << "\n";
}
}
}
IRInterpreter::Value IRInterpreter::evalBinary(const std::string& op, const Value& a, const Value& b) {
if (std::holds_alternative<int>(a) && std::holds_alternative<int>(b)) {
int x = std::get<int>(a), y = std::get<int>(b);
if (op == "+") return x + y;
if (op == "-") return x - y;
if (op == "*") return x * y;
if (op == "/") return y != 0 ? x / y : 0;
if (op == "<") return x < y;
if (op == ">") return x > y;
if (op == "==") return x == y;
if (op == "!=") return x != y;
if (op == "&&") return x && y;
if (op == "||") return x || y;
}
return 0;
}
std::string IRInterpreter::findLastSource(const std::vector<Quad>& quads, const std::string& target) {
for (auto it = quads.rbegin(); it != quads.rend(); ++it) {
if (it->result == target && !it->arg1.empty()) {
return it->arg1;
}
}
return "";
}
void IRInterpreter::execute(const Quad& q,
const std::vector<Quad>& quads,
const std::unordered_map<std::string, int>& labelToIndex) {
// 类型记录
if (!q.result.empty() && q.type) {
types_[q.result] = q.type;
}
if (q.op == "=") {
if (q.arg1.empty()) {
memory_.emplace(q.result, 0);
} else if (q.arg1[0] == '"') {
memory_[q.result] = asStr(q.arg1);
} else if (isdigit(q.arg1[0]) || (q.arg1[0] == '-' && isdigit(q.arg1[1]))) {
memory_[q.result] = std::stoi(q.arg1);
} else {
memory_[q.result] = memory_.count(q.arg1) ? memory_[q.arg1] : 0;
}
}
else if (q.op == "+" || q.op == "-" || q.op == "*" || q.op == "/" ||
q.op == "<" || q.op == ">" || q.op == "==" || q.op == "!=" ||
q.op == "&&" || q.op == "||") {
Value valA = memory_.count(q.arg1) ? memory_[q.arg1] : asInt(q.arg1);
Value valB = memory_.count(q.arg2) ? memory_[q.arg2] : asInt(q.arg2);
memory_[q.result] = evalBinary(q.op, valA, valB);
}
else if (q.op == "!") {
int val = asInt(q.arg1);
memory_[q.result] = !val;
}
else if (q.op == "label" || q.op == "goto" || q.op == "ifTrue" || q.op == "ifFalse") {
// 控制流不处理,外部 runStepByStep() 会处理 PC 跳转
}
// else if (q.op == "param" || q.op == "call" || q.op == "return") {
// std::cout << "[WARN] Function-related op '" << q.op << "' not yet supported.\n";
// }
else if (q.op == "param") {
Value val = memory_.count(q.arg1) ? memory_[q.arg1] : asInt(q.arg1);
paramStack_.push_back(val);
}
else if (q.op == "call") {
CallFrame frame;
frame.return_pc = pc_ + 1;
frame.locals = memory_; // 保存当前变量环境
callStack_.push(frame);
memory_.clear();
int num_args = std::stoi(q.arg2);
auto it = labelToIndex.find(q.arg1);
if (it == labelToIndex.end()) {
std::cerr << "[ERROR] Undefined function: " << q.arg1 << "\n";
return;
}
pc_ = it->second + 1; // 跳转到函数标签下一条指令
// 传递参数到函数内部
for (int i = num_args - 1; i >= 0; --i) {
memory_["arg" + std::to_string(i)] = paramStack_.back();
paramStack_.pop_back();
}
}
else if (q.op == "return") {
Value ret_val = memory_.count(q.arg1) ? memory_[q.arg1] : asInt(q.arg1);
if (callStack_.empty()) {
std::cerr << "[ERROR] Return outside function!\n";
return;
}
CallFrame frame = callStack_.top();
callStack_.pop();
memory_ = frame.locals; // 恢复调用函数前的内存环境
// 将返回值存入指定变量中如果call指令有返回值
if (!quads[frame.return_pc - 1].result.empty()) {
memory_[quads[frame.return_pc - 1].result] = ret_val;
}
pc_ = frame.return_pc; // 返回调用位置继续执行
}
else {
std::cerr << "[ERROR] Unknown op: " << q.op << "\n";
}
}
void IRInterpreter::runUntil(const std::vector<Quad>& quads, int breakLine) {
// 建立 label -> index 映射
std::unordered_map<std::string, int> labelToIndex;
for (int i = 0; i < quads.size(); ++i) {
if (quads[i].op == "label") {
labelToIndex[quads[i].result] = i;
}
}
int pc = 0;
while (pc < quads.size()) {
const auto& q = quads[pc];
std::cout << "[PC " << pc << "] line = " << q.loc.line << ", breakLine = " << breakLine << "\n";
if (q.loc.line >= breakLine) break;
std::cout << "[EXEC] " << q.op << " " << q.arg1 << " " << q.arg2 << " -> " << q.result << "\n";
if (!q.result.empty() && q.type) {
types_[q.result] = q.type;
}
if (q.op == "=") {
if (q.arg1.empty()) {
memory_.emplace(q.result, 0);
} else if (q.arg1[0] == '"') {
memory_[q.result] = asStr(q.arg1);
} else if (isdigit(q.arg1[0]) || (q.arg1[0] == '-' && isdigit(q.arg1[1]))) {
memory_[q.result] = std::stoi(q.arg1);
} else {
memory_[q.result] = memory_.count(q.arg1) ? memory_[q.arg1] : 0;
}
}
else if (q.op == "+" || q.op == "-" || q.op == "*" || q.op == "/" ||
q.op == "<" || q.op == ">" || q.op == "==" || q.op == "!=" ||
q.op == "&&" || q.op == "||") {
Value valA = memory_.count(q.arg1) ? memory_[q.arg1] : asInt(q.arg1);
Value valB = memory_.count(q.arg2) ? memory_[q.arg2] : asInt(q.arg2);
memory_[q.result] = evalBinary(q.op, valA, valB);
}
else if (q.op == "!") {
int val = asInt(q.arg1);
memory_[q.result] = !val;
}
else if (q.op == "ifFalse") {
int cond = memory_.count(q.arg1) ? std::get<int>(memory_[q.arg1]) : asInt(q.arg1);
if (!cond) {
pc = labelToIndex[q.result];
continue;
}
}
else if (q.op == "ifTrue") {
int cond = memory_.count(q.arg1) ? std::get<int>(memory_[q.arg1]) : asInt(q.arg1);
if (cond) {
pc = labelToIndex[q.result];
continue;
}
}
else if (q.op == "goto") {
std::cout << "[DEBUG] Handling goto to " << q.result << "\n";
auto it = labelToIndex.find(q.result);
if (it != labelToIndex.end()) {
pc = it->second;
continue;
} else {
std::cerr << "[ERROR] Unknown label: " << q.result << "\n";
}
}
else if (q.op == "label") {
// do nothing
}
else if (q.op == "param" || q.op == "call" || q.op == "return") {
// 留给下一阶段实现函数调用
}
pc++; // 正常执行下一条
}
dumpVariables(breakLine);
}
void IRInterpreter::dumpVariables(int breakLine) {
std::cout << "\n---- Variables before line " << breakLine << " ----\n";
for (const auto& [name, val] : memory_) {
// 忽略以 "t" 开头的临时变量(比如 t1, t2
if (!name.empty() && name[0] == 't' && isdigit(name[1])) continue;
std::cout << name << " = ";
if (std::holds_alternative<int>(val)) {
std::cout << std::get<int>(val);
} else if (std::holds_alternative<std::string>(val)) {
std::cout << "\"" << std::get<std::string>(val) << "\"";
}
if (types_.count(name)) {
std::cout << " (type = " << types_[name]->toString() << ")";
}
std::cout << "\n";
}
}