4IFS2-COMP-PLD/compiler/CodeGenVisitor.cpp
2026-03-04 10:54:23 +01:00

83 lines
2.3 KiB
C++

#include "CodeGenVisitor.h"
#include "generated/ifccParser.h"
std::any CodeGenVisitor::visitProg(ifccParser::ProgContext *ctx) {
scopeStack.push_back("main");
int size = symbolTable->stackSize(currentScope());
#ifdef __APPLE__
std::cout << ".globl _main\n_main:\n";
std::cout << " sub sp, sp, #" << size << "\n";
#else
std::cout << ".globl main\nmain:\n";
std::cout << " subq $" << size << ", %rsp\n";
#endif
this->visitChildren(ctx);
#ifdef __APPLE__
std::cout << " add sp, sp, #" << size << "\n";
#else
std::cout << " addq $" << size << ", %rsp\n";
#endif
std::cout << " ret\n";
scopeStack.pop_back();
return 0;
}
std::any CodeGenVisitor::visitStmt(ifccParser::StmtContext *ctx) {
std::cout << " ;" << ctx->getText() << "\n";
return this->visitChildren(ctx);
}
// Declaration pass already filled the symbol table: nothing to do here.
std::any CodeGenVisitor::visitDecl_stmt(ifccParser::Decl_stmtContext *ctx) {
return 0;
}
// Assign a value to a variable: evaluate val, store on stack, mark as initialized.
std::any CodeGenVisitor::visitSet_stmt(ifccParser::Set_stmtContext *ctx) {
std::string name = ctx->VAR_NAME()->getText();
int offset = symbolTable->getOffset(currentScope(), name);
this->visit(ctx->val());
#ifdef __APPLE__
std::cout << " str w0, [sp, #" << offset << "]\n";
#else
std::cout << " movl %eax, " << offset << "(%rsp)\n";
#endif
symbolTable->markInitialized(currentScope(), name);
return 0;
}
// Load a constant or variable into the accumulator register.
std::any CodeGenVisitor::visitVal(ifccParser::ValContext *ctx) {
if (ctx->CONST()) {
int val = stoi(ctx->CONST()->getText());
#ifdef __APPLE__
std::cout << " mov w0, #" << val << "\n";
#else
std::cout << " movl $" << val << ", %eax\n";
#endif
return val;
}
std::string name = ctx->VAR_NAME()->getText();
int offset = symbolTable->getOffset(currentScope(), name);
symbolTable->isInitialized(currentScope(), name); // emits warning if needed
#ifdef __APPLE__
std::cout << " ldr w0, [sp, #" << offset << "]\n";
#else
std::cout << " movl " << offset << "(%rsp), %eax\n";
#endif
return offset;
}
std::any CodeGenVisitor::visitReturn_stmt(ifccParser::Return_stmtContext *ctx) {
this->visit(ctx->val());
return 0;
}