diff options
[IPL/T] Implemented general handling of names as variables
1 files changed, 21 insertions, 11 deletions
| -rw-r--r-- | Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.cpp | 32 |
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"); |
