diff options
| Commit | 34ab5a9292118dad0fa3a302282b627b2fc956b9 (patch) | |
|---|---|---|
| Author | 2023-02-07 21:17:26 +0200 | |
| Committer | 2023-02-07 21:17:26 +0200 | |
| Files | 136f7f886d268721d58612d67dfb4c306f8e9aa1 | |
| uni-projects-34ab5a9292118dad0fa3a302282b627b2fc956b9.tar uni-projects-34ab5a9292118dad0fa3a302282b627b2fc956b9.tar.gz uni-projects-34ab5a9292118dad0fa3a302282b627b2fc956b9.zip | ||
| Parent | 4d359b9c16b01847b26d6827e137f680c65969f2 (diff) | |
[IPL/T] Implemented general handling of names as variables
2 files changed, 24 insertions, 12 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 98af7f8..0424d04 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 @@ -21,14 +21,16 @@ LLVMRet LLVMVisitor::f_defun(const std::vector<Value*>& args) { funcRet = args[i]->Visit(*this); } - std::map<std::string, LLVMRet> locals; + std::map<std::string, LLVMRet> localVars; + locals.push(&localVars); + outFile << "define " << funcRet.type << " @" << fname->get_value() << "("; for (Value* v : fargs->get_value()) { std::string name = "%_" + static_cast<Name*>(v)->get_value(); // TODO: figure out argument type, based on usage outFile << "i32 " << name; - locals.insert({ name, { "i32", name } }); + localVars.insert({ name, { "i32", name } }); if (v != fargs->get_value().back()) outFile << ", "; } @@ -42,25 +44,30 @@ LLVMRet LLVMVisitor::f_defun(const std::vector<Value*>& args) { } outFile << "\tret " << funcRet << "\n}\n\n"; + locals.pop(); return { funcRet.type, "@" + fname->get_value() }; } -LLVMRet LLVMVisitor::nameAsVar(const Name* name, std::map<std::string, LLVMRet>& locals) { - auto asLoc = locals.find("%_" + name->get_value()); - if (asLoc != locals.end()) - return asLoc->second; +LLVMRet LLVMVisitor::nameAsVar(const LLVMRet& ret) { + if (!locals.empty()) { + auto asLoc = locals.top()->find("%_" + ret.addr); + if (asLoc != locals.top()->end()) + return asLoc->second; + } - auto asVar = vars_user.find("@" + name->get_value()); + auto asVar = vars_user.find("@" + ret.addr); if (asVar != vars_user.end()) return asVar->second; - auto asFunc = funcs_user.find("@" + name->get_value()); + auto asFunc = funcs_user.find("@" + ret.addr); if (asFunc != funcs_user.end()) return asFunc->second; // TODO: try to figure out type (f_defun) - LLVMRet newLocal = { "i32", "%_" + name->get_value() }; - locals.insert({ newLocal.addr, newLocal }); + LLVMRet newLocal = { "i32", "%_" + ret.addr }; + if (!locals.empty()) { + locals.top()->insert({ newLocal.addr, newLocal }); + } return newLocal; } @@ -68,7 +75,10 @@ LLVMRet LLVMVisitor::aritop(const std::string name, const std::vector<Value*>& a LLVMRet leftRet = args[astart]->Visit(*this); LLVMRet rightRet = (args.size() - astart > 2) ? aritop(name, args, astart+1) : args[astart+1]->Visit(*this); - + + if (leftRet.type == "name") leftRet = nameAsVar(leftRet); + if (rightRet.type == "name") rightRet = nameAsVar(rightRet); + Register r = lreg++; outBuf.push_back(*r + " = " + ((leftRet.type == "double") ? "f" : "") + name + " " + leftRet.toStr() + ", " + rightRet.addr + "\n"); 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 65c6498..9929dda 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 @@ -6,6 +6,7 @@ #include <map> #include <algorithm> #include <functional> +#include <stack> #include "Register.h" #include "LLVMVisitorReturn.h" #include "../Value/Integer.h" @@ -24,12 +25,13 @@ class LLVMVisitor { typedef const std::vector<Value*>& funcargs; LLVMRet f_defun(funcargs args); - LLVMRet nameAsVar(const Name* name, std::map<std::string, LLVMRet>& locals); + LLVMRet nameAsVar(const LLVMRet& ret); LLVMRet aritop(const std::string name, funcargs args, unsigned astart = 0); LLVMRet f_add(funcargs args); LLVMRet f_sub(funcargs args); + std::stack<std::map<std::string, LLVMRet>*> locals; std::map<std::string, LLVMRet> funcs_user; std::map<std::string, LLVMRet> vars_user; |
