From 7929b59b60c87f8618bc3b2ae4ec7461d3c190e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Grennerat?= Date: Wed, 4 Mar 2026 11:56:25 +0100 Subject: [PATCH] Operations support with temp expressions values in stack --- compiler/CodeGenVisitor.cpp | 46 +++++++++++++++++++++++++++++---- compiler/CodeGenVisitor.h | 3 +++ compiler/DeclarationVisitor.cpp | 12 --------- compiler/DeclarationVisitor.h | 16 +++++++++--- compiler/ifcc.g4 | 21 ++++++++++++--- testfiles/5_expr.c | 7 +++++ 6 files changed, 82 insertions(+), 23 deletions(-) create mode 100644 testfiles/5_expr.c diff --git a/compiler/CodeGenVisitor.cpp b/compiler/CodeGenVisitor.cpp index 7d8a712..88986f5 100644 --- a/compiler/CodeGenVisitor.cpp +++ b/compiler/CodeGenVisitor.cpp @@ -27,6 +27,11 @@ std::any CodeGenVisitor::visitProg(ifccParser::ProgContext *ctx) { std::any CodeGenVisitor::visitStmt(ifccParser::StmtContext *ctx) { std::cout << " ;" << ctx->getText() << "\n"; return this->visitChildren(ctx); + +} +std::any CodeGenVisitor::visitReturn_stmt(ifccParser::Return_stmtContext *ctx) { + this->visit(ctx->expr()); + return 0; } // Declaration pass already filled the symbol table: nothing to do here. @@ -37,9 +42,9 @@ std::any CodeGenVisitor::visitDecl_stmt(ifccParser::Decl_stmtContext *ctx) { // 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); + int offset = symbolTable->getOffset(currentScope(), name) + stackOffset; - this->visit(ctx->val()); + this->visit(ctx->expr()); #ifdef __APPLE__ std::cout << " str w0, [sp, #" << offset << "]\n"; @@ -64,7 +69,7 @@ std::any CodeGenVisitor::visitVal(ifccParser::ValContext *ctx) { } std::string name = ctx->VAR_NAME()->getText(); - int offset = symbolTable->getOffset(currentScope(), name); + int offset = symbolTable->getOffset(currentScope(), name) + stackOffset; symbolTable->isInitialized(currentScope(), name); // emits warning if needed #ifdef __APPLE__ @@ -76,7 +81,38 @@ std::any CodeGenVisitor::visitVal(ifccParser::ValContext *ctx) { return offset; } -std::any CodeGenVisitor::visitReturn_stmt(ifccParser::Return_stmtContext *ctx) { - this->visit(ctx->val()); +std::any CodeGenVisitor::visitExpr(ifccParser::ExprContext *ctx) { + // Parenthesized expression or single val: delegate directly + if (ctx->expr().size() == 1) { + return this->visit(ctx->expr(0)); + } + if (ctx->expr().empty()) { + return this->visit(ctx->val()); + } + + // Evaluate left, push result onto stack to survive nested sub-expressions + this->visit(ctx->expr(0)); +#ifdef __APPLE__ + std::cout << " str w0, [sp, #-16]!\n"; // sp -= 16, push -> [sp] +#else + std::cout << " pushq %rax\n"; +#endif + stackOffset += 16; + + // Evaluate right, result in w0 / eax + this->visit(ctx->expr(1)); + +#ifdef __APPLE__ + std::cout << " ldr w8, [sp], #16\n"; // pop -> w8, sp += 16 + if (ctx->MUL()) std::cout << " mul w0, w8, w0\n"; + else if (ctx->DIV()) std::cout << " sdiv w0, w8, w0\n"; + else if (ctx->ADD()) std::cout << " add w0, w8, w0\n"; + else if (ctx->SUB()) std::cout << " sub w0, w8, w0\n"; +#else + +#endif + + stackOffset -= 16; return 0; } + diff --git a/compiler/CodeGenVisitor.h b/compiler/CodeGenVisitor.h index ccefcc5..d29af09 100644 --- a/compiler/CodeGenVisitor.h +++ b/compiler/CodeGenVisitor.h @@ -10,6 +10,7 @@ class CodeGenVisitor : public ifccBaseVisitor { SymbolTable *symbolTable; // shared, not owned std::vector scopeStack; // navigation state, owned by this visitor + int stackOffset = 0; // When adding additional information to the stack such as temp expressions results, sp gets decremented and this offset keeps track of how much std::string currentScope() const { return scopeStack.back(); } @@ -28,4 +29,6 @@ public: std::any visitSet_stmt(ifccParser::Set_stmtContext *ctx) override; std::any visitVal(ifccParser::ValContext *ctx) override; + + std::any visitExpr(ifccParser::ExprContext *ctx) override; }; diff --git a/compiler/DeclarationVisitor.cpp b/compiler/DeclarationVisitor.cpp index 24866d7..34bcc7f 100644 --- a/compiler/DeclarationVisitor.cpp +++ b/compiler/DeclarationVisitor.cpp @@ -22,15 +22,3 @@ std::any DeclarationVisitor::visitDecl_stmt(ifccParser::Decl_stmtContext *ctx) { } return 0; } - -std::any DeclarationVisitor::visitSet_stmt(ifccParser::Set_stmtContext *ctx) { - return 0; -} - -std::any DeclarationVisitor::visitVal(ifccParser::ValContext *ctx) { - return 0; -} - -std::any DeclarationVisitor::visitReturn_stmt(ifccParser::Return_stmtContext *ctx) { - return 0; -} diff --git a/compiler/DeclarationVisitor.h b/compiler/DeclarationVisitor.h index 017893a..c8112df 100644 --- a/compiler/DeclarationVisitor.h +++ b/compiler/DeclarationVisitor.h @@ -27,13 +27,23 @@ public: std::any visitStmt(ifccParser::StmtContext *ctx) override; - std::any visitReturn_stmt(ifccParser::Return_stmtContext *ctx) override; + std::any visitReturn_stmt(ifccParser::Return_stmtContext *ctx) override { + return 0; + } std::any visitDecl_stmt(ifccParser::Decl_stmtContext *ctx) override; - std::any visitSet_stmt(ifccParser::Set_stmtContext *ctx) override; + std::any visitSet_stmt(ifccParser::Set_stmtContext *ctx) override { + return 0; + } - std::any visitVal(ifccParser::ValContext *ctx) override; + std::any visitVal(ifccParser::ValContext *ctx) override { + return 0; + } + + std::any visitExpr(ifccParser::ExprContext *ctx) override { + return 0; + } }; diff --git a/compiler/ifcc.g4 b/compiler/ifcc.g4 index 3dd64af..41876bf 100644 --- a/compiler/ifcc.g4 +++ b/compiler/ifcc.g4 @@ -6,12 +6,27 @@ prog: 'int' 'main' '(' ')' '{' stmt* '}' ; stmt: decl_stmt | set_stmt | return_stmt ; -return_stmt: RETURN val ';' ; +return_stmt: RETURN expr ';' ; decl_stmt: 'int' (VAR_NAME ',')* VAR_NAME ';' ; -set_stmt: VAR_NAME '=' val ';' ; +set_stmt: VAR_NAME '=' expr ';' ; -val: CONST | VAR_NAME ; +val: CONST | VAR_NAME; + +expr: expr MUL expr + | expr DIV expr + | expr ADD expr + | expr SUB expr + | '(' expr ')' + | val + ; + + + +MUL : '*' ; +DIV : '/' ; +ADD : '+' ; +SUB : '-' ; RETURN : 'return' ; CONST : [0-9]+ ; diff --git a/testfiles/5_expr.c b/testfiles/5_expr.c new file mode 100644 index 0000000..de8c96e --- /dev/null +++ b/testfiles/5_expr.c @@ -0,0 +1,7 @@ +int main() { + int x; + int y; + x = 42; + y = 8; + return (x + y) * (x - y) / (x * y); +}