#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; }