From 375bed3c2e94f44fc3587f3b0cd036b97df8f72d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 7 Dec 2010 23:25:14 +0000 Subject: Rename 'parse' to the now more accurate 'expand'. git-svn-id: http://svn.drobilla.net/resp/resp@307 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- Makefile | 2 +- src/expand.cpp | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/parse.cpp | 139 --------------------------------------------------------- src/repl.cpp | 2 +- src/resp.cpp | 2 +- src/resp.hpp | 2 +- 6 files changed, 142 insertions(+), 143 deletions(-) create mode 100644 src/expand.cpp delete mode 100644 src/parse.cpp diff --git a/Makefile b/Makefile index d76a7cc..b33dd9a 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ OBJECTS = \ build/gc.o \ build/lex.o \ build/lift.o \ - build/parse.o \ + build/expand.o \ build/pprint.o \ build/repl.o \ build/resp.o \ diff --git a/src/expand.cpp b/src/expand.cpp new file mode 100644 index 0000000..8e682dd --- /dev/null +++ b/src/expand.cpp @@ -0,0 +1,138 @@ +/* Resp: A programming language + * Copyright (C) 2008-2009 David Robillard + * + * Resp 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. + * + * Resp 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 Resp. If not, see . + */ + +/** @file + * @brief Expand built-in macros (i.e. def) + */ + +#include "resp.hpp" + +using namespace std; + +static inline const ATuple* +expand_list(PEnv& penv, const ATuple* e) +{ + List ret; + FOREACHP(ATuple::const_iterator, i, e) + ret.push_back(penv.expand(*i)); + return ret.head; +} + +static inline const AST* +expand_fn(PEnv& penv, const AST* exp, void* arg) +{ + const ATuple* tup = exp->to_tuple(); + ATuple::const_iterator a = tup->begin(); + THROW_IF(++a == tup->end(), exp->loc, "Unexpected end of `fn' form"); + THROW_IF(!(*a)->to_tuple(), (*a)->loc, "First argument of `fn' is not a list"); + const ATuple* prot = (*a++)->to_tuple(); + List ret(new ATuple(penv.sym("fn"), NULL, exp->loc)); + ret.push_back(prot); + while (a != tup->end()) + ret.push_back(penv.expand(*a++)); + return ret.head; +} + +static inline const AST* +expand_def(PEnv& penv, const AST* exp, void* arg) +{ + const ATuple* tup = exp->as_tuple(); + + ATuple::const_iterator i = tup->begin(); + THROW_IF(i == tup->end(), tup->loc, "Unexpected end of `def' form"); + const AST* arg1 = *(++i); + THROW_IF(i == tup->end(), arg1->loc, "Unexpected end of `def' form"); + if (arg1->to_symbol()) { + return expand_list(penv, tup); + } else { + // (def (f x) y) => (def f (fn (x) y)) + const ATuple* pat = arg1->to_tuple(); + + List argsExp; + ATuple::const_iterator j = pat->begin(); + for (++j; j != pat->end(); ++j) + argsExp.push_back(*j); + argsExp.head->loc = exp->loc; + const AST* body = *(++i); + + List fnExp; + fnExp.push_back(penv.sym("fn")); + fnExp.push_back(argsExp.head); + for (; i != tup->end(); ++i) + fnExp.push_back(*i); + fnExp.head->loc = body->loc; + + List ret; + ret.push_back(tup->head()); + ret.push_back(pat->head()); + ret.push_back(fnExp.head); + ret.head->loc = exp->loc; + + return expand_list(penv, ret.head); + } +} + +const AST* +PEnv::expand(const AST* exp) +{ + const ATuple* tup = exp->to_tuple(); + if (!tup) + return exp; + + THROW_IF(tup->empty(), exp->loc, "Call to empty list"); + + if (is_form(tup, "def")) + return expand_def(*this, exp, NULL); + else if (is_form(tup, "fn")) + return expand_fn(*this, exp, NULL); + else + return expand_list(*this, tup); +} + + +/*************************************************************************** + * Language Definition * + ***************************************************************************/ + +void +initLang(PEnv& penv, TEnv& tenv) +{ + // Types + tenv.def(penv.sym("Bool"), new AType(penv.sym("Bool"), AType::PRIM)); + tenv.def(penv.sym("Float"), new AType(penv.sym("Float"), AType::PRIM)); + tenv.def(penv.sym("Int"), new AType(penv.sym("Int"), AType::PRIM)); + tenv.def(penv.sym("Lexeme"), new AType(penv.sym("Lexeme"), AType::PRIM)); + tenv.def(penv.sym("Nothing"), new AType(penv.sym("Nothing"), AType::PRIM)); + tenv.def(penv.sym("Quote"), new AType(penv.sym("Quote"), AType::PRIM)); + tenv.def(penv.sym("String"), new AType(penv.sym("String"), AType::PRIM)); + + // Numeric primitives + penv.primitives.insert("+"); + penv.primitives.insert("-"); + penv.primitives.insert("*"); + penv.primitives.insert("/"); + penv.primitives.insert("%"); + penv.primitives.insert("and"); + penv.primitives.insert("or"); + penv.primitives.insert("xor"); + penv.primitives.insert("="); + penv.primitives.insert("!="); + penv.primitives.insert(">"); + penv.primitives.insert(">="); + penv.primitives.insert("<"); + penv.primitives.insert("<="); +} diff --git a/src/parse.cpp b/src/parse.cpp deleted file mode 100644 index 3fb8375..0000000 --- a/src/parse.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* Resp: A programming language - * Copyright (C) 2008-2009 David Robillard - * - * Resp 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. - * - * Resp 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 Resp. If not, see . - */ - -/** @file - * @brief Expand built-in macros (i.e. def) - */ - -#include "resp.hpp" - -using namespace std; - -const ATuple* -parseList(PEnv& penv, const ATuple* e) -{ - List ret; - FOREACHP(ATuple::const_iterator, i, e) - ret.push_back(penv.parse(*i)); - return ret.head; -} - -inline const AST* -parseFn(PEnv& penv, const AST* exp, void* arg) -{ - const ATuple* tup = exp->to_tuple(); - ATuple::const_iterator a = tup->begin(); - THROW_IF(++a == tup->end(), exp->loc, "Unexpected end of `fn' form"); - THROW_IF(!(*a)->to_tuple(), (*a)->loc, "First argument of `fn' is not a list"); - const ATuple* prot = (*a++)->to_tuple(); - List ret(new ATuple(penv.sym("fn"), NULL, exp->loc)); - ret.push_back(prot); - while (a != tup->end()) - ret.push_back(penv.parse(*a++)); - return ret.head; -} - -inline const AST* -parseDef(PEnv& penv, const AST* exp, void* arg) -{ - const ATuple* tup = exp->as_tuple(); - - ATuple::const_iterator i = tup->begin(); - THROW_IF(i == tup->end(), tup->loc, "Unexpected end of `def' form"); - const AST* arg1 = *(++i); - THROW_IF(i == tup->end(), arg1->loc, "Unexpected end of `def' form"); - if (arg1->to_symbol()) { - return parseList(penv, tup); - } else { - // (def (f x) y) => (def f (fn (x) y)) - const ATuple* pat = arg1->to_tuple(); - - List argsExp; - ATuple::const_iterator j = pat->begin(); - for (++j; j != pat->end(); ++j) - argsExp.push_back(*j); - argsExp.head->loc = exp->loc; - const AST* body = *(++i); - - List fnExp; - fnExp.push_back(penv.sym("fn")); - fnExp.push_back(argsExp.head); - for (; i != tup->end(); ++i) - fnExp.push_back(*i); - fnExp.head->loc = body->loc; - - List ret; - ret.push_back(tup->head()); - ret.push_back(pat->head()); - ret.push_back(fnExp.head); - ret.head->loc = exp->loc; - - return parseList(penv, ret.head); - } -} - -const AST* -PEnv::parse(const AST* exp) -{ - const ATuple* tup = exp->to_tuple(); - if (!tup) - return exp; - - THROW_IF(tup->empty(), exp->loc, "Call to empty list"); - - if (is_form(tup, "def")) - return parseDef(*this, exp, NULL); - else if (is_form(tup, "fn")) - return parseFn(*this, exp, NULL); - else - return parseList(*this, tup); -} - - - -/*************************************************************************** - * Language Definition * - ***************************************************************************/ - -void -initLang(PEnv& penv, TEnv& tenv) -{ - // Types - tenv.def(penv.sym("Bool"), new AType(penv.sym("Bool"), AType::PRIM)); - tenv.def(penv.sym("Float"), new AType(penv.sym("Float"), AType::PRIM)); - tenv.def(penv.sym("Int"), new AType(penv.sym("Int"), AType::PRIM)); - tenv.def(penv.sym("Lexeme"), new AType(penv.sym("Lexeme"), AType::PRIM)); - tenv.def(penv.sym("Nothing"), new AType(penv.sym("Nothing"), AType::PRIM)); - tenv.def(penv.sym("Quote"), new AType(penv.sym("Quote"), AType::PRIM)); - tenv.def(penv.sym("String"), new AType(penv.sym("String"), AType::PRIM)); - - // Numeric primitives - penv.primitives.insert("+"); - penv.primitives.insert("-"); - penv.primitives.insert("*"); - penv.primitives.insert("/"); - penv.primitives.insert("%"); - penv.primitives.insert("and"); - penv.primitives.insert("or"); - penv.primitives.insert("xor"); - penv.primitives.insert("="); - penv.primitives.insert("!="); - penv.primitives.insert(">"); - penv.primitives.insert(">="); - penv.primitives.insert("<"); - penv.primitives.insert("<="); -} diff --git a/src/repl.cpp b/src/repl.cpp index 8b4faab..965e202 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -39,7 +39,7 @@ readParseType(CEnv& cenv, Cursor& cursor, istream& is, AST*& exp, const AST*& as if (!exp || (exp->to_tuple() && exp->to_tuple()->empty())) return false; - ast = cenv.penv.parse(exp); // Parse input + ast = cenv.penv.expand(exp); // Parse input Constraints c(cenv.tsubst); resp_constrain(cenv.tenv, c, ast); // Constrain types diff --git a/src/resp.cpp b/src/resp.cpp index 824acff..9e959f5 100644 --- a/src/resp.cpp +++ b/src/resp.cpp @@ -147,7 +147,7 @@ main(int argc, char** argv) if (!exp || (exp->to_tuple() && exp->to_tuple()->tup_len() == 1)) break; - const AST* ast = penv.parse(exp); + const AST* ast = penv.expand(exp); pprint(os, ast, cenv, false); is.ignore(std::numeric_limits::max(), '\n'); // Skip newlines } diff --git a/src/resp.hpp b/src/resp.hpp index 77f771c..ae7bc11 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -557,7 +557,7 @@ struct PEnv : private map { return sym; } } - const AST* parse(const AST* exp); + const AST* expand(const AST* exp); typedef std::set Primitives; Primitives primitives; -- cgit v1.2.1