diff options
-rw-r--r-- | src/c.cpp | 3 | ||||
-rw-r--r-- | src/compile.cpp | 18 | ||||
-rw-r--r-- | src/llvm.cpp | 6 | ||||
-rw-r--r-- | src/repl.cpp | 98 | ||||
-rw-r--r-- | src/resp.hpp | 7 |
5 files changed, 73 insertions, 59 deletions
@@ -42,7 +42,6 @@ struct CEngine : public Engine { } CFunc startFn(CEnv& cenv, const string& name, const ATuple* args, const ATuple* type); - void pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc f); void finishFn(CEnv& cenv, CFunc f, CVal ret, const AST* retT); void eraseFn(CEnv& cenv, CFunc f); @@ -63,6 +62,8 @@ struct CEngine : public Engine { const string call(CEnv& cenv, CFunc f, const AST* retT); private: + void pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc f); + typedef string Type; typedef string Value; diff --git a/src/compile.cpp b/src/compile.cpp index e8baed3..f84d789 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -33,7 +33,8 @@ compile_symbol(CEnv& cenv, const ASymbol* sym) throw() return NULL; if (cenv.repl && cenv.vals.topLevel(sym) && !is_form(cenv.type(sym), "Fn")) { - return cenv.engine()->compileGlobalGet(cenv, sym->sym(), *cenv.vals.ref(sym)); + CVal val = cenv.globals[sym->sym()]; + return cenv.engine()->compileGlobalGet(cenv, sym->sym(), val); } else { return *cenv.vals.ref(sym); } @@ -93,6 +94,7 @@ compile_def(CEnv& cenv, const ATuple* def) throw() if (cenv.repl && cenv.vals.topLevel(sym) && !is_form(cenv.type(sym), "Fn")) { CVal global = cenv.engine()->compileGlobalSet( cenv, sym->sym(), val, cenv.type(body)); + cenv.globals.insert(make_pair(sym->sym(), global)); cenv.def(sym, body, cenv.type(body), global); } else { cenv.def(sym, body, cenv.type(body), val); @@ -159,10 +161,7 @@ compile_fn_start(CEnv& cenv, const ATuple* call) throw() const ATuple* type = cenv.type(name)->as_tuple(); const ATuple* args = call->rst()->rst(); - CFunc func = cenv.engine()->startFn(cenv, name->sym(), args, type); - cenv.def(name, NULL, type, func); - - cenv.engine()->pushFnArgs(cenv, args, type, func); + cenv.engine()->startFn(cenv, name->sym(), args, type); return NULL; } @@ -170,8 +169,13 @@ compile_fn_start(CEnv& cenv, const ATuple* call) throw() static CVal compile_fn_end(CEnv& cenv, const ATuple* call) throw() { - const AST* retT = cenv.type(call->frst())->as_tuple()->frrst(); - cenv.engine()->finishFn(cenv, resp_compile(cenv, call->frrst()), retT); + const AST* ret = (call->list_len() > 2) ? call->frrst() : NULL; + const AST* retT = (ret) + ? cenv.type(call->frst())->as_tuple()->frrst() + : cenv.penv.sym("Nothing"); + + cenv.engine()->finishFn(cenv, resp_compile(cenv, ret), retT); + cenv.pop(); return NULL; } diff --git a/src/llvm.cpp b/src/llvm.cpp index 3391cb7..c4744c3 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -78,7 +78,6 @@ struct LLVMEngine : public Engine { virtual ~LLVMEngine(); CFunc startFn(CEnv& cenv, const string& name, const ATuple* args, const ATuple* type); - void pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc f); void finishFn(CEnv& cenv, CVal ret, const AST* retT); CFunc getFn(CEnv& cenv, const std::string& name); void eraseFn(CEnv& cenv, CFunc f); @@ -103,6 +102,8 @@ struct LLVMEngine : public Engine { const string call(CEnv& cenv, CFunc f, const AST* retT); private: + void pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc f); + void appendBlock(LLVMEngine* engine, Function* function, BasicBlock* block) { function->getBasicBlockList().push_back(block); engine->builder.SetInsertPoint(block); @@ -403,6 +404,9 @@ LLVMEngine::startFn( builder.SetInsertPoint(bb); currentFn = f; + cenv.def(cenv.penv.sym(name), NULL, type, f); + pushFnArgs(cenv, args, type, f); + return f; } diff --git a/src/repl.cpp b/src/repl.cpp index edaa003..b457e06 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -81,7 +81,7 @@ dump(CEnv& cenv, const Code& code) } const AST* -compile(CEnv& cenv, const Code& parsed, Code& defs, Code& exprs) +compile(CEnv& cenv, const Code& parsed, Code& defs, bool& hasMain, const char* mainName) { const AST* exp = NULL; @@ -111,6 +111,7 @@ compile(CEnv& cenv, const Code& parsed, Code& defs, Code& exprs) // Flatten expressions const AST* retT = NULL; + Code exprs; for (Code::const_iterator i = lifted.begin(); i != lifted.end(); ++i) { const ATuple* call = (*i)->to_tuple(); if (call && (is_form(*i, "def-type") @@ -125,6 +126,25 @@ compile(CEnv& cenv, const Code& parsed, Code& defs, Code& exprs) } } + // Flatten top-level code into main function + if (!exprs.empty()) { + const ASymbol* main = cenv.penv.sym(mainName); + + List mainT(Cursor(), cenv.penv.sym("Fn"), new ATuple(Cursor()), retT, NULL); + cenv.def(main, NULL, mainT, NULL); + + defs.push_back( + tup(Cursor(), cenv.penv.sym("fn-start"), main, NULL)); + + const AST* mainRet = NULL; + for (Code::const_iterator i = exprs.begin(); i != exprs.end(); ++i) + mainRet = resp_flatten(cenv, defs, *i); + + defs.push_back( + tup(Cursor(), cenv.penv.sym("fn-end"), main, mainRet, NULL)); + } + + hasMain = !exprs.empty(); return retT; } @@ -145,27 +165,9 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute) return 0; } - Code defs; - Code exprs; - const AST* retT = compile(cenv, parsed, defs, exprs); - - // Flatten main code into `defs' - if (!exprs.empty()) { - const ASymbol* main = cenv.penv.sym("main"); - List mainT(Cursor(), cenv.penv.sym("Fn"), new ATuple(Cursor()), retT, NULL); - cenv.def(main, NULL, mainT, NULL); - - defs.push_back( - tup(Cursor(), cenv.penv.sym("fn-start"), main, NULL)); - - const AST* mainRet = NULL; - for (Code::const_iterator i = exprs.begin(); i != exprs.end(); ++i) - mainRet = resp_flatten(cenv, defs, *i); - - defs.push_back( - tup(Cursor(), cenv.penv.sym("fn-end"), main, mainRet, NULL)); - } - + Code defs; + bool hasMain; + const AST* retT = compile(cenv, parsed, defs, hasMain, "main"); if (cenv.args.find("-F") != cenv.args.end()) { dump(cenv, defs); return 0; @@ -174,15 +176,15 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute) // Compile flattened code for (Code::const_iterator i = defs.begin(); i != defs.end(); ++i) { resp_compile(cenv, *i); + Object::pool.addRoot(*i); } - if (cenv.args.find("-S") != cenv.args.end()) { cenv.engine()->writeModule(cenv, cenv.out); return 0; } // Call main and print result - if (!exprs.empty()) + if (hasMain) callPrintCollect(cenv, cenv.engine()->getFn(cenv, "main"), ast, retT, execute); @@ -199,9 +201,8 @@ repl(CEnv& cenv) { cenv.repl = true; - const AST* exp = NULL; - const AST* ast = NULL; - const string replFnName = cenv.penv.gensymstr("_repl"); + const AST* exp = NULL; + const AST* ast = NULL; while (1) { cenv.out << "() "; cenv.out.flush(); @@ -211,24 +212,31 @@ repl(CEnv& cenv) if (!readParseType(cenv, cursor, std::cin, exp, ast)) break; - Code lifted; - ast = resp_lift(cenv, lifted, ast); - - const AST* type = cenv.type(ast); - const ATuple* fnT = tup(cursor, cenv.tenv.Fn, new ATuple(cursor), type, 0); - CFunc f = NULL; - try { - // Create function for this repl loop - f = cenv.engine()->startFn(cenv, replFnName, new ATuple(cursor), fnT); - cenv.engine()->finishFn(cenv, resp_compile(cenv, ast), type); - - if (cenv.args.find("-S") != cenv.args.end()) - cenv.engine()->writeModule(cenv, cenv.out); - else - callPrintCollect(cenv, f, ast, type, true); - } catch (Error& e) { - cenv.out << e.msg << endl; - cenv.engine()->eraseFn(cenv, f); + Code parsed; + parsed.push_back(ast); + + Code defs; + bool hasMain; + const std::string replName = cenv.penv.gensymstr("_repl"); + const AST* retT = compile(cenv, parsed, defs, hasMain, replName.c_str()); + if (cenv.args.find("-F") != cenv.args.end()) { + dump(cenv, defs); + continue; + } + + // Compile flattened code + for (Code::const_iterator i = defs.begin(); i != defs.end(); ++i) { + resp_compile(cenv, *i); + } + if (cenv.args.find("-S") != cenv.args.end()) { + cenv.engine()->writeModule(cenv, cenv.out); + continue; + } + + // Call main and print result + if (hasMain) { + callPrintCollect(cenv, cenv.engine()->getFn(cenv, replName), + ast, retT, true); } } catch (Error& e) { diff --git a/src/resp.hpp b/src/resp.hpp index f12c4c9..f952c40 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -671,11 +671,6 @@ struct Engine { const ATuple* args, const ATuple* type) = 0; - virtual void pushFnArgs(CEnv& cenv, - const ATuple* prot, - const ATuple* type, - CFunc f) = 0; - virtual void finishFn(CEnv& cenv, CVal ret, const AST* retT) = 0; virtual CFunc getFn(CEnv& cenv, const std::string& name) = 0; virtual void eraseFn(CEnv& cenv, CFunc f) = 0; @@ -784,6 +779,8 @@ struct CEnv { map<string,string> args; + map<string, CVal> globals; + typedef map<const char*, CVal> CSyms; CSyms cSyms; |