diff options
Diffstat (limited to 'ast.cpp')
-rw-r--r-- | ast.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -0,0 +1,78 @@ +#include "ast.hpp" + +int ThunkAST::tcount = 0; + +NumberAST::NumberAST(const std::string& n): BaseAST(n) {} + +llvm::Value *NumberAST::codegen(LLVMState& llvmState) const +{ + auto val = llvmState.createInt(std::stoi(name)); + return llvmState.builder.CreateStore(val, llvmState.createPush()); +} + +PushAST::PushAST(const std::string& n): BaseAST(n) {} + +llvm::Value *PushAST::codegen(LLVMState& llvmState) const +{ + if (auto [var, thunk] = Var::lookup(name); var) { + auto dsget = llvmState.createPush(); + if (!thunk) + var = llvmState.builder.CreateLoad(llvmState.inttype, var); + + return llvmState.builder.CreateStore(var, dsget); + } else { + return nullptr; + } +} + +PopAST::PopAST(const std::string& n): BaseAST(n) {} + +llvm::Value *PopAST::codegen(LLVMState& llvmState) const +{ + auto gep = llvmState.createPop(); + auto var = llvmState.createVariable(name); + auto load = llvmState.builder.CreateLoad(llvmState.inttype, gep); + llvmState.builder.CreateStore(load, var, false); + + return Var::addLocal(name, var).value; +} + +CallAST::CallAST(const std::string& n): BaseAST(n) {} + +llvm::Value *CallAST::codegen(LLVMState& llvmState) const +{ + if (auto [var, call] = Var::lookup(name); var) { + if (call) { + return llvmState.builder.CreateCall(llvmState.ftype, var); + } else { + auto val = llvmState.builder.CreateLoad(llvmState.inttype, var); + auto cast = llvmState.builder.CreateIntToPtr(val, + llvmState.inttype->getPointerTo()); + return llvmState.builder.CreateCall(llvmState.ftype, cast); + } + } else { + auto func = llvmState.createFunction(name); + Var::addGlobal(name, Var {func, true}); + return llvmState.builder.CreateCall(llvmState.ftype, func); + } +} + +ThunkAST::ThunkAST(LLVMState& llvmState): + ThunkAST(llvmState, std::string("__t") + std::to_string(tcount++)) {} + +ThunkAST::ThunkAST(LLVMState& llvmState, std::string n): BaseAST(n) +{ + parent = llvmState.builder.saveIP(); + func = llvmState.createFunction(name); + auto BB = llvmState.createEntry(func); + llvmState.builder.SetInsertPoint(BB); +} + +llvm::Value *ThunkAST::codegen(LLVMState& llvmState) const +{ + llvmState.builder.CreateRetVoid(); + llvmState.builder.restoreIP(parent); + + return func; +} + |