diff options
Diffstat (limited to 'src/resp.hpp')
-rw-r--r-- | src/resp.hpp | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/src/resp.hpp b/src/resp.hpp index 752796b..a76aed7 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -241,12 +241,20 @@ struct ALiteral : public AST { const T val; }; +/// Lexeme (any atom in the CST, e.g. "a", "3.4", ""hello"", etc. +struct ALexeme : public AST, public std::string { + ALexeme(Cursor c, const string& s) : AST(c), std::string(s) {} + bool operator==(const AST& rhs) const { return this == &rhs; } + void constrain(TEnv& tenv, Constraints& c) const throw(Error); + CVal compile(CEnv& cenv) throw(); +}; + /// String, e.g. ""a"" struct AString : public AST, public std::string { AString(Cursor c, const string& s) : AST(c), std::string(s) {} bool operator==(const AST& rhs) const { return this == &rhs; } void constrain(TEnv& tenv, Constraints& c) const throw(Error); - CVal compile(CEnv& cenv) throw() { return NULL; } + CVal compile(CEnv& cenv) throw(); }; /// Symbol, e.g. "a" @@ -490,7 +498,7 @@ struct PEnv : private map<const string, ASymbol*> { void defmac(const string& s, const MF f) { macros.insert(make_pair(s, f)); } - MF mac(const AString& s) const { + MF mac(const ALexeme& s) const { map<string, MF>::const_iterator i = macros.find(s); return (i != macros.end()) ? i->second : NULL; } @@ -517,32 +525,32 @@ struct PEnv : private map<const string, ASymbol*> { if (tup) { if (tup->empty()) throw Error(exp->loc, "call to empty list"); if (!tup->head()->to<const ATuple*>()) { - MF mf = mac(*tup->head()->to<const AString*>()); + MF mf = mac(*tup->head()->to<const ALexeme*>()); const AST* expanded = (mf ? mf(*this, exp) : exp); const ATuple* expanded_tup = expanded->to<const ATuple*>(); - const PEnv::Handler* h = handler(true, *expanded_tup->head()->to<const AString*>()); + const PEnv::Handler* h = handler(true, *expanded_tup->head()->to<const ALexeme*>()); if (h) return h->func(*this, expanded, h->arg); } ATuple* parsed_tup = parseTuple(tup); 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; + const ALexeme* lex = exp->to<const ALexeme*>(); + assert(lex); + if (isdigit((*lex)[0])) { + const std::string& s = *lex; if (s.find('.') == string::npos) 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); - } else if ((*str)[0] == '\"') { - return new AString(exp->loc, str->substr(1, str->length() - 2)); + } else if ((*lex)[0] == '\"') { + return new AString(exp->loc, lex->substr(1, lex->length() - 2)); } else { - const PEnv::Handler* h = handler(false, *str); + const PEnv::Handler* h = handler(false, *lex); if (h) return h->func(*this, exp, h->arg); } - return sym(*exp->to<const AString*>(), exp->loc); + return sym(*lex, exp->loc); } unsigned symID; }; @@ -691,6 +699,7 @@ struct Engine { virtual CVal compileTup(CEnv& cenv, const AType* t, ValVec& f) = 0; virtual CVal compileDot(CEnv& cenv, CVal tup, int32_t index) = 0; virtual CVal compileLiteral(CEnv& cenv, AST* lit) = 0; + virtual CVal compileString(CEnv& cenv, const char* str) = 0; virtual CVal compileCall(CEnv& cenv, CFunc f, const AType* fT, ValVec& args) = 0; virtual CVal compilePrimitive(CEnv& cenv, APrimitive* prim) = 0; virtual CVal compileIf(CEnv& cenv, AIf* aif) = 0; |