|
|
|
#include <algorithm>
|
|
|
|
#include <cctype>
|
|
|
|
#include <iostream>
|
|
|
|
#include <list>
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
#include <string_view>
|
|
|
|
#include <tuple>
|
|
|
|
|
|
|
|
#include "ast.hpp"
|
|
|
|
#include "llvm.hpp"
|
|
|
|
#include "parser.hpp"
|
|
|
|
#include "var.hpp"
|
|
|
|
|
|
|
|
static LLVMState llvmState;
|
|
|
|
static std::list<ThunkAST> scope;
|
|
|
|
|
|
|
|
static bool parseString(std::string_view sv);
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
Var::pushScope();
|
|
|
|
|
|
|
|
std::string line;
|
|
|
|
while (std::cin.good()) {
|
|
|
|
std::getline(std::cin, line);
|
|
|
|
parseString(line);
|
|
|
|
//std::cout << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvmState.output();
|
|
|
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool parseString(std::string_view sv)
|
|
|
|
{
|
|
|
|
do {
|
|
|
|
const auto [nsv, tok] = nextToken(sv);
|
|
|
|
|
|
|
|
//printToken(tok);
|
|
|
|
|
|
|
|
if (tok == Token::none && !nsv.empty()) {
|
|
|
|
std::cerr << "unknown " << nsv << std::endl;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
std::unique_ptr<BaseAST> expr;
|
|
|
|
|
|
|
|
switch (tok) {
|
|
|
|
case Token::ThunkOpen:
|
|
|
|
if (scope.empty())
|
|
|
|
scope.emplace_back(llvmState, "main");
|
|
|
|
else
|
|
|
|
scope.emplace_back(llvmState);
|
|
|
|
Var::pushScope();
|
|
|
|
break;
|
|
|
|
case Token::ThunkClose:
|
|
|
|
{
|
|
|
|
auto& thunk = scope.back();
|
|
|
|
auto gen = thunk.codegen(llvmState);
|
|
|
|
Var::popScope();
|
|
|
|
Var::addLocal(thunk.name, Var {gen, true});
|
|
|
|
expr.reset(new PushAST {thunk.name});
|
|
|
|
scope.pop_back();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Token::Quote:
|
|
|
|
break;
|
|
|
|
case Token::PopVar:
|
|
|
|
expr.reset(new PopAST {name});
|
|
|
|
break;
|
|
|
|
case Token::PushVar:
|
|
|
|
expr.reset(new PushAST {name});
|
|
|
|
break;
|
|
|
|
case Token::Var:
|
|
|
|
expr.reset(new CallAST {name});
|
|
|
|
break;
|
|
|
|
case Token::Number:
|
|
|
|
expr.reset(new NumberAST {name});
|
|
|
|
break;
|
|
|
|
case Token::none:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (expr && !scope.empty()) {
|
|
|
|
expr->codegen(llvmState);
|
|
|
|
//scope.back().body.emplace_back().swap(expr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sv = nsv;
|
|
|
|
} while (!sv.empty());
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|