diff options
| Commit | b21256461dae9546f6690ff3b1ea53d4c508f252 (patch) | |
|---|---|---|
| Author | 2023-02-07 23:34:43 +0200 | |
| Committer | 2023-02-07 23:34:43 +0200 | |
| Files | 867a6a286a51b94f09ceed206770d4bd241a3ff8 | |
| uni-projects-b21256461dae9546f6690ff3b1ea53d4c508f252.tar uni-projects-b21256461dae9546f6690ff3b1ea53d4c508f252.tar.gz uni-projects-b21256461dae9546f6690ff3b1ea53d4c508f252.zip | ||
| Parent | 95dfe7c4df8482c7b83a816917cb27605ceb3076 (diff) | |
[IPL/T] Implemented if, without boolean algebra
5 files changed, 52 insertions, 6 deletions
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) { diff --git a/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.h b/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.h index a79d75c..a71219b 100644 --- a/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.h +++ b/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.h @@ -26,6 +26,7 @@ class LLVMVisitor { typedef const std::vector<Value*>& funcargs; LLVMRet f_defun(funcargs args); LLVMRet f_defvar(funcargs args); + LLVMRet f_if(funcargs args); LLVMRet nameAsVar(const LLVMRet& ret); LLVMRet aritop(const std::string name, funcargs args, unsigned astart = 0); diff --git a/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/Register.cpp b/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/Register.cpp index 5d125a7..329e1ba 100644 --- a/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/Register.cpp +++ b/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/Register.cpp @@ -21,6 +21,10 @@ void Register::reset() { counter = 0; } +std::string Register::headless() { + return std::to_string(counter); +} + std::ostream& operator<<(std::ostream& ostr, const Register& reg) { return ostr << *reg; } diff --git a/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/Register.h b/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/Register.h index ff51129..40592e7 100644 --- a/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/Register.h +++ b/Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/Register.h @@ -14,6 +14,7 @@ public: Register operator++(int); std::string operator*() const; void reset(); + std::string headless(); }; std::ostream& operator<<(std::ostream& ostr, const Register& reg); diff --git a/Year 2/Implementation of Programming Languages/Transpiler/src/main.cpp b/Year 2/Implementation of Programming Languages/Transpiler/src/main.cpp index 3efc904..4d58dc7 100644 --- a/Year 2/Implementation of Programming Languages/Transpiler/src/main.cpp +++ b/Year 2/Implementation of Programming Languages/Transpiler/src/main.cpp @@ -22,7 +22,12 @@ int main() { new Integer(7), new Name("a"), new Name("b") - }) }) + }), + new Funcall("if", { + new Integer(5), + new Funcall("+", { new Integer(1), new Integer(2) }), + new Funcall("-", { new Integer(3), new Integer(4) }) + })}) }; for (Value* n : nodes) { n->Visit(visitor); |
