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 --- Makefile | 1 + src/compile.cpp | 60 +------------------------------------------- src/lift.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 59 deletions(-) create mode 100644 src/lift.cpp diff --git a/Makefile b/Makefile index e8f94cf..e432d68 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ OBJECTS = \ build/cps.o \ build/gc.o \ build/lex.o \ + build/lift.o \ build/llvm.o \ build/parse.o \ build/pprint.o \ 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(), *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); -} - 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(); - 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(); - 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 + * + * 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