aboutsummaryrefslogtreecommitdiffstats
path: root/src/tuplr.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tuplr.hpp')
-rw-r--r--src/tuplr.hpp98
1 files changed, 37 insertions, 61 deletions
diff --git a/src/tuplr.hpp b/src/tuplr.hpp
index 087ce77..54d7098 100644
--- a/src/tuplr.hpp
+++ b/src/tuplr.hpp
@@ -62,37 +62,6 @@ struct Error {
string msg;
};
-/// Expression ::= Atom | (Expression*)
-template<typename Atom>
-struct Exp {
- typedef std::vector< Exp<Atom> > Vec;
-
- Exp(Cursor c) : type(LIST), loc(c), _vec(new Vec()) {}
- Exp(Cursor c, const Atom& a) : type(ATOM), loc(c), _atom(a) {}
-
- enum { ATOM, LIST } type;
-
- inline const Atom& atom() const { assert(type == ATOM); return _atom; }
-
- void push_back(const Exp<Atom>& exp) { assert(type == LIST); _vec->push_back(exp); }
-
- bool empty() const { assert(type == LIST); return _vec->empty(); }
- const Exp<Atom>& front() const { assert(type == LIST); return _vec->front(); }
-
- typedef typename Vec::const_iterator const_iterator;
- const_iterator begin() const { assert(type == LIST); return _vec->begin(); }
- const_iterator end() const { assert(type == LIST); return _vec->end(); }
-
- Cursor loc;
-
-private:
- Atom _atom;
- Vec* _vec;
-};
-
-template<typename Atom>
-extern ostream& operator<<(ostream& out, const Exp<Atom>& exp);
-
/// Lexical Address
struct LAddr {
LAddr(unsigned u=0, unsigned o=0) : up(u), over(o) {}
@@ -143,10 +112,9 @@ struct Env : public list< vector< pair<K,V> > > {
* Lexer: Text (istream) -> S-Expressions (SExp) *
***************************************************************************/
-class AString;
-typedef Exp<AString*> SExp; ///< Textual S-Expression
+class AST;
+AST* readExpression(Cursor& cur, std::istream& in);
-SExp readExpression(Cursor& cur, std::istream& in);
/***************************************************************************
@@ -290,9 +258,9 @@ private:
/// Tuple (heterogeneous sequence of fixed length), e.g. "(a b c)"
struct ATuple : public AST {
ATuple(Cursor c) : AST(c), _len(0), _vec(0) {}
- ATuple(Cursor c, const ATuple& t) : AST(c), _len(t._len) {
+ ATuple(const ATuple& exp) : AST(exp.loc), _len(exp._len) {
_vec = (AST**)malloc(sizeof(AST*) * _len);
- memcpy(_vec, t._vec, sizeof(AST*) * _len);
+ memcpy(_vec, exp._vec, sizeof(AST*) * _len);
}
ATuple(Cursor c, AST* ast, va_list args) : AST(c), _len(0), _vec(0) {
if (!ast) return;
@@ -306,6 +274,7 @@ struct ATuple : public AST {
newvec[_len++] = ast;
_vec = newvec;
}
+ const AST* front() const { assert(_len > 0); return _vec[0]; }
const AST* at(size_t i) const { assert(i < _len); return _vec[i]; }
AST*& at(size_t i) { assert(i < _len); return _vec[i]; }
size_t size() const { return _len; }
@@ -456,7 +425,7 @@ struct AFn : public ATuple {
/// Function call/application, e.g. "(func arg1 arg2)"
struct ACall : public ATuple {
- ACall(const SExp& e, const ATuple& t) : ATuple(e.loc, t) {}
+ ACall(const ATuple* exp) : ATuple(*exp) {}
ACall(Cursor c, AST* ast, va_list args) : ATuple(c, ast, args) {}
void constrain(TEnv& tenv, Constraints& c) const;
AST* cps(TEnv& tenv, AST* cont);
@@ -466,7 +435,7 @@ struct ACall : public ATuple {
/// Definition special form, e.g. "(def x 2)"
struct ADef : public ACall {
- ADef(const SExp& e, const ATuple& t) : ACall(e, t) {}
+ ADef(const ATuple* exp) : ACall(exp) {}
ADef(Cursor c, AST* ast, va_list args) : ACall(c, ast, args) {}
const ASymbol* sym() const {
const ASymbol* sym = at(1)->to<const ASymbol*>();
@@ -485,7 +454,7 @@ struct ADef : public ACall {
/// Conditional special form, e.g. "(if cond thenexp elseexp)"
struct AIf : public ACall {
- AIf(const SExp& e, const ATuple& t) : ACall(e, t) {}
+ AIf(const ATuple* exp) : ACall(exp) {}
AIf(Cursor c, AST* ast, va_list args) : ACall(c, ast, args) {}
void constrain(TEnv& tenv, Constraints& c) const;
AST* cps(TEnv& tenv, AST* cont);
@@ -494,7 +463,7 @@ struct AIf : public ACall {
/// Primitive (builtin arithmetic function), e.g. "(+ 2 3)"
struct APrimitive : public ACall {
- APrimitive(const SExp& e, const ATuple& t) : ACall(e, t) {}
+ APrimitive(const ATuple* exp) : ACall(exp) {}
bool value() const {
ATuple::const_iterator i = begin();
for (++i; i != end(); ++i)
@@ -515,8 +484,8 @@ struct APrimitive : public ACall {
/// Parse Time Environment (really just a symbol table)
struct PEnv : private map<const string, ASymbol*> {
PEnv() : symID(0) {}
- typedef AST* (*PF)(PEnv&, const SExp&, void*); ///< Parse Function
- typedef SExp (*MF)(PEnv&, const SExp&); ///< Macro Function
+ typedef AST* (*PF)(PEnv&, const AST*, void*); ///< Parse Function
+ typedef AST* (*MF)(PEnv&, const AST*); ///< Macro Function
struct Handler { Handler(PF f, void* a=0) : func(f), arg(a) {} PF func; void* arg; };
map<const string, Handler> aHandlers; ///< Atom parse functions
map<const string, Handler> lHandlers; ///< List parse functions
@@ -548,36 +517,43 @@ struct PEnv : private map<const string, ASymbol*> {
return sym;
}
}
- ATuple parseTuple(const SExp& e) {
- ATuple ret(e.loc);
- FOREACH(SExp::const_iterator, i, e)
- ret.push_back(parse(*i));
+ ATuple* parseTuple(const ATuple* e) {
+ ATuple* ret = new ATuple(e->loc);
+ FOREACH(ATuple::const_iterator, i, *e)
+ ret->push_back(parse(*i));
return ret;
}
- AST* parse(const SExp& exp) {
- if (exp.type == SExp::LIST) {
- if (exp.empty()) throw Error(exp.loc, "call to empty list");
- if (exp.front().type == SExp::ATOM) {
- MF mf = mac(*exp.front().atom());
- SExp expanded = (mf ? mf(*this, exp) : exp);
-
- const PEnv::Handler* h = handler(true, *expanded.front().atom());
+ AST* parse(const AST* exp) {
+ const ATuple* tup = exp->to<const ATuple*>();
+ if (tup) {
+ if (tup->empty()) throw Error(exp->loc, "call to empty list");
+ if (!tup->front()->to<const ATuple*>()) {
+ const AString* str = tup->front()->to<const AString*>();
+ assert(str);
+ MF mf = mac(*str);
+ const AST* expanded = (mf ? mf(*this, exp) : exp);
+ const ATuple* expanded_tup = expanded->to<const ATuple*>();
+ const PEnv::Handler* h = handler(true, *expanded_tup->front()->to<const AString*>());
if (h)
return h->func(*this, expanded, h->arg);
}
- return new ACall(exp, parseTuple(exp)); // Parse as regular call
- } else if (isdigit((*exp.atom())[0])) {
- const std::string& s = *exp.atom();
+ ATuple* parsed_tup = parseTuple(tup); // FIXME: leak
+ return new ACall(parsed_tup); // Parse as regular call
+ }
+ const AString* str = exp->to<const AString*>();
+ assert(str);
+ if (isdigit((*str)[0])) {
+ const std::string& s = *str;
if (s.find('.') == string::npos)
- return new ALiteral<int32_t>(strtol(s.c_str(), NULL, 10), exp.loc);
+ return new ALiteral<int32_t>(strtol(s.c_str(), NULL, 10), exp->loc);
else
- return new ALiteral<float>(strtod(s.c_str(), NULL), exp.loc);
+ return new ALiteral<float>(strtod(s.c_str(), NULL), exp->loc);
} else {
- const PEnv::Handler* h = handler(false, *exp.atom());
+ const PEnv::Handler* h = handler(false, *str);
if (h)
return h->func(*this, exp, h->arg);
}
- return sym(*exp.atom(), exp.loc);
+ return sym(*exp->to<const AString*>(), exp->loc);
}
unsigned symID;
};