Operations support with temp expressions values in stack
This commit is contained in:
parent
906759a515
commit
7929b59b60
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
class CodeGenVisitor : public ifccBaseVisitor {
|
||||
SymbolTable *symbolTable; // shared, not owned
|
||||
std::vector<std::string> 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;
|
||||
};
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -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]+ ;
|
||||
|
||||
7
testfiles/5_expr.c
Normal file
7
testfiles/5_expr.c
Normal file
@ -0,0 +1,7 @@
|
||||
int main() {
|
||||
int x;
|
||||
int y;
|
||||
x = 42;
|
||||
y = 8;
|
||||
return (x + y) * (x - y) / (x * y);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user