Summary Files Commits Branches @commit @diff @stats
path: root / Year 2 / Implementation of Programming Languages / Transpiler / src / LLVMVisitor / LLVMVisitor.cpp
diff options
context:
space:
mode:
Commit34ab5a9292118dad0fa3a302282b627b2fc956b9 (patch)
Author
 Syndamia <kamen@syndamia.com>
2023-02-07 21:17:26 +0200
Committer
 Syndamia <kamen@syndamia.com>
2023-02-07 21:17:26 +0200
Files136f7f886d268721d58612d67dfb4c306f8e9aa1 /Year 2/Implementation of Programming Languages/Transpiler/src/LLVMVisitor/LLVMVisitor.cpp
uni-projects-34ab5a9292118dad0fa3a302282b627b2fc956b9.tar
uni-projects-34ab5a9292118dad0fa3a302282b627b2fc956b9.tar.gz
uni-projects-34ab5a9292118dad0fa3a302282b627b2fc956b9.zip
Parent4d359b9c16b01847b26d6827e137f680c65969f2 (diff)
[IPL/T] Implemented general handling of names as variables
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");