#include #include #include "LLVMVisitor.h" LLVMVisitor::LLVMVisitor(const char* fileName) : outFile(std::ofstream(fileName)), greg("@v"), lreg("%v") { if (!outFile.is_open()) throw std::runtime_error("Couldn't open file for writing!"); // outFile << "define i32 @main() {\n"; } void LLVMVisitor::finalizeFile() { // outFile << "ret i32 0\n}\n"; } std::string LLVMVisitor::Visit(const Integer& vint) { return std::to_string(vint.get_value()); } std::string LLVMVisitor::Visit(const Float& vfloat) { return std::to_string(vfloat.get_value()); } std::string LLVMVisitor::Visit(const Name& vname) { return vname.get_value(); } std::string LLVMVisitor::Visit(const Funcall& vfuncall) { if (std::find(gfuncs.begin(), gfuncs.end(), vfuncall) == gfuncs.end()) throw std::runtime_error("Function doesn't exist!"); std::vector pargs; for (Value* arg : vfuncall.get_args()) pargs.push_back(arg->Visit(*this)); std::string valReg = *(lreg++); outFile << valReg << " = call i32 " << vfuncall.get_funname() << "("; for (std::string arg : pargs) outFile << "i32 " << arg << ", "; outFile << ")\n"; return valReg; } void f_add(std::string reg, Value::T_Primitive ty, std::string first, std::string second, std::ofstream& of) { of << reg << " = "; switch(ty) { case Value::T_integer: of << "add i32"; break; case Value::T_float: of << "fadd double"; break; default: throw std::runtime_error("Invalid type for function!"); } of << " " << first << ", " << second << "\n"; } void f_sub(std::string reg, Value::T_Primitive ret, std::string first, std::string second, std::ofstream& of) { of << reg << " = "; switch(ret) { case Value::T_integer: of << "sub i32"; break; case Value::T_float: of << "fsub double"; break; default: throw std::runtime_error("Invalid type for function!"); } of << " " << first << ", " << second << "\n"; } std::string LLVMVisitor::rightAssoc(BiFout f, const BuiltInFunction& bfun, unsigned i) { std::string leftArg = bfun.get_args()[i]->Visit(*this); std::string rightArg; if (bfun.get_args().size() - 2 == i) rightArg = bfun.get_args()[i+1]->Visit(*this); else rightArg = rightAssoc(f, bfun, i+1); std::string valRegister = *(lreg++); f(valRegister, bfun.RetType(), leftArg, rightArg, outFile); return valRegister; } std::string LLVMVisitor::Visit(const BuiltInFunction& bfun) { if (bfun.get_name() == "+") return rightAssoc(f_add, bfun); if (bfun.get_name() == "-") return rightAssoc(f_sub, bfun); return ""; }