diff options
author | David Robillard <d@drobilla.net> | 2009-10-08 03:20:50 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-10-08 03:20:50 +0000 |
commit | 3c096da60b685d8d583255e777759afa96b18321 (patch) | |
tree | 32578ce06cc71645e0fe7c7269e4afdde1e86a3a /src | |
parent | 1b6ab3940ba7519c7ec3368b804e8a33f1d819db (diff) | |
download | resp-3c096da60b685d8d583255e777759afa96b18321.tar.gz resp-3c096da60b685d8d583255e777759afa96b18321.tar.bz2 resp-3c096da60b685d8d583255e777759afa96b18321.zip |
Move lifting pass to separate file.
git-svn-id: http://svn.drobilla.net/resp/tuplr@205 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src')
-rw-r--r-- | src/compile.cpp | 60 | ||||
-rw-r--r-- | src/lift.cpp | 78 |
2 files changed, 79 insertions, 59 deletions
diff --git a/src/compile.cpp b/src/compile.cpp index addad2b..5b6dacd 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -16,11 +16,7 @@ */ /** @file - * @brief Compile AST using generic backend interface - * - * Compilation pass functions (lift/compile) that don't require direct use - * of any specific backend API are implemented here. Others are implemented - * in e.g. llvm.cpp. + * @brief Compile all code (compilation pass 2) */ #include "tuplr.hpp" @@ -41,27 +37,6 @@ ASymbol::compile(CEnv& cenv) return cenv.vals.ref(this); } -void -AFn::lift(CEnv& cenv) -{ - cenv.push(); - for (const_iterator p = prot()->begin(); p != prot()->end(); ++p) - cenv.def((*p)->as<ASymbol*>(), *p, NULL, NULL); - - // Lift body - for (size_t i = 2; i < size(); ++i) - at(i)->lift(cenv); - - cenv.pop(); - - AType* type = cenv.type(this); - if (impls.find(type) || !type->concrete()) - return; - - AType* protT = type->at(1)->as<AType*>(); - cenv.engine()->liftCall(cenv, this, *protT); -} - CValue AFn::compile(CEnv& cenv) { @@ -83,28 +58,6 @@ AFn::compile(CEnv& cenv) return tupPtr;*/ } -void -ACall::lift(CEnv& cenv) -{ - AFn* c = cenv.tenv.resolve(at(0))->to<AFn*>(); - AType argsT(loc); - - // Lift arguments - for (size_t i = 1; i < size(); ++i) { - at(i)->lift(cenv); - argsT.push_back(cenv.type(at(i))); - } - - if (!c) return; // Primitive - - if (c->prot()->size() < size() - 1) - throw Error(loc, (format("too many arguments to function `%1%'") % at(0)->str()).str()); - if (c->prot()->size() > size() - 1) - throw Error(loc, (format("too few arguments to function `%1%'") % at(0)->str()).str()); - - cenv.engine()->liftCall(cenv, c, argsT); // Lift called closure -} - CValue ACall::compile(CEnv& cenv) { @@ -133,17 +86,6 @@ ACall::compile(CEnv& cenv) return cenv.engine()->compileCall(cenv, f, args); } -void -ADef::lift(CEnv& cenv) -{ - // Define stub first for recursion - cenv.def(sym(), at(2), cenv.type(at(2)), NULL); - AFn* c = at(2)->to<AFn*>(); - if (c) - c->name = sym()->str(); - at(2)->lift(cenv); -} - CValue ADef::compile(CEnv& cenv) { diff --git a/src/lift.cpp b/src/lift.cpp new file mode 100644 index 0000000..d97e541 --- /dev/null +++ b/src/lift.cpp @@ -0,0 +1,78 @@ +/* Tuplr: A programming language + * Copyright (C) 2008-2009 David Robillard <dave@drobilla.net> + * + * Tuplr is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Tuplr is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Tuplr. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file + * @brief Lift functions (compilation pass 1) + */ + +#include "tuplr.hpp" + +using namespace std; + +void +AFn::lift(CEnv& cenv) +{ + cenv.push(); + for (const_iterator p = prot()->begin(); p != prot()->end(); ++p) + cenv.def((*p)->as<ASymbol*>(), *p, NULL, NULL); + + // Lift body + for (size_t i = 2; i < size(); ++i) + at(i)->lift(cenv); + + cenv.pop(); + + AType* type = cenv.type(this); + if (impls.find(type) || !type->concrete()) + return; + + AType* protT = type->at(1)->as<AType*>(); + cenv.engine()->liftCall(cenv, this, *protT); +} + +void +ACall::lift(CEnv& cenv) +{ + AFn* c = cenv.tenv.resolve(at(0))->to<AFn*>(); + AType argsT(loc); + + // Lift arguments + for (size_t i = 1; i < size(); ++i) { + at(i)->lift(cenv); + argsT.push_back(cenv.type(at(i))); + } + + if (!c) return; // Primitive + + if (c->prot()->size() < size() - 1) + throw Error(loc, (format("too many arguments to function `%1%'") % at(0)->str()).str()); + if (c->prot()->size() > size() - 1) + throw Error(loc, (format("too few arguments to function `%1%'") % at(0)->str()).str()); + + cenv.engine()->liftCall(cenv, c, argsT); // Lift called closure +} + +void +ADef::lift(CEnv& cenv) +{ + // Define stub first for recursion + cenv.def(sym(), at(2), cenv.type(at(2)), NULL); + AFn* c = at(2)->to<AFn*>(); + if (c) + c->name = sym()->str(); + at(2)->lift(cenv); +} |