diff --git a/bootstrap/emit.cc b/bootstrap/emit.cc index 8f50004..1e6e3c1 100644 --- a/bootstrap/emit.cc +++ b/bootstrap/emit.cc @@ -3,6 +3,11 @@ namespace xlang { +std::string EmitVisitor::tmp() { + last = "%t" + std::to_string(tmpcount++); + return last; +} + EmitVisitor::EmitVisitor(std::string_view outputfile) : output{outputfile} {} std::any EmitVisitor::visitFile(xlangParser::FileContext *ctx) { @@ -32,8 +37,8 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) { if (auto identifier = ctx->Identifier()) { tmpcount = 0; visitExpr(ctx->expr()); - output << " %_" << identifier->getSymbol()->getText() << " = w copy %t" - << tmpcount - 1 << std::endl; + output << " %_" << identifier->getSymbol()->getText() << " = w copy " + << last << std::endl; return {}; } if (ctx->If()) { @@ -41,8 +46,8 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) { output << "@if" << block << "_expr" << std::endl; tmpcount = 0; visitExpr(ctx->expr()); - output << " jnz %t" << tmpcount - 1 << ", @if" << block << "_then, @if" - << block << "_else" << std::endl; + output << " jnz " << last << ", @if" << block << "_then, @if" << block + << "_else" << std::endl; output << "@if" << block << "_then" << std::endl; visitBlock(ctx->block(0)); output << " jmp @if" << block << "_end" << std::endl; @@ -58,8 +63,8 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) { output << "@while" << block << "_expr" << std::endl; tmpcount = 0; visitExpr(ctx->expr()); - output << " jnz %t" << tmpcount - 1 << ", @while" << block - << "_body, @while" << block << "_end" << std::endl; + output << " jnz " << last << ", @while" << block << "_body, @while" + << block << "_end" << std::endl; output << "@while" << block << "_body" << std::endl; visitBlock(ctx->block(0)); output << " jmp @while" << block << "_expr" << std::endl; @@ -69,14 +74,14 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) { if (ctx->Return()) { tmpcount = 0; visitExpr(ctx->expr()); - output << " ret %t" << tmpcount - 1 << std::endl; + output << " ret " << last << std::endl; output << "@dead" << blockcount++ << std::endl; return {}; } if (ctx->Print()) { tmpcount = 0; visitExpr(ctx->expr()); - output << " call $printf(l $printformat, ..., w %t" << tmpcount - 1 << ")" + output << " call $printf(l $printformat, ..., w " << last << ")" << std::endl; return {}; } @@ -84,15 +89,15 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) { return {}; } -#define OPERATOR(Operator, visitLeft, left, visitRight, right, ssa_op) \ - if (ctx->Operator()) { \ - visitLeft(ctx->left); \ - int l = tmpcount - 1; \ - visitRight(ctx->right); \ - output << " %t" << tmpcount << " = w " ssa_op " %t" << l << ", %t" \ - << tmpcount - 1 << std::endl; \ - tmpcount++; \ - return {}; \ +#define OPERATOR(Operator, visitLeft, left, visitRight, right, ssa_op) \ + if (ctx->Operator()) { \ + visitLeft(ctx->left); \ + std::string l = last; \ + visitRight(ctx->right); \ + std::string r = last; \ + output << " " << tmp() << " = w " ssa_op " " << l << ", " << r \ + << std::endl; \ + return {}; \ } std::any EmitVisitor::visitExpr(xlangParser::ExprContext *ctx) { @@ -122,28 +127,26 @@ std::any EmitVisitor::visitTerm(xlangParser::TermContext *ctx) { std::any EmitVisitor::visitFactor(xlangParser::FactorContext *ctx) { if (auto integer = ctx->Integer()) { - output << " %t" << tmpcount++ << " = w copy " - << integer->getSymbol()->getText() << std::endl; + last = integer->getSymbol()->getText(); return {}; } if (auto identifier = ctx->Identifier()) { if (ctx->LeftParen()) { - std::vector args; + std::vector args; if (auto expr_list = ctx->exprList()) { for (auto expr : expr_list->expr()) { visitExpr(expr); - args.push_back(tmpcount - 1); + args.push_back(last); } } - output << " %t" << tmpcount++ << " = w call $" + output << " " << tmp() << " = w call $" << identifier->getSymbol()->getText() << "("; for (auto arg : args) { - output << "w %t" << arg << ", "; + output << "w " << arg << ", "; } output << ")" << std::endl; } else { - output << " %t" << tmpcount++ << " = w copy %_" - << identifier->getSymbol()->getText() << std::endl; + last = "%_" + identifier->getSymbol()->getText(); } return {}; } diff --git a/bootstrap/emit.hh b/bootstrap/emit.hh index 38ff861..7f1a3dc 100644 --- a/bootstrap/emit.hh +++ b/bootstrap/emit.hh @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -10,6 +11,9 @@ class EmitVisitor : public xlangBaseVisitor { std::ofstream output; int blockcount; int tmpcount; + std::string last; + + std::string tmp(); public: EmitVisitor(std::string_view outputfile);