aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-12-07 23:21:08 +0000
committerDavid Robillard <d@drobilla.net>2010-12-07 23:21:08 +0000
commit7682c4ceab935d39aafac369c9b110b658b1e575 (patch)
tree96fcddeb789f72419a5416201ee8944a58baac4e
parent5e8c55c15f42aff343d0b6189a6c8f8c50d12775 (diff)
downloadresp-7682c4ceab935d39aafac369c9b110b658b1e575.tar.gz
resp-7682c4ceab935d39aafac369c9b110b658b1e575.tar.bz2
resp-7682c4ceab935d39aafac369c9b110b658b1e575.zip
Saner recursive descent lexer/parser.
git-svn-id: http://svn.drobilla.net/resp/resp@306 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--src/c.cpp1
-rw-r--r--src/compile.cpp4
-rw-r--r--src/constrain.cpp12
-rw-r--r--src/lex.cpp222
-rw-r--r--src/lift.cpp4
-rw-r--r--src/llvm.cpp5
-rw-r--r--src/parse.cpp122
-rw-r--r--src/pprint.cpp6
-rw-r--r--src/repl.cpp4
-rw-r--r--src/resp.cpp4
-rw-r--r--src/resp.hpp32
-rwxr-xr-xtest.sh1
-rw-r--r--test/quote.resp3
13 files changed, 200 insertions, 220 deletions
diff --git a/src/c.cpp b/src/c.cpp
index 6493ff3..19cc1d5 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -51,7 +51,6 @@ llType(const AType* t)
if (t->head()->str() == "Float") return new string("float");
if (t->head()->str() == "String") return new string("char*");
if (t->head()->str() == "Quote") return new string("char*");
- if (t->head()->str() == "Lexeme") return new string("char*");
throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'");
} else if (t->kind == AType::EXPR && t->head()->str() == "Fn") {
AType::const_iterator i = t->begin();
diff --git a/src/compile.cpp b/src/compile.cpp
index 4ac7dfc..35fb042 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -148,8 +148,6 @@ resp_compile(CEnv& cenv, const AST* ast) throw()
case T_FLOAT:
case T_INT32:
return cenv.engine()->compileLiteral(cenv, ast);
- case T_LEXEME:
- return cenv.engine()->compileString(cenv, ((ALexeme*)ast)->cppstr.c_str());
case T_STRING:
return cenv.engine()->compileString(cenv, ((AString*)ast)->cppstr.c_str());
case T_SYMBOL:
@@ -171,8 +169,6 @@ resp_compile(CEnv& cenv, const AST* ast) throw()
return compile_cons(cenv, call);
else if (form == ".")
return compile_dot(cenv, call);
- else if (form == "quote")
- return resp_compile(cenv, call->list_ref(1));
else if (form == "match")
return cenv.engine()->compileMatch(cenv, call);
else if (form == "def-type")
diff --git a/src/constrain.cpp b/src/constrain.cpp
index e151eb6..3aee45a 100644
--- a/src/constrain.cpp
+++ b/src/constrain.cpp
@@ -230,13 +230,6 @@ constrain_dot(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
}
static void
-constrain_quote(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
-{
- c.constrain(tenv, call, tenv.named("Quote"));
- resp_constrain(tenv, c, call->list_ref(1));
-}
-
-static void
constrain_call(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
{
const AST* const head = call->head();
@@ -347,8 +340,6 @@ constrain_tuple(TEnv& tenv, Constraints& c, const ATuple* tup) throw(Error)
constrain_cons(tenv, c, tup);
else if (form == ".")
constrain_dot(tenv, c, tup);
- else if (form == "quote")
- constrain_quote(tenv, c, tup);
else
constrain_call(tenv, c, tup);
}
@@ -369,9 +360,6 @@ resp_constrain(TEnv& tenv, Constraints& c, const AST* ast) throw(Error)
case T_INT32:
c.constrain(tenv, ast, tenv.named("Int"));
break;
- case T_LEXEME:
- c.constrain(tenv, ast, tenv.named("Lexeme"));
- break;
case T_STRING:
c.constrain(tenv, ast, tenv.named("String"));
break;
diff --git a/src/lex.cpp b/src/lex.cpp
index 5b6eb73..2ac838f 100644
--- a/src/lex.cpp
+++ b/src/lex.cpp
@@ -16,8 +16,7 @@
*/
/** @file
- * @brief Lexing (build a CST from a string).
- * A CST is a lexeme, or a tuple of CST's.
+ * @brief Parsing (build an AST from text)
*/
#include <stdio.h>
@@ -26,8 +25,8 @@
using namespace std;
-inline int
-readChar(Cursor& cur, istream& in)
+static inline int
+read_char(Cursor& cur, istream& in)
{
int ch = in.get();
switch (ch) {
@@ -37,81 +36,172 @@ readChar(Cursor& cur, istream& in)
return ch;
}
+static inline void
+skip_space(Cursor& cur, istream& in)
+{
+ while (isspace(in.peek()))
+ read_char(cur, in);
+}
+
+static inline void
+eat_char(Cursor& cur, istream& in, const char character)
+{
+ const char c = read_char(cur, in);
+ assert(c == character);
+ return;
+}
+
+static AST*
+read_string(Cursor& cur, istream& in)
+{
+ string str;
+ char c;
+ Cursor loc = cur;
+ eat_char(cur, in, '"');
+ while ((c = read_char(cur, in)) != '"') {
+ if (c == '\\') { // string escape
+ switch (c = read_char(cur, in)) {
+ case '"':
+ str.push_back('"');
+ break;
+ case '\\':
+ str.push_back('\\');
+ break;
+ default:
+ cin.putback(c);
+ throw Error(cur, string("unknown string escape `\\") + (char)c + "'");
+ }
+ } else { // any other character
+ str.push_back(c);
+ }
+ }
+ return new AString(loc, str);
+}
+
+static AST*
+read_line_comment(Cursor& cur, istream& in)
+{
+ char c;
+ while ((c = read_char(cur, in)) != '\n') {}
+ return NULL;
+}
+
+static AST*
+read_list(PEnv& penv, Cursor& cur, istream& in)
+{
+ List<ATuple, AST> list;
+
+ eat_char(cur, in, '(');
+ while (true) {
+ skip_space(cur, in);
+ if (in.peek() == ')') {
+ eat_char(cur, in, ')');
+ return list.head;
+ }
+
+ list.push_back(read_expression(penv, cur, in));
+ }
+ assert(false);
+}
+
+static AST*
+read_special(Cursor& cur, istream& in)
+{
+ eat_char(cur, in, '#');
+ switch (in.peek()) {
+ case '|':
+ while (!(read_char(cur, in) == '|' && read_char(cur, in) == '#')) {}
+ return NULL;
+ case 't':
+ eat_char(cur, in, 't');
+ return new ALiteral<bool>(T_BOOL, true, cur);
+ case 'f':
+ return new ALiteral<bool>(T_BOOL, false, cur);
+ default:
+ throw Error(cur, (format("unknown special lexeme `%1%'") % in.peek()).str());
+ }
+ assert(false);
+ return NULL;
+}
+
+static AST*
+read_number(Cursor& cur, istream& in)
+{
+ string str;
+ char c;
+ Cursor loc = cur;
+ while ((c = in.peek()) != EOF) {
+ if (isdigit(c) || c == '.')
+ str += read_char(cur, in);
+ else
+ break;
+ }
+
+ if (str.find('.') == string::npos)
+ return new ALiteral<int32_t>(T_INT32, strtol(str.c_str(), NULL, 10), loc);
+ else
+ return new ALiteral<float>(T_FLOAT, strtod(str.c_str(), NULL), loc);
+}
+
+static AST*
+read_symbol(PEnv& penv, Cursor& cur, istream& in)
+{
+ string str;
+ char c;
+ Cursor loc = cur;
+ while ((c = in.peek()) != EOF) {
+ if (!isspace(c) && c != ')' && c != '(' && c != EOF && c != -1) {
+ str += read_char(cur, in);
+ } else {
+ break;
+ }
+ }
+
+ return penv.sym(str);
+}
+
/// Read an expression from @a in
AST*
-readExpression(Cursor& cur, istream& in)
+read_expression(PEnv& penv, Cursor& cur, istream& in)
{
-#define PUSH(s, t) { if (t != "") { s.top().push_back(new ALexeme(loc, t)); t = ""; } }
-#define YIELD(s, t) { if (s.empty()) { return new ALexeme(loc, t); } else PUSH(s, t) }
- stack< List<ATuple, AST> > stk;
- string tok;
- Cursor loc; // start of tok
- while (int c = readChar(cur, in)) {
+ while (!cin.eof()) {
+ skip_space(cur, in);
+ const char c = in.peek();
switch (c) {
case EOF:
- THROW_IF(!stk.empty(), cur, "unexpected end of file");
- return new ATuple(cur);
+ return NULL;
case ';':
- while ((c = readChar(cur, in)) != '\n') {}
- case '\n': case ' ': case '\t': case '\r': case '\f':
- if (tok != "") YIELD(stk, tok);
+ read_line_comment(cur, in);
break;
case '"':
- loc = cur;
- tok.push_back(c); // leading quote
- while ((c = readChar(cur, in)) != '"') {
- if (c == '\\') { // string escape
- switch (c = readChar(cur, in)) {
- case '"':
- tok.push_back('"');
- break;
- case '\\':
- tok.push_back('\\');
- break;
- default:
- cin.putback(c);
- throw Error(cur, string("unknown string escape `\\") + (char)c + "'");
- }
- } else { // any other character
- tok.push_back(c);
- }
- }
- tok.push_back(c); // trailing quote
- YIELD(stk, tok);
- break;
+ return read_string(cur, in);
case '(':
- stk.push(List<ATuple, AST>());
- break;
+ return read_list(penv, cur, in);
case ')':
- switch (stk.size()) {
- case 0:
- cin.putback(c);
- throw Error(cur, "unexpected `)'");
- case 1:
- PUSH(stk, tok);
- return stk.top().head;
- default:
- PUSH(stk, tok);
- List<ATuple, AST> l = stk.top();
- stk.pop();
- stk.top().push_back(l.head);
- }
- break;
+ throw Error(cur, "unexpected `)'");
case '#':
- if (in.peek() == '|') {
- while (!(readChar(cur, in) == '|' && readChar(cur, in) == '#')) {}
- break;
+ {
+ AST* ret = read_special(cur, in);
+ if (ret)
+ return ret;
+ break;
+ }
+ case '-':
+ case '+':
+ read_char(cur, in);
+ if (isdigit(in.peek())) {
+ in.putback(c);
+ return read_number(cur, in);
+ } else {
+ in.putback(c);
+ return read_symbol(penv, cur, in);
}
default:
- if (tok == "") loc = cur;
- tok += c;
+ if (isdigit(c))
+ return read_number(cur, in);
+ else
+ return read_symbol(penv, cur, in);
}
}
- switch (stk.size()) {
- case 0: return new AString(loc, tok);
- case 1: return stk.top().head;
- default: throw Error(cur, "missing `)'");
- }
- assert(false);
- return new ATuple(cur); // never reached
+ return NULL;
}
diff --git a/src/lift.cpp b/src/lift.cpp
index fe901f0..e0a5b5a 100644
--- a/src/lift.cpp
+++ b/src/lift.cpp
@@ -33,7 +33,7 @@ lift_symbol(CEnv& cenv, Code& code, const ASymbol* sym) throw()
const std::string& cppstr = sym->cppstr;
if (!cenv.liftStack.empty() && cppstr == cenv.name(cenv.liftStack.top().fn)) {
return cenv.penv.sym("_me"); // Reference to innermost function
- } else if (!cenv.penv.handler(cppstr) && !cenv.code.innermost(sym)) {
+ } else if (!cenv.code.innermost(sym)) {
const int32_t index = cenv.liftStack.top().index(sym);
@@ -247,8 +247,6 @@ resp_lift(CEnv& cenv, Code& code, const AST* ast) throw()
return lift_builtin_call(cenv, code, call);
else if (form == ".")
return lift_builtin_call(cenv, code, call);
- else if (form == "quote")
- return lift_builtin_call(cenv, code, call);
else if (form == "match" || form == "def-type")
return call; // FIXME
else
diff --git a/src/llvm.cpp b/src/llvm.cpp
index b03713d..bc90977 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -96,7 +96,6 @@ struct LLVMEngine : public Engine {
if (t->head()->str() == "Float") return Type::getFloatTy(context);
if (t->head()->str() == "String") return PointerType::get(Type::getInt8Ty(context), NULL);
if (t->head()->str() == "Quote") return PointerType::get(Type::getInt8Ty(context), NULL);
- if (t->head()->str() == "Lexeme") return PointerType::get(Type::getInt8Ty(context), NULL);
throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'");
} else if (t->kind == AType::EXPR && t->head()->str() == "Fn") {
AType::const_iterator i = t->begin();
@@ -260,10 +259,6 @@ struct LLVMEngine : public Engine {
}
}
ss << "\"";
- } else if (retT->head()->str() == "Lexeme") {
- ss << ((char* (*)())fp)();
- } else if (retT->head()->str() == "Quote") {
- ss << "(quote " << ((char* (*)())fp)() << ")";
} else if (t != Type::getVoidTy(context)) {
ss << ((void* (*)())fp)();
} else {
diff --git a/src/parse.cpp b/src/parse.cpp
index 81aaa83..3fb8375 100644
--- a/src/parse.cpp
+++ b/src/parse.cpp
@@ -16,7 +16,7 @@
*/
/** @file
- * @brief Parsing (build a code AST from a textual AST)
+ * @brief Expand built-in macros (i.e. def)
*/
#include "resp.hpp"
@@ -24,7 +24,7 @@
using namespace std;
const ATuple*
-parseTuple(PEnv& penv, const ATuple* e)
+parseList(PEnv& penv, const ATuple* e)
{
List<ATuple, const AST> ret;
FOREACHP(ATuple::const_iterator, i, e)
@@ -32,84 +32,19 @@ parseTuple(PEnv& penv, const ATuple* e)
return ret.head;
}
-const AST*
-PEnv::parse(const AST* exp)
-{
- const ATuple* tup = exp->to_tuple();
- if (tup) {
- THROW_IF(tup->empty(), exp->loc, "Call to empty list");
- const ALexeme* form = tup->head()->to_lexeme();
- if (form) {
- if (isupper(form->cppstr.c_str()[0])) // Call constructor (any uppercase symbol)
- return parseTuple(*this, tup);
-
- const PEnv::Handler* h = handler(form->cppstr);
- if (h)
- return h->func(*this, exp, h->arg); // Parse special form
- }
-
- return parseTuple(*this, tup); // Parse regular call
- }
-
- const ALexeme* lex = exp->to_lexeme();
- assert(lex);
- if (isdigit(lex->cppstr[0])) {
- const std::string& s = lex->cppstr;
- if (s.find('.') == string::npos)
- return new ALiteral<int32_t>(T_INT32, strtol(s.c_str(), NULL, 10), exp->loc);
- else
- return new ALiteral<float>(T_FLOAT, strtod(s.c_str(), NULL), exp->loc);
- } else if (lex->cppstr[0] == '\"') {
- return new AString(exp->loc, lex->cppstr.substr(1, lex->cppstr.length() - 2));
- } else if (lex->cppstr == "#t") {
- return new ALiteral<bool>(T_BOOL, true, exp->loc);
- } else if (lex->cppstr == "#f") {
- return new ALiteral<bool>(T_BOOL, false, exp->loc);
- }
- return sym(lex->cppstr, exp->loc);
-}
-
-
-/***************************************************************************
- * Parser Functions *
- ***************************************************************************/
-
-inline const AST*
-parseCall(PEnv& penv, const AST* exp, void* arg)
-{
- return parseTuple(penv, exp->to_tuple());
-}
-
-inline const AST*
-parseBool(PEnv& penv, const AST* exp, void* arg)
-{
- return new ALiteral<bool>(T_BOOL, *reinterpret_cast<bool*>(arg), exp->loc);
-}
-
inline const AST*
parseFn(PEnv& penv, const AST* exp, void* arg)
{
- const ATuple* texp = exp->to_tuple();
- ATuple::const_iterator a = texp->begin();
- THROW_IF(++a == texp->end(), exp->loc, "Unexpected end of `fn' form");
- const ATuple* prot = parseTuple(penv, (*a++)->to_tuple());
- List<ATuple, const AST> ret(new ATuple(penv.sym("fn"), NULL, Cursor()));
+ 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<ATuple, const AST> ret(new ATuple(penv.sym("fn"), NULL, exp->loc));
ret.push_back(prot);
- while (a != texp->end())
+ while (a != tup->end())
ret.push_back(penv.parse(*a++));
- ret.head->loc = exp->loc;
- return new ATuple(*ret.head);
-}
-
-inline const AST*
-parseQuote(PEnv& penv, const AST* exp, void* arg)
-{
- const ATuple* texp = exp->to_tuple();
- THROW_IF(texp->list_len() != 2, exp->loc, "`quote' requires exactly 1 argument");
- const ALexeme* quotee = texp->list_ref(1)->to_lexeme();
- THROW_IF(!quotee, exp->loc, "`quote' argument is not a lexeme");
- ATuple* ret = tup<ATuple>(texp->loc, penv.sym("quote"), quotee, NULL);
- return ret;
+ return ret.head;
}
inline const AST*
@@ -121,8 +56,8 @@ parseDef(PEnv& penv, const AST* exp, void* arg)
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_lexeme()) {
- return parseCall(penv, exp, arg);
+ if (arg1->to_symbol()) {
+ return parseList(penv, tup);
} else {
// (def (f x) y) => (def f (fn (x) y))
const ATuple* pat = arg1->to_tuple();
@@ -135,7 +70,7 @@ parseDef(PEnv& penv, const AST* exp, void* arg)
const AST* body = *(++i);
List<ATuple, const AST> fnExp;
- fnExp.push_back(new ALexeme(exp->loc, "fn"));
+ fnExp.push_back(penv.sym("fn"));
fnExp.push_back(argsExp.head);
for (; i != tup->end(); ++i)
fnExp.push_back(*i);
@@ -147,10 +82,28 @@ parseDef(PEnv& penv, const AST* exp, void* arg)
ret.push_back(fnExp.head);
ret.head->loc = exp->loc;
- return parseCall(penv, ret.head, arg);
+ 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 *
@@ -168,15 +121,6 @@ initLang(PEnv& penv, TEnv& tenv)
tenv.def(penv.sym("Quote"), new AType(penv.sym("Quote"), AType::PRIM));
tenv.def(penv.sym("String"), new AType(penv.sym("String"), AType::PRIM));
- // Special forms
- penv.reg(".", PEnv::Handler(parseCall));
- penv.reg("def", PEnv::Handler(parseDef));
- penv.reg("def-type", PEnv::Handler(parseCall));
- penv.reg("fn", PEnv::Handler(parseFn));
- penv.reg("if", PEnv::Handler(parseCall));
- penv.reg("match", PEnv::Handler(parseCall));
- penv.reg("quote", PEnv::Handler(parseQuote));
-
// Numeric primitives
penv.primitives.insert("+");
penv.primitives.insert("-");
@@ -192,6 +136,4 @@ initLang(PEnv& penv, TEnv& tenv)
penv.primitives.insert(">=");
penv.primitives.insert("<");
penv.primitives.insert("<=");
- FOREACH (PEnv::Primitives::const_iterator, i, penv.primitives)
- penv.reg(*i, PEnv::Handler(parseCall));
}
diff --git a/src/pprint.cpp b/src/pprint.cpp
index 88ed90f..5253316 100644
--- a/src/pprint.cpp
+++ b/src/pprint.cpp
@@ -85,10 +85,6 @@ print_to(ostream& out, const AST* ast, unsigned indent, CEnv* cenv, bool types)
const ASymbol* sym = (*i)->to_symbol();
if (sym) {
form = sym->cppstr;
- } else {
- const ALexeme* lexeme = (*i)->to_lexeme();
- if (lexeme)
- form = lexeme->cppstr;
}
}
@@ -149,8 +145,6 @@ print_to(ostream& out, const AST* ast, unsigned indent, CEnv* cenv, bool types)
return out << showpoint << ((const ALiteral<float>*)ast)->val;
case T_INT32:
return out << showpoint << ((const ALiteral<int32_t>*)ast)->val;
- case T_LEXEME:
- return out << ((const ALexeme*)ast)->cppstr;
case T_STRING:
return out << '"' << ((const AString*)ast)->cppstr << '"';
case T_SYMBOL:
diff --git a/src/repl.cpp b/src/repl.cpp
index 4ea4d68..8b4faab 100644
--- a/src/repl.cpp
+++ b/src/repl.cpp
@@ -30,13 +30,13 @@ static bool
readParseType(CEnv& cenv, Cursor& cursor, istream& is, AST*& exp, const AST*& ast)
{
try {
- exp = readExpression(cursor, is);
+ exp = read_expression(cenv.penv, cursor, is);
} catch (Error e) {
is.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Skip REPL junk
throw e;
}
- if (exp->to_tuple() && exp->to_tuple()->empty())
+ if (!exp || (exp->to_tuple() && exp->to_tuple()->empty()))
return false;
ast = cenv.penv.parse(exp); // Parse input
diff --git a/src/resp.cpp b/src/resp.cpp
index 0d1af5a..824acff 100644
--- a/src/resp.cpp
+++ b/src/resp.cpp
@@ -143,8 +143,8 @@ main(int argc, char** argv)
try {
while (is.good() && !is.eof()) {
Cursor loc(*f);
- AST* exp = readExpression(loc, is);
- if (!exp || (exp->as_tuple() && exp->as_tuple()->tup_len() == 1))
+ AST* exp = read_expression(cenv->penv, loc, is);
+ if (!exp || (exp->to_tuple() && exp->to_tuple()->tup_len() == 1))
break;
const AST* ast = penv.parse(exp);
diff --git a/src/resp.hpp b/src/resp.hpp
index 0c698a9..77f771c 100644
--- a/src/resp.hpp
+++ b/src/resp.hpp
@@ -117,8 +117,9 @@ ostream& operator<<(ostream& out, const Env<K,V>& env) {
* Lexer: Text (istream) -> S-Expressions (SExp) *
***************************************************************************/
+struct PEnv;
struct AST;
-AST* readExpression(Cursor& cur, std::istream& in);
+AST* read_expression(PEnv& penv, Cursor& cur, std::istream& in);
/***************************************************************************
@@ -141,11 +142,10 @@ enum Tag {
T_BOOL = 4,
T_FLOAT = 6,
T_INT32 = 8,
- T_LEXEME = 10,
- T_STRING = 12,
- T_SYMBOL = 14,
- T_TUPLE = 16,
- T_TYPE = 18
+ T_STRING = 10,
+ T_SYMBOL = 12,
+ T_TUPLE = 14,
+ T_TYPE = 16
};
/// Garbage collector
@@ -204,7 +204,6 @@ struct CEnv; ///< Compile-Time Environment
struct ATuple;
struct ASymbol;
struct AType;
-struct ALexeme;
class AST;
extern ostream& operator<<(ostream& out, const AST* ast);
@@ -241,7 +240,6 @@ struct AST : public Object {
const ASymbol* as_symbol() const { return as_a<const ASymbol>(T_SYMBOL); }
const ASymbol* to_symbol() const { return to_a<const ASymbol>(T_SYMBOL); }
- const ALexeme* to_lexeme() const { return to_a<const ALexeme>(T_LEXEME); }
const AType* as_type() const { return as_a<const AType>(T_TYPE); }
const AType* to_type() const { return to_a<const AType>(T_TYPE); }
@@ -265,12 +263,6 @@ struct ALiteral : public AST {
const T val;
};
-/// Lexeme (any atom in the CST, e.g. "a", "3.4", ""hello"", etc.)
-struct ALexeme : public AST {
- ALexeme(Cursor c, const string& s) : AST(T_LEXEME, c), cppstr(s) {}
- const string cppstr;
-};
-
/// String, e.g. ""a""
struct AString : public AST {
AString(Cursor c, const string& s) : AST(T_STRING, c), cppstr(s) {}
@@ -538,7 +530,6 @@ AST::operator==(const AST& rhs) const
}
case T_UNKNOWN:
- case T_LEXEME:
case T_STRING:
case T_SYMBOL:
return this == &rhs;
@@ -553,19 +544,10 @@ AST::operator==(const AST& rhs) const
/// Parse Time Environment (really just a symbol table)
struct PEnv : private map<const string, ASymbol*> {
PEnv() : symID(0) {}
- typedef const AST* (*PF)(PEnv&, const AST*, void*); ///< Parse Function
- struct Handler { Handler(PF f, void* a=0) : func(f), arg(a) {} PF func; void* arg; };
- map<const string, Handler> handlers; ///< List parse functions
- void reg(const string& s, const Handler& h) {
- handlers.insert(make_pair(sym(s)->str(), h));
- }
- const Handler* handler(const string& s) const {
- map<string, Handler>::const_iterator i = handlers.find(s);
- return (i != handlers.end()) ? &i->second : NULL;
- }
string gensymstr(const char* s="_") { return (format("%s_%d") % s % symID++).str(); }
ASymbol* gensym(const char* s="_") { return sym(gensymstr(s)); }
ASymbol* sym(const string& s, Cursor c=Cursor()) {
+ assert(s != "");
const const_iterator i = find(s);
if (i != end()) {
return i->second;
diff --git a/test.sh b/test.sh
index 53ce693..c307cc3 100755
--- a/test.sh
+++ b/test.sh
@@ -22,7 +22,6 @@ run './test/inlinefn.resp' '2 : Int'
run './test/nest.resp' '8 : Int'
run './test/tup.resp' '5 : Int'
run './test/string.resp' '"Hello, world!" : String'
-run './test/quote.resp' '(quote hello) : Quote'
run './test/match.resp' '"Hello, rectangle!" : String'
#run './test/poly.resp' '#t : Bool'
diff --git a/test/quote.resp b/test/quote.resp
deleted file mode 100644
index a7b41a1..0000000
--- a/test/quote.resp
+++ /dev/null
@@ -1,3 +0,0 @@
-(def q (quote hello))
-
-q