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/lift.cpp | |
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/lift.cpp')
-rw-r--r-- | src/lift.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
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); +} |