diff options
1 files changed, 40 insertions, 5 deletions
| -rw-r--r-- | Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.cpp | 45 |
diff --git a/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.cpp b/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.cpp index d6cdf89..1db9365 100644 --- a/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.cpp +++ b/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.cpp @@ -37,7 +37,7 @@ LLVMRet LLVMVisitor::f_defun(const std::vector<Value*>& args) { outFile << ") {\n"; for (unsigned i = outbodySize; i < outBuf.size(); i++) { - outFile << outBuf[i]; + outFile << "\t" << outBuf[i] << "\n"; } while (outbodySize < outBuf.size()) { outBuf.pop_back(); @@ -60,6 +60,40 @@ LLVMRet LLVMVisitor::f_defvar(funcargs args) { return val; } +LLVMRet LLVMVisitor::f_if(funcargs args) { + LLVMRet boolExpr = args[0]->Visit(*this); + Register rResult = lreg++, + rTrue = lreg++, + rFalse = lreg++, + rCont = (args.size() == 2) ? rFalse : lreg++; + + unsigned reservedI = outBuf.size(); + outBuf.push_back(""); + outBuf.push_back(""); + outBuf.push_back(""); + + LLVMRet tExpr = args[1]->Visit(*this); + + outBuf[reservedI ] = *rResult + " = alloca " + tExpr.type; + outBuf[reservedI+1] = "br " + boolExpr.toStr() + ", label " + *rTrue + ", label " + *rFalse + "\n"; + outBuf[reservedI+2] = "v" + rTrue.headless() + ":"; + + outBuf.push_back("store " + tExpr.toStr() + ", ptr " + *rResult); + outBuf.push_back("br label " + *rCont + "\n"); + + if (args.size() > 2) { + outBuf.push_back("v" + rFalse.headless() + ":"); + LLVMRet fExpr = args[2]->Visit(*this); + outBuf.push_back("store " + fExpr.toStr() + ", ptr " + *rResult); + outBuf.push_back("br label " + *rCont + "\n"); + } + + outBuf.push_back("v" + rCont.headless() + ":"); + Register finalRegister = lreg++; + outBuf.push_back(*finalRegister + " = load " + tExpr.type + ", ptr " + *rResult); + return { tExpr.type, *finalRegister }; +} + LLVMRet LLVMVisitor::nameAsVar(const LLVMRet& ret) { if (!locals.empty()) { auto asLoc = locals.top()->find("%_" + ret.addr); @@ -92,7 +126,7 @@ LLVMRet LLVMVisitor::aritop(const std::string name, const std::vector<Value*>& a if (rightRet.type == "name") rightRet = nameAsVar(rightRet); Register r = lreg++; - outBuf.push_back(*r + " = " + ((leftRet.type == "double") ? "f" : "") + name + " " + leftRet.toStr() + ", " + rightRet.addr + "\n"); + outBuf.push_back(*r + " = " + ((leftRet.type == "double") ? "f" : "") + name + " " + leftRet.toStr() + ", " + rightRet.addr); return { leftRet.type, *r }; } @@ -138,7 +172,7 @@ LLVMRet LLVMVisitor::Visit(const Funcall& vfuncall) { if (arg.addr != pargs.back().addr) out += ", "; } - outBuf.push_back(out += ")\n"); + outBuf.push_back(out += ")"); return { userFuncIt->second.type, valReg }; } @@ -152,14 +186,15 @@ LLVMVisitor::LLVMVisitor(const char* fileName) : outFile(std::ofstream(fileName) funcs_direct.insert({"/", &LLVMVisitor::f_div}); funcs_direct.insert({"defun", &LLVMVisitor::f_defun}); funcs_direct.insert({"defvar", &LLVMVisitor::f_defvar}); + funcs_direct.insert({"if", &LLVMVisitor::f_if}); } void LLVMVisitor::insertMain() { outFile << "define i32 @main() {\n"; for (std::string& codeline : outBuf) { - outFile << codeline; + outFile << "\t" << codeline << "\n"; } - outFile << "ret i32 0\n}\n"; + outFile << "\tret i32 0\n}\n"; } LLVMRet LLVMVisitor::Visit(const Integer& vint) { |
