feat(cli): saqut ir komutu — IR talimat dump'u
- IRFunction::dump() yenilendi: ASCII kutu, sn slot notasyonu, ikili op'larda sembol (+/-/*/<= vb.), hizalı sütunlar - src/cli/commands/ir.hpp: tokenize→parse→collect→ir→dump pipeline - main.cpp + args.hpp: "ir" komutu kayıtlı
This commit is contained in:
parent
3c76eab932
commit
4c67f29362
Binary file not shown.
|
|
@ -10,14 +10,16 @@
|
|||
21 7502 1781796718449424977 CMakeFiles/saqut.dir/src/parser/nodes/statements.cpp.o 3c8869307381c930
|
||||
14 6864 1781796718442362341 CMakeFiles/saqut.dir/src/parser/nodes/binary_expr.cpp.o 5cc8b697133bcf64
|
||||
15 6733 1781796718442847556 CMakeFiles/saqut.dir/src/parser/nodes/declarations.cpp.o c3d262615ede4c95
|
||||
2 4655 1781799345769869911 CMakeFiles/saqut.dir/src/main.cpp.o 3cfef7a665d5bf87
|
||||
4655 4925 1781799350422111935 saqut f2e198803c4dbffb
|
||||
0 22 1781799395548855747 build.ninja 1876a59d627a585
|
||||
0 22 1781799395548855747 /home/saqut/Masaüstü/saqutcompiler/build/cmake_install.cmake 1876a59d627a585
|
||||
2 4490 1781799598563879630 CMakeFiles/saqut.dir/src/main.cpp.o 3cfef7a665d5bf87
|
||||
4490 4758 1781799603051859470 saqut f2e198803c4dbffb
|
||||
0 22 1781799611852960564 build.ninja 1876a59d627a585
|
||||
0 22 1781799611852960564 /home/saqut/Masaüstü/saqutcompiler/build/cmake_install.cmake 1876a59d627a585
|
||||
6733 11112 1781796725160284765 CMakeFiles/saqut.dir/src/symbol/symbol_collector.cpp.o ec4e483b8ddb4007
|
||||
4805 9685 1781796723232278341 CMakeFiles/saqut.dir/src/semantic/structural_validator.cpp.o 248faa3675024351
|
||||
6700 10405 1781796725127284655 CMakeFiles/saqut.dir/src/semantic/type_checker.cpp.o b29c133293d988b0
|
||||
2 795 1781799345769990010 CMakeFiles/saqut.dir/src/vm/interpreter.cpp.o b7dd80e002d68a1d
|
||||
1 958 1781799106946635459 CMakeFiles/saqut.dir/src/ir/ir_function.cpp.o 10f5e8dfd1461d69
|
||||
1 668 1781799598562879634 CMakeFiles/saqut.dir/src/ir/ir_function.cpp.o 10f5e8dfd1461d69
|
||||
1 1001 1781799106947865509 CMakeFiles/saqut.dir/src/ir/ir_program.cpp.o 9518231d970828da
|
||||
2 3078 1781799345769137653 CMakeFiles/saqut.dir/src/ir/ir_generator.cpp.o 10a1ed4e1f52e530
|
||||
1 636 1781799663202595202 CMakeFiles/saqut.dir/src/ir/ir_function.cpp.o 10f5e8dfd1461d69
|
||||
636 892 1781799663837592468 saqut f2e198803c4dbffb
|
||||
|
|
|
|||
|
|
@ -88,8 +88,9 @@ inline CliArgs parseArgs(int argc, char* argv[]) {
|
|||
// İlk argüman komut mu?
|
||||
if (args.command.empty() && i == 1) {
|
||||
if (arg == "run" || arg == "tokens" || arg == "ast" ||
|
||||
arg == "symbols" || arg == "check" || arg == "compile" ||
|
||||
arg == "parse" || arg == "transpile" || arg == "interpret") {
|
||||
arg == "symbols" || arg == "check" || arg == "ir" ||
|
||||
arg == "compile" || arg == "parse" || arg == "transpile" ||
|
||||
arg == "interpret") {
|
||||
args.command = arg;
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef SAQUT_CLI_IR
|
||||
#define SAQUT_CLI_IR
|
||||
|
||||
#include <iostream>
|
||||
#include "cli/args.hpp"
|
||||
#include "tokenizer/tokenizer.hpp"
|
||||
#include "parser/parser.hpp"
|
||||
#include "symbol/symbol_table.hpp"
|
||||
#include "symbol/symbol_collector.hpp"
|
||||
#include "diagnostic/diagnostic_engine.hpp"
|
||||
#include "ir/ir_generator.hpp"
|
||||
|
||||
inline int cmdIr(const CliArgs& args) {
|
||||
std::string filePath = inputFilePath(args);
|
||||
std::string source = readSource(args);
|
||||
if (source.empty()) return 1;
|
||||
|
||||
Tokenizer tokenizer;
|
||||
auto tokens = tokenizer.scan(source, filePath);
|
||||
|
||||
Parser parser;
|
||||
ASTNode* ast = parser.parse(tokens);
|
||||
if (!ast) {
|
||||
std::cerr << "Hata: AST üretilemedi\n";
|
||||
for (auto* t : tokens) delete t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SymbolTable symbolTable;
|
||||
DiagnosticEngine diag;
|
||||
SymbolCollector(symbolTable, diag).collect(ast);
|
||||
|
||||
if (diag.hasErrors()) {
|
||||
diag.printAll(std::cerr);
|
||||
delete ast;
|
||||
for (auto* t : tokens) delete t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
IRGenerator irGenerator;
|
||||
IRProgram program = irGenerator.generate(ast, symbolTable);
|
||||
|
||||
program.dump();
|
||||
|
||||
delete ast;
|
||||
for (auto* t : tokens) delete t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // SAQUT_CLI_IR
|
||||
|
|
@ -1,62 +1,118 @@
|
|||
#include "ir/ir_function.hpp"
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// Her instruction'ı "indeks: OPCODE operandlar" formatında yazdır.
|
||||
// Bu çıktı hem insanın okuduğu hem de birim testlerin karşılaştırdığı formattır.
|
||||
void IRFunction::dump() const {
|
||||
std::cout << "=== " << name
|
||||
<< " (paramCount=" << paramCount
|
||||
<< ", slotCount=" << slotCount << ") ===\n";
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Yardımcılar
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
for (int i = 0; i < (int)instructions.size(); i++) {
|
||||
const Instruction& ins = instructions[i];
|
||||
std::cout << " " << std::setw(3) << i << ": "
|
||||
<< std::left << std::setw(14) << opcodeName(ins.opcode);
|
||||
// Slot adını kısa göster: s0, s1, ...
|
||||
static std::string slot(int s) {
|
||||
if (s == -1) return "?";
|
||||
return "s" + std::to_string(s);
|
||||
}
|
||||
|
||||
switch (ins.opcode) {
|
||||
case Opcode::LOAD_CONST:
|
||||
std::cout << "slot[" << ins.dest << "] = " << ins.intValue;
|
||||
break;
|
||||
case Opcode::LOAD_SLOT:
|
||||
std::cout << "slot[" << ins.dest << "] = slot[" << ins.src << "]";
|
||||
break;
|
||||
// İkili op sembolü: ADD → "+"
|
||||
static const char* opSymbol(Opcode op) {
|
||||
switch (op) {
|
||||
case Opcode::ADD: return "+";
|
||||
case Opcode::SUB: return "-";
|
||||
case Opcode::MUL: return "*";
|
||||
case Opcode::DIV: return "/";
|
||||
case Opcode::MOD: return "%";
|
||||
case Opcode::LESS: return "<";
|
||||
case Opcode::LESS_EQUAL: return "<=";
|
||||
case Opcode::GREATER: return ">";
|
||||
case Opcode::GREATER_EQUAL: return ">=";
|
||||
case Opcode::EQUAL_EQUAL: return "==";
|
||||
case Opcode::NOT_EQUAL: return "!=";
|
||||
default: return "?";
|
||||
}
|
||||
}
|
||||
|
||||
static bool isBinaryOp(Opcode op) {
|
||||
switch (op) {
|
||||
case Opcode::ADD: case Opcode::SUB: case Opcode::MUL:
|
||||
case Opcode::DIV: case Opcode::MOD:
|
||||
case Opcode::LESS: case Opcode::LESS_EQUAL:
|
||||
case Opcode::GREATER: case Opcode::GREATER_EQUAL:
|
||||
case Opcode::EQUAL_EQUAL: case Opcode::NOT_EQUAL:
|
||||
std::cout << "slot[" << ins.dest << "] = "
|
||||
<< "slot[" << ins.left << "] op slot[" << ins.right << "]";
|
||||
break;
|
||||
case Opcode::JMP:
|
||||
return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// IRFunction::dump
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
void IRFunction::dump() const {
|
||||
// Başlık: fonksiyon adı + slot bilgisi
|
||||
std::string header = " " + name + "()";
|
||||
if (paramCount > 0) {
|
||||
header = " " + name + "(";
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
if (i) header += ", ";
|
||||
header += "s" + std::to_string(i);
|
||||
}
|
||||
header += ")";
|
||||
}
|
||||
header += " [" + std::to_string(slotCount) + " slot]";
|
||||
|
||||
// Üst çizgi
|
||||
std::cout << "+-" << std::string(header.size(), '-') << "-+\n";
|
||||
std::cout << "|" << header << " |\n";
|
||||
std::cout << "+-" << std::string(header.size(), '-') << "-+\n";
|
||||
|
||||
// Talimatlar
|
||||
for (int i = 0; i < (int)instructions.size(); i++) {
|
||||
const Instruction& ins = instructions[i];
|
||||
|
||||
// Satır numarası
|
||||
std::cout << " " << std::setw(3) << std::right << i << "│ ";
|
||||
|
||||
// Opcode sütunu (12 karakter genişlik)
|
||||
std::cout << std::left << std::setw(12) << opcodeName(ins.opcode);
|
||||
|
||||
// Operandlar — opcode'a göre farklı format
|
||||
if (ins.opcode == Opcode::LOAD_CONST) {
|
||||
std::cout << slot(ins.dest) << " = " << ins.intValue;
|
||||
|
||||
} else if (ins.opcode == Opcode::LOAD_SLOT) {
|
||||
std::cout << slot(ins.dest) << " = " << slot(ins.src);
|
||||
|
||||
} else if (isBinaryOp(ins.opcode)) {
|
||||
std::cout << slot(ins.dest) << " = "
|
||||
<< slot(ins.left) << " " << opSymbol(ins.opcode)
|
||||
<< " " << slot(ins.right);
|
||||
|
||||
} else if (ins.opcode == Opcode::JMP) {
|
||||
std::cout << "→ " << ins.jumpTarget;
|
||||
break;
|
||||
case Opcode::JIF_FALSE:
|
||||
std::cout << "if !slot[" << ins.cond << "] → " << ins.jumpTarget;
|
||||
break;
|
||||
case Opcode::CALL: {
|
||||
std::cout << "slot[" << ins.dest << "] = " << ins.functionName << "(";
|
||||
|
||||
} else if (ins.opcode == Opcode::JIF_FALSE) {
|
||||
std::cout << "!" << slot(ins.cond) << " → " << ins.jumpTarget;
|
||||
|
||||
} else if (ins.opcode == Opcode::CALL) {
|
||||
std::cout << slot(ins.dest) << " = " << ins.functionName << "(";
|
||||
for (int j = 0; j < (int)ins.argSlots.size(); j++) {
|
||||
if (j) std::cout << ", ";
|
||||
std::cout << "slot[" << ins.argSlots[j] << "]";
|
||||
std::cout << slot(ins.argSlots[j]);
|
||||
}
|
||||
std::cout << ")";
|
||||
break;
|
||||
}
|
||||
case Opcode::RETURN:
|
||||
std::cout << "slot[" << ins.src << "]";
|
||||
break;
|
||||
case Opcode::CALLHOST: {
|
||||
|
||||
} else if (ins.opcode == Opcode::CALLHOST) {
|
||||
std::cout << ins.functionName << "(";
|
||||
for (int j = 0; j < (int)ins.argSlots.size(); j++) {
|
||||
if (j) std::cout << ", ";
|
||||
std::cout << "slot[" << ins.argSlots[j] << "]";
|
||||
std::cout << slot(ins.argSlots[j]);
|
||||
}
|
||||
std::cout << ")";
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (ins.opcode == Opcode::RETURN) {
|
||||
std::cout << slot(ins.src);
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "cli/commands/ast.hpp"
|
||||
#include "cli/commands/symbols.hpp"
|
||||
#include "cli/commands/check.hpp"
|
||||
#include "cli/commands/ir.hpp"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Komutları kaydet
|
||||
|
|
@ -53,6 +54,10 @@ int main(int argc, char* argv[]) {
|
|||
"Semantik analiz — tip denetimi + yapısal doğrulama",
|
||||
false, cmdCheck});
|
||||
|
||||
cli.registerCommand({"ir",
|
||||
"IR talimat listesini göster (ara temsil — bytecode öncesi)",
|
||||
false, cmdIr});
|
||||
|
||||
// --- Gelecek komutlar (TODO) ---
|
||||
cli.registerCommand({"compile",
|
||||
"TODO: Kaynak kodu derle",
|
||||
|
|
|
|||
Loading…
Reference in New Issue