From 3c096da60b685d8d583255e777759afa96b18321 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 8 Oct 2009 03:20:50 +0000 Subject: Move lifting pass to separate file. git-svn-id: http://svn.drobilla.net/resp/tuplr@205 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/lift.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/lift.cpp (limited to 'src/lift.cpp') 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 + * + * 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 . + */ + +/** @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(), *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(); + cenv.engine()->liftCall(cenv, this, *protT); +} + +void +ACall::lift(CEnv& cenv) +{ + AFn* c = cenv.tenv.resolve(at(0))->to(); + 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(); + if (c) + c->name = sym()->str(); + at(2)->lift(cenv); +} -- cgit v1.2.1