use less temporaries
This commit is contained in:
parent
577581f2ce
commit
d46f7fb91f
|
@ -3,6 +3,11 @@
|
||||||
|
|
||||||
namespace xlang {
|
namespace xlang {
|
||||||
|
|
||||||
|
std::string EmitVisitor::tmp() {
|
||||||
|
last = "%t" + std::to_string(tmpcount++);
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
EmitVisitor::EmitVisitor(std::string_view outputfile) : output{outputfile} {}
|
EmitVisitor::EmitVisitor(std::string_view outputfile) : output{outputfile} {}
|
||||||
|
|
||||||
std::any EmitVisitor::visitFile(xlangParser::FileContext *ctx) {
|
std::any EmitVisitor::visitFile(xlangParser::FileContext *ctx) {
|
||||||
|
@ -32,8 +37,8 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
|
||||||
if (auto identifier = ctx->Identifier()) {
|
if (auto identifier = ctx->Identifier()) {
|
||||||
tmpcount = 0;
|
tmpcount = 0;
|
||||||
visitExpr(ctx->expr());
|
visitExpr(ctx->expr());
|
||||||
output << " %_" << identifier->getSymbol()->getText() << " = w copy %t"
|
output << " %_" << identifier->getSymbol()->getText() << " = w copy "
|
||||||
<< tmpcount - 1 << std::endl;
|
<< last << std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (ctx->If()) {
|
if (ctx->If()) {
|
||||||
|
@ -41,8 +46,8 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
|
||||||
output << "@if" << block << "_expr" << std::endl;
|
output << "@if" << block << "_expr" << std::endl;
|
||||||
tmpcount = 0;
|
tmpcount = 0;
|
||||||
visitExpr(ctx->expr());
|
visitExpr(ctx->expr());
|
||||||
output << " jnz %t" << tmpcount - 1 << ", @if" << block << "_then, @if"
|
output << " jnz " << last << ", @if" << block << "_then, @if" << block
|
||||||
<< block << "_else" << std::endl;
|
<< "_else" << std::endl;
|
||||||
output << "@if" << block << "_then" << std::endl;
|
output << "@if" << block << "_then" << std::endl;
|
||||||
visitBlock(ctx->block(0));
|
visitBlock(ctx->block(0));
|
||||||
output << " jmp @if" << block << "_end" << std::endl;
|
output << " jmp @if" << block << "_end" << std::endl;
|
||||||
|
@ -58,8 +63,8 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
|
||||||
output << "@while" << block << "_expr" << std::endl;
|
output << "@while" << block << "_expr" << std::endl;
|
||||||
tmpcount = 0;
|
tmpcount = 0;
|
||||||
visitExpr(ctx->expr());
|
visitExpr(ctx->expr());
|
||||||
output << " jnz %t" << tmpcount - 1 << ", @while" << block
|
output << " jnz " << last << ", @while" << block << "_body, @while"
|
||||||
<< "_body, @while" << block << "_end" << std::endl;
|
<< block << "_end" << std::endl;
|
||||||
output << "@while" << block << "_body" << std::endl;
|
output << "@while" << block << "_body" << std::endl;
|
||||||
visitBlock(ctx->block(0));
|
visitBlock(ctx->block(0));
|
||||||
output << " jmp @while" << block << "_expr" << std::endl;
|
output << " jmp @while" << block << "_expr" << std::endl;
|
||||||
|
@ -69,14 +74,14 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
|
||||||
if (ctx->Return()) {
|
if (ctx->Return()) {
|
||||||
tmpcount = 0;
|
tmpcount = 0;
|
||||||
visitExpr(ctx->expr());
|
visitExpr(ctx->expr());
|
||||||
output << " ret %t" << tmpcount - 1 << std::endl;
|
output << " ret " << last << std::endl;
|
||||||
output << "@dead" << blockcount++ << std::endl;
|
output << "@dead" << blockcount++ << std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (ctx->Print()) {
|
if (ctx->Print()) {
|
||||||
tmpcount = 0;
|
tmpcount = 0;
|
||||||
visitExpr(ctx->expr());
|
visitExpr(ctx->expr());
|
||||||
output << " call $printf(l $printformat, ..., w %t" << tmpcount - 1 << ")"
|
output << " call $printf(l $printformat, ..., w " << last << ")"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -84,15 +89,15 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPERATOR(Operator, visitLeft, left, visitRight, right, ssa_op) \
|
#define OPERATOR(Operator, visitLeft, left, visitRight, right, ssa_op) \
|
||||||
if (ctx->Operator()) { \
|
if (ctx->Operator()) { \
|
||||||
visitLeft(ctx->left); \
|
visitLeft(ctx->left); \
|
||||||
int l = tmpcount - 1; \
|
std::string l = last; \
|
||||||
visitRight(ctx->right); \
|
visitRight(ctx->right); \
|
||||||
output << " %t" << tmpcount << " = w " ssa_op " %t" << l << ", %t" \
|
std::string r = last; \
|
||||||
<< tmpcount - 1 << std::endl; \
|
output << " " << tmp() << " = w " ssa_op " " << l << ", " << r \
|
||||||
tmpcount++; \
|
<< std::endl; \
|
||||||
return {}; \
|
return {}; \
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any EmitVisitor::visitExpr(xlangParser::ExprContext *ctx) {
|
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) {
|
std::any EmitVisitor::visitFactor(xlangParser::FactorContext *ctx) {
|
||||||
if (auto integer = ctx->Integer()) {
|
if (auto integer = ctx->Integer()) {
|
||||||
output << " %t" << tmpcount++ << " = w copy "
|
last = integer->getSymbol()->getText();
|
||||||
<< integer->getSymbol()->getText() << std::endl;
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (auto identifier = ctx->Identifier()) {
|
if (auto identifier = ctx->Identifier()) {
|
||||||
if (ctx->LeftParen()) {
|
if (ctx->LeftParen()) {
|
||||||
std::vector<int> args;
|
std::vector<std::string> args;
|
||||||
if (auto expr_list = ctx->exprList()) {
|
if (auto expr_list = ctx->exprList()) {
|
||||||
for (auto expr : expr_list->expr()) {
|
for (auto expr : expr_list->expr()) {
|
||||||
visitExpr(expr);
|
visitExpr(expr);
|
||||||
args.push_back(tmpcount - 1);
|
args.push_back(last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output << " %t" << tmpcount++ << " = w call $"
|
output << " " << tmp() << " = w call $"
|
||||||
<< identifier->getSymbol()->getText() << "(";
|
<< identifier->getSymbol()->getText() << "(";
|
||||||
for (auto arg : args) {
|
for (auto arg : args) {
|
||||||
output << "w %t" << arg << ", ";
|
output << "w " << arg << ", ";
|
||||||
}
|
}
|
||||||
output << ")" << std::endl;
|
output << ")" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
output << " %t" << tmpcount++ << " = w copy %_"
|
last = "%_" + identifier->getSymbol()->getText();
|
||||||
<< identifier->getSymbol()->getText() << std::endl;
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <xlangBaseVisitor.h>
|
#include <xlangBaseVisitor.h>
|
||||||
|
|
||||||
|
@ -10,6 +11,9 @@ class EmitVisitor : public xlangBaseVisitor {
|
||||||
std::ofstream output;
|
std::ofstream output;
|
||||||
int blockcount;
|
int blockcount;
|
||||||
int tmpcount;
|
int tmpcount;
|
||||||
|
std::string last;
|
||||||
|
|
||||||
|
std::string tmp();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EmitVisitor(std::string_view outputfile);
|
EmitVisitor(std::string_view outputfile);
|
||||||
|
|
Loading…
Reference in a new issue