diff options
author | David Robillard <d@drobilla.net> | 2009-06-29 00:28:50 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-06-29 00:28:50 +0000 |
commit | 314482b95ff83f1f88e41d45fadd05a7e625bb0c (patch) | |
tree | 56da1ec61b8f98746a7e27e045959cf9c91ad084 /src/tuplr.cpp | |
parent | f3ef0b25195098389bc7aea1e75d98e62b91b1e2 (diff) | |
download | resp-314482b95ff83f1f88e41d45fadd05a7e625bb0c.tar.gz resp-314482b95ff83f1f88e41d45fadd05a7e625bb0c.tar.bz2 resp-314482b95ff83f1f88e41d45fadd05a7e625bb0c.zip |
Split code up further.
git-svn-id: http://svn.drobilla.net/resp/tuplr@165 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/tuplr.cpp')
-rw-r--r-- | src/tuplr.cpp | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/src/tuplr.cpp b/src/tuplr.cpp index 7ff9f52..a0c001d 100644 --- a/src/tuplr.cpp +++ b/src/tuplr.cpp @@ -24,7 +24,6 @@ #include <fstream> #include <set> #include <sstream> -#include <stack> #include "tuplr.hpp" using namespace std; @@ -52,187 +51,6 @@ operator<<(ostream& out, const Exp<Atom>& exp) /*************************************************************************** - * Lexer * - ***************************************************************************/ - -inline int -readChar(Cursor& cur, istream& in) -{ - int ch = in.get(); - switch (ch) { - case '\n': ++cur.line; cur.col = 0; break; - default: ++cur.col; - } - return ch; -} - -SExp -readExpression(Cursor& cur, istream& in) -{ -#define PUSH(s, t) { if (t != "") { s.top().push_back(SExp(loc, t)); t = ""; } } -#define YIELD(s, t) { if (s.empty()) { return SExp(loc, t); } else PUSH(s, t) } - stack<SExp> stk; - string tok; - Cursor loc; // start of tok - while (int c = readChar(cur, in)) { - switch (c) { - case EOF: - THROW_IF(!stk.empty(), cur, "unexpected end of file") - return SExp(cur); - case ';': - while ((c = readChar(cur, in)) != '\n') {} - case '\n': case ' ': case '\t': - if (tok != "") YIELD(stk, tok); - break; - case '"': - loc = cur; - do { tok.push_back(c); } while ((c = readChar(cur, in)) != '"'); - YIELD(stk, tok + '"'); - break; - case '(': - stk.push(SExp(cur)); - break; - case ')': - switch (stk.size()) { - case 0: - throw Error(cur, "unexpected `)'"); - case 1: - PUSH(stk, tok); - return stk.top(); - default: - PUSH(stk, tok); - SExp l = stk.top(); - stk.pop(); - stk.top().push_back(l); - } - break; - case '#': - if (in.peek() == '|') { - while (!(readChar(cur, in) == '|' && readChar(cur, in) == '#')) {} - break; - } - default: - if (tok == "") loc = cur; - tok += c; - } - } - switch (stk.size()) { - case 0: return SExp(loc, tok); - case 1: return stk.top(); - default: throw Error(cur, "missing `)'"); - } - return SExp(cur); -} - - -/*************************************************************************** - * Macro Functions * - ***************************************************************************/ - -inline SExp -macDef(PEnv& penv, const SExp& exp) -{ - THROW_IF(exp.size() < 3, exp.loc, "[MAC] `def' requires at least 2 arguments") - if (exp.at(1).type == SExp::ATOM) { - return exp; - } else { - // (def (f x) y) => (def f (fn (x) y)) - SExp argsExp(exp.loc); - for (size_t i = 1; i < exp.at(1).size(); ++i) - argsExp.push_back(exp.at(1).at(i)); - SExp fnExp(exp.at(2).loc); - fnExp.push_back(SExp(exp.at(2).loc, "fn")); - fnExp.push_back(argsExp); - for (size_t i = 2; i < exp.size(); ++i) - fnExp.push_back(exp.at(i)); - SExp ret(exp.loc); - ret.push_back(exp.at(0)); - ret.push_back(exp.at(1).at(0)); - ret.push_back(fnExp); - return ret; - } -} - - -/*************************************************************************** - * Parser Functions * - ***************************************************************************/ - -template<typename C> -inline AST* -parseCall(PEnv& penv, const SExp& exp, void* arg) -{ - return new C(exp, penv.parseTuple(exp)); -} - -template<typename T> -inline AST* -parseLiteral(PEnv& penv, const SExp& exp, void* arg) -{ - return new ALiteral<T>(*reinterpret_cast<T*>(arg), exp.loc); -} - -inline AST* -parseFn(PEnv& penv, const SExp& exp, void* arg) -{ - if (exp.size() < 2) - throw Error(exp.loc, "Missing function parameters and body"); - else if (exp.size() < 3) - throw Error(exp.loc, "Missing function body"); - SExp::const_iterator a = exp.begin(); ++a; - AFn* ret = tup<AFn>(exp.loc, penv.sym("fn"), new ATuple(penv.parseTuple(*a++)), 0); - while (a != exp.end()) - ret->push_back(penv.parse(*a++)); - return ret; -} - - -/*************************************************************************** - * Standard Definitions * - ***************************************************************************/ - -void -initLang(PEnv& penv, TEnv& tenv) -{ - // Types - tenv.def(penv.sym("Nothing"), make_pair((AST*)0, new AType(penv.sym("Nothing")))); - tenv.def(penv.sym("Bool"), make_pair((AST*)0, new AType(penv.sym("Bool")))); - tenv.def(penv.sym("Int"), make_pair((AST*)0, new AType(penv.sym("Int")))); - tenv.def(penv.sym("Float"), make_pair((AST*)0, new AType(penv.sym("Float")))); - - // Literals - static bool trueVal = true; - static bool falseVal = false; - penv.reg(false, "#t", PEnv::Handler(parseLiteral<bool>, &trueVal)); - penv.reg(false, "#f", PEnv::Handler(parseLiteral<bool>, &falseVal)); - - // Macros - penv.defmac("def", macDef); - - // Special forms - penv.reg(true, "fn", PEnv::Handler(parseFn)); - penv.reg(true, "if", PEnv::Handler(parseCall<AIf>)); - penv.reg(true, "def", PEnv::Handler(parseCall<ADef>)); - - // Numeric primitives - penv.reg(true, "+", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "-", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "*", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "/", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "%", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "and", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "or", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "xor", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "=", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "!=", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, ">", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, ">=", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "<", PEnv::Handler(parseCall<APrimitive>)); - penv.reg(true, "<=", PEnv::Handler(parseCall<APrimitive>)); -} - - -/*************************************************************************** * EVAL/REPL * ***************************************************************************/ |