diff options
author | Clyne Sullivan <clyne@bitgloo.com> | 2024-06-27 15:22:47 -0400 |
---|---|---|
committer | Clyne Sullivan <clyne@bitgloo.com> | 2024-06-27 15:22:47 -0400 |
commit | 8a6a7a43116021c38d09e590f236be6ebd79eca5 (patch) | |
tree | e6780a51941ad6018437c31d145da18c574d84b7 /main.cpp | |
parent | 69d136281d0a0d7cd36a091a8a8d10f6b2473754 (diff) |
move AST->IR outside of parsing stage
Diffstat (limited to 'main.cpp')
-rw-r--r-- | main.cpp | 77 |
1 files changed, 58 insertions, 19 deletions
@@ -21,6 +21,7 @@ #include <iostream> #include <list> #include <map> +#include <stack> #include <string> #include <string_view> #include <tuple> @@ -30,15 +31,19 @@ #include "parser.hpp" #include "var.hpp" +llvm::Function *curFunc; +llvm::Value *curEnv; + static LLVMState llvmState; -std::list<ThunkAST> scope; +static std::list<ThunkAST> scope; +static std::stack<std::reference_wrapper<ThunkAST>> callstack; static bool parseString(std::string_view sv); +static std::list<ThunkAST>::iterator buildThunk(std::list<ThunkAST>::iterator it); int main() { - Var::pushScope(); - + // 1. Parse code into ThunkASTs, i.e. functions with AST lists for bodies. std::string line; for (unsigned lineno = 1; std::cin.good(); ++lineno) { std::getline(std::cin, line); @@ -48,6 +53,13 @@ int main() } } + // 2. Traverse through thunks in the order they are given in the file and build IR. + Var::pushScope(); + for (auto it = scope.begin(); it != scope.end();) { + it = buildThunk(it); + } + + // 3. Create main() which initiate global vars and calls the top-level thunk. auto func = llvmState.createFunction("main"); auto entry = llvmState.createEntry(func); auto envtype = llvm::VectorType::get(llvmState.inttype, ThunkAST::envidx, false); @@ -59,9 +71,11 @@ int main() llvmState.builder.CreateCall(llvmState.ftype, t0, llvm::ArrayRef<llvm::Value *> {env}); llvmState.builder.CreateRetVoid(); + // 4. Output the IR to stdout. llvmState.output(); std::cerr << "envidx: " << ThunkAST::envidx << std::endl; - std::cout << std::endl; + + return 0; } bool parseString(std::string_view sv) @@ -77,20 +91,11 @@ bool parseString(std::string_view sv) switch (tok) { case Token::ThunkOpen: - scope.emplace_back(llvmState); - Var::pushScope(); + callstack.push(scope.emplace_back()); break; case Token::ThunkClose: - { - auto& thunk = scope.back(); - auto gen = thunk.codegen(llvmState); - if (!gen) - return false; - Var::popScope(); - Var::addLocal(thunk.name, Var {gen, true}); - expr.reset(new PushAST {thunk.name}); - scope.pop_back(); - } + expr.reset(new PushAST {callstack.top().get().name}); + callstack.pop(); break; case Token::Quote: std::cerr << "error: quoting is not supported!" << std::endl; @@ -112,9 +117,8 @@ bool parseString(std::string_view sv) } if (expr) { - if (!scope.empty()) { - if (!expr->codegen(llvmState)) - return false; + if (!callstack.empty()) { + callstack.top().get().ast.emplace_back().swap(expr); } else if (tok != Token::ThunkClose) { std::cerr << "error: non-thunk at top level!" << std::endl; return false; @@ -128,3 +132,38 @@ bool parseString(std::string_view sv) return true; } +std::list<ThunkAST>::iterator buildThunk(std::list<ThunkAST>::iterator it) +{ + auto next = it; + ++next; + + it->beginGen(llvmState); + Var::pushScope(); + + curFunc = it->func; + curEnv = it->env; + + for (auto& a : it->ast) { + if (a->name.starts_with("__t")) { + next = buildThunk(next); + curFunc = it->func; + curEnv = it->env; + } + + if (a->codegen(llvmState) == nullptr) { + return scope.end(); + } + } + + it->endGen(llvmState); + + auto gen = it->codegen(llvmState); + if (!gen) + return scope.end(); + + Var::popScope(); + Var::addLocal(it->name, Var {gen, true}); + scope.erase(it); + return next; +} + |