aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/c.cpp24
-rw-r--r--src/compile.cpp57
-rw-r--r--src/constrain.cpp46
-rw-r--r--src/cps.cpp6
-rw-r--r--src/gc.cpp7
-rw-r--r--src/lift.cpp42
-rw-r--r--src/llvm.cpp53
-rw-r--r--src/parse.cpp28
-rw-r--r--src/pprint.cpp60
-rw-r--r--src/repl.cpp6
-rw-r--r--src/resp.cpp10
-rw-r--r--src/resp.hpp107
-rw-r--r--src/unify.cpp24
13 files changed, 254 insertions, 216 deletions
diff --git a/src/c.cpp b/src/c.cpp
index 7df33b0..6493ff3 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -55,14 +55,14 @@ llType(const AType* t)
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();
- const ATuple* protT = (*++i)->to<const ATuple*>();
- const AType* retT = (*i)->as<const AType*>();
+ const ATuple* protT = (*++i)->to_tuple();
+ const AType* retT = (*i)->as_type();
if (!llType(retT))
return NULL;
Type* ret = new Type(*llType(retT) + " (*)(");
FOREACHP(ATuple::const_iterator, i, protT) {
- const AType* at = (*i)->to<const AType*>();
+ const AType* at = (*i)->to_type();
const Type* lt = llType(at);
if (!lt)
return NULL;
@@ -74,7 +74,7 @@ llType(const AType* t)
} else if (t->kind == AType::EXPR && t->head()->str() == "Tup") {
Type* ret = new Type("struct { void* me; ");
for (AType::const_iterator i = t->iter_at(1); i != t->end(); ++i) {
- const Type* lt = llType((*i)->to<const AType*>());
+ const Type* lt = llType((*i)->to_type());
if (!lt)
return NULL;
ret->append("; ");
@@ -103,12 +103,12 @@ struct CEngine : public Engine {
CFunc startFunction(CEnv& cenv,
const std::string& name, const ATuple* args, const AType* type)
{
- const AType* argsT = type->prot()->as<const AType*>();
- const AType* retT = type->list_ref(2)->as<const AType*>();
+ const AType* argsT = type->prot()->as_type();
+ const AType* retT = type->list_ref(2)->as_type();
vector<const Type*> cprot;
FOREACHP(ATuple::const_iterator, i, argsT) {
- const AType* at = (*i)->as<const AType*>();
+ const AType* at = (*i)->as_type();
THROW_IF(!llType(at), Cursor(), string("non-concrete parameter :: ")
+ at->str())
cprot.push_back(llType(at));
@@ -126,7 +126,7 @@ struct CEngine : public Engine {
for (; ai != argsT->end(); ++ai, ++ni) {
if (ai != argsT->begin())
f->text += ", ";
- f->text += *llType((*ai)->as<const AType*>()) + " " + (*ni)->as<const ASymbol*>()->cppstr;
+ f->text += *llType((*ai)->as_type()) + " " + (*ni)->as_symbol()->cppstr;
}
f->text += ")\n{\n";
@@ -215,17 +215,17 @@ CEngine::pushFunctionArgs(CEnv& cenv, const ATuple* fn, const AType* type, CFunc
{
cenv.push();
- const AType* argsT = type->prot()->as<const AType*>();
+ const AType* argsT = type->prot()->as_type();
// Bind argument values in CEnv
vector<Value*> args;
ATuple::const_iterator p = fn->prot()->begin();
ATuple::const_iterator pT = argsT->begin();
for (; p != fn->prot()->end(); ++p, ++pT) {
- const AType* t = (*pT)->as<const AType*>();
+ const AType* t = (*pT)->as_type();
const Type* lt = llType(t);
THROW_IF(!lt, fn->loc, "untyped parameter\n");
- cenv.def((*p)->as<const ASymbol*>(), *p, t, new string((*p)->str()));
+ cenv.def((*p)->as_symbol(), *p, t, new string((*p)->str()));
}
}
@@ -275,7 +275,7 @@ CEngine::compilePrimitive(CEnv& cenv, const ATuple* prim)
Value* a = llVal(resp_compile(cenv, *i++));
Value* b = llVal(resp_compile(cenv, *i++));
- const string n = prim->head()->to<const ASymbol*>()->str();
+ const string n = prim->head()->to_symbol()->str();
string op = n;
// Convert operator to C operator if they don't match
diff --git a/src/compile.cpp b/src/compile.cpp
index ebd6083..142fa0a 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -69,7 +69,7 @@ compile_fn(CEnv& cenv, const ATuple* fn) throw()
static CVal
compile_type(CEnv& cenv, const AType* type) throw()
{
- const ASymbol* sym = type->head()->as<const ASymbol*>();
+ const ASymbol* sym = type->head()->as_symbol();
CVal* existing = cenv.vals.ref(sym);
if (existing) {
return *existing;
@@ -99,7 +99,7 @@ compile_call(CEnv& cenv, const ATuple* call) throw()
static CVal
compile_def(CEnv& cenv, const ATuple* def) throw()
{
- const ASymbol* const sym = def->list_ref(1)->as<const ASymbol*>();
+ const ASymbol* const sym = def->list_ref(1)->as_symbol();
const AST* const body = def->list_ref(2);
cenv.def(sym, body, cenv.type(body), NULL); // define stub first for recursion
CVal val = resp_compile(cenv, body);
@@ -115,7 +115,7 @@ compile_def(CEnv& cenv, const ATuple* def) throw()
static CVal
compile_cons(CEnv& cenv, const ATuple* cons) throw()
{
- AType* type = new AType(const_cast<ASymbol*>(cons->head()->as<const ASymbol*>()), NULL, Cursor());
+ AType* type = new AType(const_cast<ASymbol*>(cons->head()->as_symbol()), NULL, Cursor());
TList tlist(type);
vector<CVal> fields;
for (ATuple::const_iterator i = cons->iter_at(1); i != cons->end(); ++i) {
@@ -128,9 +128,10 @@ compile_cons(CEnv& cenv, const ATuple* cons) throw()
static CVal
compile_dot(CEnv& cenv, const ATuple* dot) throw()
{
- ATuple::const_iterator i = dot->begin();
- const AST* tup = *++i;
- const ALiteral<int32_t>* index = (*++i)->as<const ALiteral<int32_t>*>();
+ ATuple::const_iterator i = dot->begin();
+ const AST* tup = *++i;
+ const ALiteral<int32_t>* index = (ALiteral<int32_t>*)(*++i);
+ assert(index->tag() == T_INT32);
CVal tupVal = resp_compile(cenv, tup);
return cenv.engine()->compileDot(cenv, tupVal, index->val);
}
@@ -138,33 +139,28 @@ compile_dot(CEnv& cenv, const ATuple* dot) throw()
CVal
resp_compile(CEnv& cenv, const AST* ast) throw()
{
- if (ast->to<const ALiteral<int32_t>*>()
- || ast->to<const ALiteral<float>*>()
- || ast->to<const ALiteral<bool>*>())
+ switch (ast->tag()) {
+ case T_UNKNOWN:
+ return NULL;
+ case T_TYPE:
+ return compile_type(cenv, ast->as_type());
+ case T_BOOL:
+ case T_FLOAT:
+ case T_INT32:
return cenv.engine()->compileLiteral(cenv, ast);
-
- const AString* str = ast->to<const AString*>();
- if (str)
- return cenv.engine()->compileString(cenv, str->cppstr.c_str());
-
- const ALexeme* lexeme = ast->to<const ALexeme*>();
- if (lexeme)
- return cenv.engine()->compileString(cenv, lexeme->cppstr.c_str());
-
- const ASymbol* sym = ast->to<const ASymbol*>();
- if (sym)
- return compile_symbol(cenv, sym);
-
- const AType* type = ast->to<const AType*>();
- if (type)
- return compile_type(cenv, type);
-
- const ATuple* const call = ast->to<const ATuple*>();
- if (call) {
- const ASymbol* const sym = call->head()->to<const ASymbol*>();
+ 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:
+ return compile_symbol(cenv, ast->as_symbol());
+ case T_TUPLE:
+ {
+ const ATuple* const call = ast->as_tuple();
+ const ASymbol* const sym = call->head()->to_symbol();
const std::string form = sym ? sym->cppstr : "";
if (is_primitive(cenv.penv, call))
- return cenv.engine()->compilePrimitive(cenv, ast->as<const ATuple*>());
+ return cenv.engine()->compilePrimitive(cenv, ast->as_tuple());
else if (form == "fn")
return compile_fn(cenv, call);
else if (form == "def")
@@ -184,6 +180,7 @@ resp_compile(CEnv& cenv, const AST* ast) throw()
else
return compile_call(cenv, call);
}
+ }
cenv.err << "Attempt to compile unknown type: " << ast << endl;
assert(false);
diff --git a/src/constrain.cpp b/src/constrain.cpp
index fd4e9f4..410df87 100644
--- a/src/constrain.cpp
+++ b/src/constrain.cpp
@@ -41,7 +41,7 @@ constrain_fn(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
// Add parameters to environment frame
TList protT;
for (ATuple::const_iterator i = prot->begin(); i != prot->end(); ++i) {
- const ASymbol* sym = (*i)->to<const ASymbol*>();
+ const ASymbol* sym = (*i)->to_symbol();
THROW_IF(!sym, (*i)->loc, "parameter name is not a symbol");
THROW_IF(defs.count(sym) != 0, sym->loc,
(format("duplicate parameter `%1%'") % sym->str()).str());
@@ -58,9 +58,9 @@ constrain_fn(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
// Add internal definitions to environment frame
for (++i; i != call->end(); ++i) {
const AST* exp = *i;
- const ATuple* call = exp->to<const ATuple*>();
+ const ATuple* call = exp->to_tuple();
if (call && is_form(call, "def")) {
- const ASymbol* sym = call->list_ref(1)->as<const ASymbol*>();
+ const ASymbol* sym = call->list_ref(1)->as_symbol();
THROW_IF(defs.count(sym) != 0, call->loc,
(format("`%1%' defined twice") % sym->str()).str());
defs.insert(sym);
@@ -89,7 +89,7 @@ static void
constrain_def(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
{
THROW_IF(call->list_len() != 3, call->loc, "`def' requires exactly 2 arguments");
- const ASymbol* const sym = call->list_ref(1)->as<const ASymbol*>();
+ const ASymbol* const sym = call->list_ref(1)->as_symbol();
THROW_IF(!sym, call->loc, "`def' has no symbol")
const AST* const body = call->list_ref(2);
@@ -105,19 +105,19 @@ constrain_def_type(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
{
THROW_IF(call->list_len() < 3, call->loc, "`def-type' requires at least 2 arguments");
ATuple::const_iterator i = call->iter_at(1);
- const ATuple* prot = (*i)->to<const ATuple*>();
+ const ATuple* prot = (*i)->to_tuple();
THROW_IF(!prot, (*i)->loc, "first argument of `def-type' is not a tuple");
- const ASymbol* sym = (*prot->begin())->as<const ASymbol*>();
+ const ASymbol* sym = (*prot->begin())->as_symbol();
THROW_IF(!sym, (*prot->begin())->loc, "type name is not a symbol");
THROW_IF(tenv.ref(sym), call->loc, "type redefinition");
TList type(new AType(tenv.U, NULL, call->loc));
for (ATuple::const_iterator i = call->iter_at(2); i != call->end(); ++i) {
- const ATuple* exp = (*i)->as<const ATuple*>();
- const ASymbol* tag = (*exp->begin())->as<const ASymbol*>();
+ const ATuple* exp = (*i)->as_tuple();
+ const ASymbol* tag = (*exp->begin())->as_symbol();
TList consT;
consT.push_back(new AType(const_cast<ASymbol*>(sym), AType::NAME));
for (ATuple::const_iterator i = exp->begin(); i != exp->end(); ++i) {
- const ASymbol* sym = (*i)->to<const ASymbol*>();
+ const ASymbol* sym = (*i)->to_symbol();
THROW_IF(!sym, (*i)->loc, "type expression element is not a symbol");
consT.push_back(new AType(const_cast<ASymbol*>(sym), AType::NAME));
}
@@ -138,15 +138,15 @@ constrain_match(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
resp_constrain(tenv, c, matchee);
for (ATuple::const_iterator i = call->iter_at(2); i != call->end();) {
const AST* exp = *i++;
- const ATuple* pattern = exp->to<const ATuple*>();
+ const ATuple* pattern = exp->to_tuple();
THROW_IF(!pattern, exp->loc, "pattern expression expected");
- const ASymbol* name = (*pattern->begin())->to<const ASymbol*>();
+ const ASymbol* name = (*pattern->begin())->to_symbol();
THROW_IF(!name, (*pattern->begin())->loc, "pattern does not start with a symbol");
const AType* consT = *tenv.ref(name);
if (!matcheeT) {
- const AType* headT = consT->head()->as<const AType*>();
+ const AType* headT = consT->head()->as_type();
matcheeT = tup<AType>(call->loc, const_cast<AType*>(headT), 0);
}
@@ -184,7 +184,7 @@ constrain_if(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
static void
constrain_cons(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
{
- const ASymbol* sym = (*call->begin())->as<const ASymbol*>();
+ const ASymbol* sym = (*call->begin())->as_symbol();
const AType* type = NULL;
for (ATuple::const_iterator i = call->iter_at(1); i != call->end(); ++i)
@@ -201,7 +201,7 @@ constrain_cons(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
THROW_IF(!consTRef, call->loc,
(format("call to undefined constructor `%1%'") % sym->cppstr).str());
const AType* consT = *consTRef;
- type = tup<AType>(call->loc, const_cast<AType*>(consT->head()->as<const AType*>()), 0);
+ type = tup<AType>(call->loc, const_cast<AType*>(consT->head()->as_type()), 0);
}
c.constrain(tenv, call, type);
}
@@ -210,10 +210,12 @@ static void
constrain_dot(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
{
THROW_IF(call->list_len() != 3, call->loc, "`.' requires exactly 2 arguments");
- ATuple::const_iterator i = call->begin();
- const AST* obj = *++i;
- const ALiteral<int32_t>* idx = (*++i)->to<const ALiteral<int32_t>*>();
- THROW_IF(!idx, call->loc, "the 2nd argument to `.' must be a literal integer");
+ ATuple::const_iterator i = call->begin();
+ const AST* obj = *++i;
+ const AST* idx_ast = *++i;
+ THROW_IF(idx_ast->tag() != T_INT32, call->loc, "the 2nd argument to `.' must be a literal integer");
+ const ALiteral<int32_t>* idx = (ALiteral<int32_t>*)idx_ast;
+
resp_constrain(tenv, c, obj);
const AType* retT = tenv.var(call);
@@ -266,7 +268,7 @@ constrain_call(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
static void
constrain_primitive(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
{
- const string n = call->head()->to<const ASymbol*>()->str();
+ const string n = call->head()->to_symbol()->str();
enum { ARITHMETIC, BINARY, LOGICAL, COMPARISON } type;
if (n == "+" || n == "-" || n == "*" || n == "/")
type = ARITHMETIC;
@@ -322,7 +324,7 @@ constrain_primitive(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error)
static void
constrain_tuple(TEnv& tenv, Constraints& c, const ATuple* tup) throw(Error)
{
- const ASymbol* const sym = tup->head()->to<const ASymbol*>();
+ const ASymbol* const sym = tup->head()->to_symbol();
if (!sym) {
constrain_call(tenv, c, tup);
return;
@@ -374,10 +376,10 @@ resp_constrain(TEnv& tenv, Constraints& c, const AST* ast) throw(Error)
c.constrain(tenv, ast, tenv.named("String"));
break;
case T_SYMBOL:
- constrain_symbol(tenv, c, ast->as<const ASymbol*>());
+ constrain_symbol(tenv, c, ast->as_symbol());
break;
case T_TUPLE:
- constrain_tuple(tenv, c, ast->as<const ATuple*>());
+ constrain_tuple(tenv, c, ast->as_tuple());
break;
}
}
diff --git a/src/cps.cpp b/src/cps.cpp
index 889a716..f7c3892 100644
--- a/src/cps.cpp
+++ b/src/cps.cpp
@@ -66,7 +66,7 @@ ATuple::cps(TEnv& tenv, AST* cont) const
AFn* firstFn = NULL;
ssize_t index = 0;
FOREACHP(const_iterator, i, this) {
- if (!(*i)->to<ATuple*>()) {
+ if (!(*i)->to_tuple()) {
funcs.push_back(make_pair((AFn*)NULL, (*i)));
} else {
arg = tenv.penv.gensym("a");
@@ -114,8 +114,8 @@ ATuple::cps(TEnv& tenv, AST* cont) const
AST*
ADef::cps(TEnv& tenv, AST* cont) const
{
- AST* val = body()->cps(tenv, cont);
- ATuple* valCall = val->to<ATuple*>();
+ AST* val = body()->cps(tenv, cont);
+ ATuple* valCall = val->to_tuple();
ATuple::iterator i = valCall->begin();
return tup<ADef>(loc, tenv.penv.sym("def"), sym(), *++i, 0);
}
diff --git a/src/gc.cpp b/src/gc.cpp
index 8ed0fb2..cff4f0a 100644
--- a/src/gc.cpp
+++ b/src/gc.cpp
@@ -57,7 +57,7 @@ mark(const Object* obj)
obj->mark(true);
if (obj->tag() != T_UNKNOWN) {
- const ATuple* tup = ((const AST*)obj)->to<const ATuple*>();
+ const ATuple* tup = ((const AST*)obj)->to_tuple();
if (tup)
FOREACHP(ATuple::const_iterator, i, tup)
mark(*i);
@@ -80,8 +80,9 @@ GC::collect(const Roots& roots)
(*i)->mark(false);
assert(!(*i)->marked());
} else {
- if ((*i)->tag() != T_UNKNOWN)
- ((AST*)*i)->~AST();
+ const Tag tag = (*i)->tag();
+ if (tag == T_TUPLE || tag == T_TYPE)
+ free(((ATuple*)*i)->_vec);
tlsf_free((tlsf_t*)_pool, ((char*)(*i) - sizeof(Object::Header)));
_heap.erase(i);
diff --git a/src/lift.cpp b/src/lift.cpp
index df34d7a..04bf61b 100644
--- a/src/lift.cpp
+++ b/src/lift.cpp
@@ -28,7 +28,7 @@
using namespace std;
static AST*
-lift_symbol(CEnv& cenv, Code& code, ASymbol* sym) throw()
+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)) {
@@ -45,7 +45,7 @@ lift_symbol(CEnv& cenv, Code& code, ASymbol* sym) throw()
new ALiteral<int32_t>(T_INT32, index, Cursor()),
NULL);
} else {
- return sym;
+ return const_cast<ASymbol*>(sym);
}
}
@@ -64,16 +64,18 @@ lift_fn(CEnv& cenv, Code& code, ATuple* fn) throw()
cenv.push();
const AType* type = cenv.type(fn);
AType::const_iterator tp = type->prot()->begin();
- AType* implProtT = new AType(*type->prot()->as<const AType*>());
+ AType* implProtT = new AType(*type->prot()->as_type());
ATuple::iterator ip = implProtT->begin();
for (ATuple::const_iterator p = fn->prot()->begin(); p != fn->prot()->end(); ++p) {
- const AType* paramType = (*tp++)->as<const AType*>();
+ const AType* paramType = (*tp++)->as_type();
if (paramType->kind == AType::EXPR && *paramType->head() == *cenv.tenv.Fn) {
AType* fnType = new AType(*paramType);
- fnType->set_prot(new AType(const_cast<AType*>(cenv.tenv.var()), fnType->prot()->as<AType*>(), Cursor()));
+ fnType->set_prot(new AType(const_cast<AType*>(cenv.tenv.var()),
+ const_cast<AType*>(fnType->prot()->as_type()),
+ Cursor()));
paramType = tup<const AType>((*p)->loc, cenv.tenv.Tup, fnType, NULL);
}
- cenv.def((*p)->as<const ASymbol*>(), *p, paramType, NULL);
+ cenv.def((*p)->as_symbol(), *p, paramType, NULL);
*ip++ = new AType(*paramType);
}
@@ -111,7 +113,7 @@ lift_fn(CEnv& cenv, Code& code, ATuple* fn) throw()
const CEnv::FreeVars& freeVars = cenv.liftStack.top();
for (CEnv::FreeVars::const_iterator i = freeVars.begin(); i != freeVars.end(); ++i) {
- cons.push_back(*i);
+ cons.push_back(const_cast<ASymbol*>(*i));
tupT.push_back(const_cast<AType*>(cenv.type(*i)));
consT.push_back(const_cast<AType*>(cenv.type(*i)));
}
@@ -143,7 +145,7 @@ lift_call(CEnv& cenv, Code& code, ATuple* call) throw()
const AType* copyT = NULL;
- ASymbol* sym = call->head()->to<ASymbol*>();
+ const ASymbol* sym = call->head()->to_symbol();
if (sym && !cenv.liftStack.empty() && sym->cppstr == cenv.name(cenv.liftStack.top().fn)) {
/* Recursive call to innermost function, call implementation directly,
* reusing the current "_me" closure parameter (no cons or .).
@@ -157,11 +159,11 @@ lift_call(CEnv& cenv, Code& code, ATuple* call) throw()
* closure as the first parameter:
* (_impl (Fn _impl ...) ...)
*/
- ATuple* closure = copy.head->list_ref(0)->as<ATuple*>();
- ASymbol* implSym = closure->list_ref(1)->as<ASymbol*>();
+ ATuple* closure = copy.head->list_ref(0)->as_tuple();
+ ASymbol* implSym = const_cast<ASymbol*>(closure->list_ref(1)->as_symbol());
const AType* implT = cenv.type(cenv.resolve(implSym));
copy.push_front(implSym);
- copyT = implT->list_ref(2)->as<const AType*>();
+ copyT = implT->list_ref(2)->as_type();
} else {
// Call to a closure, prepend code to access implementation function
ATuple* getFn = tup<ATuple>(call->loc, cenv.penv.sym("."),
@@ -169,10 +171,10 @@ lift_call(CEnv& cenv, Code& code, ATuple* call) throw()
new ALiteral<int32_t>(T_INT32, 0, Cursor()), NULL);
const AType* calleeT = cenv.type(copy.head->head());
assert(**calleeT->begin() == *cenv.tenv.Tup);
- const AType* implT = calleeT->list_ref(1)->as<const AType*>();
+ const AType* implT = calleeT->list_ref(1)->as_type();
copy.push_front(getFn);
cenv.setType(getFn, implT);
- copyT = implT->list_ref(2)->as<const AType*>();
+ copyT = implT->list_ref(2)->as_type();
}
cenv.setType(copy, copyT);
@@ -183,13 +185,13 @@ static AST*
lift_def(CEnv& cenv, Code& code, ATuple* def) throw()
{
// Define stub first for recursion
- const ASymbol* const sym = def->list_ref(1)->as<const ASymbol*>();
+ const ASymbol* const sym = def->list_ref(1)->as_symbol();
AST* const body = def->list_ref(2);
cenv.def(sym, body, cenv.type(body), NULL);
if (is_form(body, "fn"))
- cenv.setName(body->as<const ATuple*>(), sym->str());
+ cenv.setName(body->as_tuple(), sym->str());
- assert(def->list_ref(1)->to<const ASymbol*>());
+ assert(def->list_ref(1)->to_symbol());
List<ATuple, AST> copy;
copy.push_back(def->head());
copy.push_back(resp_lift(cenv, code, def->list_ref(1)));
@@ -201,7 +203,7 @@ lift_def(CEnv& cenv, Code& code, ATuple* def) throw()
if (copy.head->list_ref(1) == copy.head->list_ref(2))
return NULL; // Definition created by lift_fn when body was lifted
- cenv.def(copy.head->list_ref(1)->as<const ASymbol*>(),
+ cenv.def(copy.head->list_ref(1)->as_symbol(),
copy.head->list_ref(2),
cenv.type(copy.head->list_ref(2)),
NULL);
@@ -225,13 +227,13 @@ lift_builtin_call(CEnv& cenv, Code& code, ATuple* call) throw()
AST*
resp_lift(CEnv& cenv, Code& code, AST* ast) throw()
{
- ASymbol* const sym = ast->to<ASymbol*>();
+ const ASymbol* const sym = ast->to_symbol();
if (sym)
return lift_symbol(cenv, code, sym);
- ATuple* const call = ast->to<ATuple*>();
+ ATuple* const call = ast->to_tuple();
if (call) {
- const ASymbol* const sym = call->head()->to<const ASymbol*>();
+ const ASymbol* const sym = call->head()->to_symbol();
const std::string form = sym ? sym->cppstr : "";
if (is_primitive(cenv.penv, call))
return lift_builtin_call(cenv, code, call);
diff --git a/src/llvm.cpp b/src/llvm.cpp
index 31e6f6d..eabe508 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -99,14 +99,14 @@ struct LLVMEngine : public Engine {
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();
- const ATuple* protT = (*++i)->to<const ATuple*>();
- const AType* retT = (*++i)->as<const AType*>();
+ const ATuple* protT = (*++i)->to_tuple();
+ const AType* retT = (*++i)->as_type();
if (!llType(retT))
return NULL;
vector<const Type*> cprot;
FOREACHP(ATuple::const_iterator, i, protT) {
- const Type* lt = llType((*i)->to<const AType*>());
+ const Type* lt = llType((*i)->to_type());
if (!lt)
return NULL;
cprot.push_back(lt);
@@ -117,7 +117,7 @@ struct LLVMEngine : public Engine {
vector<const Type*> ctypes;
ctypes.push_back(PointerType::get(Type::getInt8Ty(context), NULL)); // RTTI
for (AType::const_iterator i = t->iter_at(1); i != t->end(); ++i) {
- const Type* lt = llType((*i)->to<const AType*>());
+ const Type* lt = llType((*i)->to_type());
if (!lt)
return NULL;
ctypes.push_back(lt);
@@ -131,14 +131,14 @@ struct LLVMEngine : public Engine {
CFunc startFunction(CEnv& cenv,
const std::string& name, const ATuple* args, const AType* type)
{
- const AType* argsT = type->prot()->as<const AType*>();
- const AType* retT = type->list_last()->as<const AType*>();
+ const AType* argsT = type->prot()->as_type();
+ const AType* retT = type->list_last()->as_type();
Function::LinkageTypes linkage = Function::ExternalLinkage;
vector<const Type*> cprot;
FOREACHP(ATuple::const_iterator, i, argsT) {
- const AType* at = (*i)->as<const AType*>();
+ const AType* at = (*i)->as_type();
THROW_IF(!llType(at), Cursor(), string("non-concrete parameter :: ")
+ at->str())
cprot.push_back(llType(at));
@@ -158,7 +158,7 @@ struct LLVMEngine : public Engine {
// Set argument names in generated code
Function::arg_iterator a = f->arg_begin();
for (ATuple::const_iterator i = args->begin(); i != args->end(); ++a, ++i)
- a->setName((*i)->as<const ASymbol*>()->cppstr);
+ a->setName((*i)->as_symbol()->cppstr);
BasicBlock* bb = BasicBlock::Create(context, "entry", f);
builder.SetInsertPoint(bb);
@@ -186,7 +186,7 @@ struct LLVMEngine : public Engine {
CVal compileCall(CEnv& cenv, CFunc f, const AType* funcT, const vector<CVal>& args) {
vector<Value*> llArgs(*reinterpret_cast<const vector<Value*>*>(&args));
Value* closure = builder.CreateBitCast(llArgs[0],
- llType(funcT->prot()->head()->as<const AType*>()),
+ llType(funcT->prot()->head()->as_type()),
cenv.penv.gensymstr("you"));
llArgs[0] = closure;
return builder.CreateCall(llFunc(f), llArgs.begin(), llArgs.end());
@@ -279,7 +279,7 @@ LLVMEngine::compileTup(CEnv& cenv, const AType* type, CVal rtti, const vector<CV
size_t s = engine->getTargetData()->getTypeSizeInBits(PointerType::get(Type::getInt8Ty(context), NULL));
assert(type->begin() != type->end());
for (AType::const_iterator i = type->iter_at(1); i != type->end(); ++i)
- s += engine->getTargetData()->getTypeSizeInBits(llType((*i)->as<const AType*>()));
+ s += engine->getTargetData()->getTypeSizeInBits(llType((*i)->as_type()));
// Allocate struct
Value* structSize = ConstantInt::get(Type::getInt32Ty(context), bitsToBytes(s));
@@ -308,19 +308,16 @@ LLVMEngine::compileDot(CEnv& cenv, CVal tup, int32_t index)
CVal
LLVMEngine::compileLiteral(CEnv& cenv, const AST* lit)
{
- const ALiteral<int32_t>* ilit = dynamic_cast<const ALiteral<int32_t>*>(lit);
- if (ilit)
- return ConstantInt::get(Type::getInt32Ty(context), ilit->val, true);
-
- const ALiteral<float>* flit = dynamic_cast<const ALiteral<float>*>(lit);
- if (flit)
- return ConstantFP::get(Type::getFloatTy(context), flit->val);
-
- const ALiteral<bool>* blit = dynamic_cast<const ALiteral<bool>*>(lit);
- if (blit)
- return ConstantInt::get(Type::getInt1Ty(context), blit->val);
-
- throw Error(lit->loc, "Unknown literal type");
+ switch (lit->tag()) {
+ case T_BOOL:
+ return ConstantInt::get(Type::getInt1Ty(context), ((const ALiteral<bool>*)lit)->val);
+ case T_FLOAT:
+ return ConstantFP::get(Type::getFloatTy(context), ((const ALiteral<float>*)lit)->val);
+ case T_INT32:
+ return ConstantInt::get(Type::getInt32Ty(context), ((const ALiteral<int32_t>*)lit)->val, true);
+ default:
+ throw Error(lit->loc, "Unknown literal type");
+ }
}
CVal
@@ -334,7 +331,7 @@ LLVMEngine::pushFunctionArgs(CEnv& cenv, const ATuple* fn, const AType* type, CF
{
cenv.push();
- const AType* argsT = type->prot()->as<const AType*>();
+ const AType* argsT = type->prot()->as_type();
// Bind argument values in CEnv
vector<Value*> args;
@@ -343,10 +340,10 @@ LLVMEngine::pushFunctionArgs(CEnv& cenv, const ATuple* fn, const AType* type, CF
assert(fn->prot()->size() == argsT->size());
assert(fn->prot()->size() == f->num_args());
for (Function::arg_iterator a = llFunc(f)->arg_begin(); a != llFunc(f)->arg_end(); ++a, ++p, ++pT) {
- const AType* t = (*pT)->as<const AType*>();
+ const AType* t = (*pT)->as_type();
const Type* lt = llType(t);
THROW_IF(!lt, fn->loc, "untyped parameter\n");
- cenv.def((*p)->as<const ASymbol*>(), *p, t, &*a);
+ cenv.def((*p)->as_symbol(), *p, t, &*a);
}
}
@@ -419,7 +416,7 @@ LLVMEngine::compileMatch(CEnv& cenv, const ATuple* match)
for (ATuple::const_iterator i = match->iter_at(2); i != match->end(); ++idx) {
const AST* pat = *i++;
const AST* body = *i++;
- const ASymbol* sym = pat->to<const ATuple*>()->head()->as<const ASymbol*>();
+ const ASymbol* sym = pat->to_tuple()->head()->as_symbol();
const AType* patT = tup<AType>(Cursor(), const_cast<ASymbol*>(sym), 0);
Value* typeV = llVal(resp_compile(cenv, patT));
@@ -465,7 +462,7 @@ LLVMEngine::compilePrimitive(CEnv& cenv, const ATuple* prim)
bool isFloat = cenv.type(*++i)->str() == "Float";
Value* a = llVal(resp_compile(cenv, *i++));
Value* b = llVal(resp_compile(cenv, *i++));
- const string n = prim->head()->to<const ASymbol*>()->str();
+ const string n = prim->head()->to_symbol()->str();
// Binary arithmetic operations
Instruction::BinaryOps op = (Instruction::BinaryOps)0;
diff --git a/src/parse.cpp b/src/parse.cpp
index a9527ea..7f107aa 100644
--- a/src/parse.cpp
+++ b/src/parse.cpp
@@ -35,22 +35,22 @@ parseTuple(PEnv& penv, const ATuple* e)
AST*
PEnv::parse(const AST* exp)
{
- const ATuple* tup = exp->to<const ATuple*>();
+ const ATuple* tup = exp->to_tuple();
if (tup) {
THROW_IF(tup->empty(), exp->loc, "Call to empty list");
- const ALexeme* form = tup->head()->to<const ALexeme*>();
+ const ALexeme* form = tup->head()->to_lexeme();
if (form) {
MF mf = mac(*form);
if (mf) {
- exp = mf(*this, exp)->as<ATuple*>(); // Apply macro
- tup = exp->to<const ATuple*>();
+ exp = mf(*this, exp)->as_tuple(); // Apply macro
+ tup = exp->to_tuple();
}
}
}
if (tup) {
THROW_IF(tup->empty(), exp->loc, "Call to empty list");
- const ALexeme* form = tup->head()->to<const ALexeme*>();
+ const ALexeme* form = tup->head()->to_lexeme();
if (form) {
const PEnv::Handler* h = handler(true, form->cppstr);
if (h)
@@ -63,7 +63,7 @@ PEnv::parse(const AST* exp)
return parseTuple(*this, tup); // Parse regular call
}
- const ALexeme* lex = exp->to<const ALexeme*>();
+ const ALexeme* lex = exp->to_lexeme();
assert(lex);
if (isdigit(lex->cppstr[0])) {
const std::string& s = lex->cppstr;
@@ -89,16 +89,16 @@ PEnv::parse(const AST* exp)
inline AST*
macDef(PEnv& penv, const AST* exp)
{
- const ATuple* tup = exp->to<const ATuple*>();
+ const ATuple* tup = exp->to_tuple();
ATuple::const_iterator i = tup->begin();
THROW_IF(i == tup->end(), tup->loc, "Unexpected end of `def' macro call");
const AST* arg1 = *(++i);
THROW_IF(i == tup->end(), arg1->loc, "Unexpected end of `def' macro call");
- if (arg1->to<const ALexeme*>()) {
+ if (arg1->to_lexeme()) {
return const_cast<AST*>(exp);
} else {
// (def (f x) y) => (def f (fn (x) y))
- const ATuple* pat = arg1->to<const ATuple*>();
+ const ATuple* pat = arg1->to_tuple();
List<ATuple, AST> argsExp;
ATuple::const_iterator j = pat->begin();
@@ -131,7 +131,7 @@ macDef(PEnv& penv, const AST* exp)
inline AST*
parseCall(PEnv& penv, const AST* exp, void* arg)
{
- return parseTuple(penv, exp->to<const ATuple*>());
+ return parseTuple(penv, exp->to_tuple());
}
inline AST*
@@ -143,10 +143,10 @@ parseBool(PEnv& penv, const AST* exp, void* arg)
inline AST*
parseFn(PEnv& penv, const AST* exp, void* arg)
{
- const ATuple* texp = exp->to<const ATuple*>();
+ const ATuple* texp = exp->to_tuple();
ATuple::const_iterator a = texp->begin();
THROW_IF(++a == texp->end(), exp->loc, "Unexpected end of `fn' form");
- ATuple* prot = parseTuple(penv, (*a++)->to<const ATuple*>());
+ ATuple* prot = parseTuple(penv, (*a++)->to_tuple());
List<ATuple, AST> ret(new ATuple(penv.sym("fn"), NULL, Cursor()));
ret.push_back(prot);
while (a != texp->end())
@@ -158,9 +158,9 @@ parseFn(PEnv& penv, const AST* exp, void* arg)
inline AST*
parseQuote(PEnv& penv, const AST* exp, void* arg)
{
- const ATuple* texp = exp->to<const ATuple*>();
+ 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<const ALexeme*>();
+ 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;
diff --git a/src/pprint.cpp b/src/pprint.cpp
index 2f4180b..528683f 100644
--- a/src/pprint.cpp
+++ b/src/pprint.cpp
@@ -60,32 +60,12 @@ print_tuple(ostream& out, const ATuple* tup, ATuple::const_iterator i,
ostream&
print_to(ostream& out, const AST* ast, unsigned indent, CEnv* cenv, bool types)
{
- const ALexeme* lexeme = ast->to<const ALexeme*>();
- if (lexeme)
- return out << lexeme->cppstr;
-
- const ALiteral<float>* flit = ast->to<const ALiteral<float>*>();
- if (flit)
- return out << showpoint << flit->val;
-
- const ALiteral<int32_t>* ilit = ast->to<const ALiteral<int32_t>*>();
- if (ilit)
- return out << ilit->val;
-
- const ALiteral<bool>* blit = ast->to<const ALiteral<bool>*>();
- if (blit)
- return out << (blit->val ? "#t" : "#f");
-
- const AString* str = ast->to<const AString*>();
- if (str)
- return out << '"' << str->cppstr << '"';
-
- const ASymbol* sym = ast->to<const ASymbol*>();
- if (sym)
- return out << sym->cppstr;
-
- const AType* type = ast->to<const AType*>();
- if (type) {
+ switch (ast->tag()) {
+ case T_UNKNOWN:
+ return out << "?";
+ case T_TYPE:
+ {
+ const AType* type = ast->as_type();
switch (type->kind) {
case AType::VAR: return out << "?" << type->id;
case AType::NAME: return out << type->head();
@@ -93,20 +73,20 @@ print_to(ostream& out, const AST* ast, unsigned indent, CEnv* cenv, bool types)
case AType::DOTS: return out << "...";
case AType::EXPR: break; // will catch Tuple case below
}
- }
-
- const ATuple* tup = ast->to<const ATuple*>();
- if (tup) {
+ }
+ case T_TUPLE:
+ {
+ const ATuple* tup = ast->as_tuple();
out << "(";
ATuple::const_iterator i = tup->begin();
std::string form = "";
if (i != tup->end()) {
- const ASymbol* sym = (*i)->to<const ASymbol*>();
+ const ASymbol* sym = (*i)->to_symbol();
if (sym) {
form = sym->cppstr;
} else {
- const ALexeme* lexeme = (*i)->to<const ALexeme*>();
+ const ALexeme* lexeme = (*i)->to_lexeme();
if (lexeme)
form = lexeme->cppstr;
}
@@ -127,7 +107,7 @@ print_to(ostream& out, const AST* ast, unsigned indent, CEnv* cenv, bool types)
} else if (form == "fn") {
out << (*i++) << " ";
- const ATuple* pat = (*i++)->as<const ATuple*>();
+ const ATuple* pat = (*i++)->as_tuple();
// Print prototype (possibly with parameter type annotations)
out << "(";
@@ -161,6 +141,20 @@ print_to(ostream& out, const AST* ast, unsigned indent, CEnv* cenv, bool types)
} else {
return print_tuple(out, tup, i, indent + 1, false, cenv, types, false);
}
+ break;
+ }
+ case T_BOOL:
+ return out << showpoint << ((const ALiteral<bool>*)ast)->val;
+ case T_FLOAT:
+ 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:
+ return out << ((const ASymbol*)ast)->cppstr;
}
return out << "?";
diff --git a/src/repl.cpp b/src/repl.cpp
index f6f8a26..0ec644c 100644
--- a/src/repl.cpp
+++ b/src/repl.cpp
@@ -36,7 +36,7 @@ readParseType(CEnv& cenv, Cursor& cursor, istream& is, AST*& exp, AST*& ast)
throw e;
}
- if (exp->to<ATuple*>() && exp->to<ATuple*>()->empty())
+ if (exp->to_tuple() && exp->to_tuple()->empty())
return false;
ast = cenv.penv.parse(exp); // Parse input
@@ -114,12 +114,12 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute)
// Compile top-level (lifted) functions
Code exprs;
for (Code::const_iterator i = lifted.begin(); i != lifted.end(); ++i) {
- const ATuple* call = (*i)->to<const ATuple*>();
+ const ATuple* call = (*i)->to_tuple();
if (call && is_form(call, "def") && is_form(call->list_ref(2), "fn")) {
val = resp_compile(cenv, call);
} else {
assert(*i);
- ATuple* tup = (*i)->to<ATuple*>();
+ ATuple* tup = (*i)->to_tuple();
if (!tup || (tup->tup_len() > 0))
exprs.push_back(*i);
}
diff --git a/src/resp.cpp b/src/resp.cpp
index 611de0d..eb70e62 100644
--- a/src/resp.cpp
+++ b/src/resp.cpp
@@ -31,11 +31,11 @@ GC Object::pool(8 * 1024 * 1024);
bool
is_form(const AST* ast, const std::string& form)
{
- const ATuple* call = ast->to<const ATuple*>();
+ const ATuple* call = ast->to_tuple();
if (!call)
return false;
- const ASymbol* const sym = call->head()->to<const ASymbol*>();
+ const ASymbol* const sym = call->head()->to_symbol();
if (!sym)
return false;
@@ -45,11 +45,11 @@ is_form(const AST* ast, const std::string& form)
bool
is_primitive(const PEnv& penv, const AST* ast)
{
- const ATuple* call = ast->to<const ATuple*>();
+ const ATuple* call = ast->to_tuple();
if (!call)
return false;
- const ASymbol* const sym = call->head()->to<const ASymbol*>();
+ const ASymbol* const sym = call->head()->to_symbol();
if (!sym)
return false;
@@ -144,7 +144,7 @@ main(int argc, char** argv)
while (is.good() && !is.eof()) {
Cursor loc(*f);
AST* exp = readExpression(loc, is);
- if (!exp || (exp->as<ATuple*>() && exp->as<ATuple*>()->tup_len() == 1))
+ if (!exp || (exp->as_tuple() && exp->as_tuple()->tup_len() == 1))
break;
AST* ast = penv.parse(exp);
diff --git a/src/resp.hpp b/src/resp.hpp
index a092fb9..e4caac5 100644
--- a/src/resp.hpp
+++ b/src/resp.hpp
@@ -206,22 +206,67 @@ extern ostream& operator<<(ostream& out, const AST* ast);
typedef list<AST*> Code;
+struct ATuple;
+struct ASymbol;
+struct AType;
+struct ALexeme;
+
/// Base class for all AST nodes
struct AST : public Object {
AST(Tag t, Cursor c=Cursor()) : loc(c) { this->tag(t); }
- virtual ~AST() {}
bool operator==(const AST& o) const;
string str() const { ostringstream ss; ss << this; return ss.str(); }
- template<typename T> T to() { return dynamic_cast<T>(this); }
- template<typename T> T const to() const { return dynamic_cast<T const>(this); }
- template<typename T> T as() {
- T t = dynamic_cast<T>(this);
- return t ? t : throw Error(loc, "internal error: bad cast");
+
+ ATuple* as_tuple() {
+ assert(tag() == T_TUPLE || tag() == T_TYPE);
+ return (ATuple*)this;
+ }
+ const ATuple* as_tuple() const {
+ assert(tag() == T_TUPLE || tag() == T_TYPE);
+ return (ATuple*)this;
+ }
+
+ ATuple* to_tuple() {
+ if (tag() == T_TUPLE || tag() == T_TYPE)
+ return (ATuple*)this;
+ return NULL;
+ }
+ const ATuple* to_tuple() const {
+ if (tag() == T_TUPLE || tag() == T_TYPE)
+ return (const ATuple*)this;
+ return NULL;
+ }
+
+ template<typename T>
+ T* as_a(Tag t) {
+ assert(tag() == t);
+ return (T*)this;
+ }
+ template<typename T>
+ T* as_a(Tag t) const {
+ assert(tag() == t);
+ return (T*)this;
+ }
+
+ template<typename T>
+ T* to_a(Tag t) {
+ if (tag() == t)
+ return (T*)this;
+ return NULL;
}
- template<typename T> T const as() const {
- T const t = dynamic_cast<T const>(this);
- return t ? t : throw Error(loc, "internal error: bad cast");
+ template<typename T>
+ T* to_a(Tag t) const {
+ if (tag() == t)
+ return (T*)this;
+ return NULL;
}
+
+ 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); }
+
Cursor loc;
};
@@ -290,7 +335,6 @@ struct ATuple : public AST {
}
}
- ~ATuple() { free(_vec); }
const AST* head() const { assert(_len > 0); return _vec[0]; }
AST*& head() { assert(_len > 0); return _vec[0]; }
const AST* last() const { return _vec[_len - 1]; }
@@ -328,7 +372,7 @@ struct ATuple : public AST {
}
inline void increment() {
if (node->last())
- node = node->last()->as<ATuple*>();
+ node = node->last()->as_tuple();
else
node = NULL;
}
@@ -358,7 +402,7 @@ struct ATuple : public AST {
const_iterator(const iterator& i) : node(i.node) {}
inline void increment() {
if (node->last())
- node = node->last()->as<const ATuple*>();
+ node = node->last()->as_tuple();
else
node = NULL;
}
@@ -407,11 +451,12 @@ struct ATuple : public AST {
AST*& list_ref(unsigned index) { return *iter_at(index); }
const AST* list_ref(unsigned index) const { return *iter_at(index); }
- const ATuple* prot() const { return list_ref(1)->as<const ATuple*>(); }
- ATuple* prot() { return list_ref(1)->as<ATuple*>(); }
+ const ATuple* prot() const { return list_ref(1)->as_tuple(); }
+ ATuple* prot() { return list_ref(1)->as_tuple(); }
void set_prot(ATuple* prot) { *iter_at(1) = prot; }
private:
+ friend class GC;
size_t _len;
AST** _vec;
};
@@ -425,7 +470,7 @@ list_contains(const ATuple* head, const AST* child) {
if (**p == *child)
return true;
- const ATuple* tup = (*p)->to<const ATuple*>();
+ const ATuple* tup = (*p)->to_tuple();
if (tup && list_contains(tup, child))
return true;
}
@@ -450,7 +495,7 @@ struct AType : public ATuple {
case PRIM: return head()->str() != "Nothing";
case EXPR:
FOREACHP(const_iterator, t, this) {
- const AType* kid = (*t)->to<const AType*>();
+ const AType* kid = (*t)->to_type();
if (kid && !kid->concrete())
return false;
}
@@ -526,21 +571,21 @@ AST::operator==(const AST& rhs) const
switch (tag) {
case T_BOOL:
- return literal_equals(this->as<const ALiteral<bool>*>(), rhs.as<const ALiteral<bool>*>());
+ return literal_equals((const ALiteral<bool>*)this, (const ALiteral<bool>*)&rhs);
case T_FLOAT:
- return literal_equals(this->as<const ALiteral<float>*>(), rhs.as<const ALiteral<float>*>());
+ return literal_equals((const ALiteral<float>*)this, (const ALiteral<float>*)&rhs);
case T_INT32:
- return literal_equals(this->as<const ALiteral<int32_t>*>(), rhs.as<const ALiteral<int32_t>*>());
+ return literal_equals((const ALiteral<int32_t>*)this, (const ALiteral<int32_t>*)&rhs);
case T_TUPLE:
{
- const ATuple* me = this->as<const ATuple*>();
- const ATuple* rt = rhs.to<const ATuple*>();
+ const ATuple* me = this->as_tuple();
+ const ATuple* rt = rhs.to_tuple();
return list_equals(me, rt);
}
case T_TYPE:
{
- const AType* me = this->as<const AType*>();
- const AType* rt = rhs.to<const AType*>();
+ const AType* me = this->as_type();
+ const AType* rt = rhs.to_type();
if (!rt || me->kind != rt->kind) {
assert(str() != rt->str());
return false;
@@ -640,15 +685,15 @@ struct Subst : public list<Constraint> {
if (in->kind == AType::EXPR) {
TList out;
for (ATuple::const_iterator i = in->begin(); i != in->end(); ++i)
- out.push_back(const_cast<AType*>(apply((*i)->as<const AType*>())));
+ out.push_back(const_cast<AType*>(apply((*i)->as_type())));
out.head->loc = in->loc;
return out.head;
} else {
const_iterator i = find(in);
if (i != end()) {
- const AType* out = i->second->as<const AType*>();
+ const AType* out = i->second->as_type();
if (out->kind == AType::EXPR && !out->concrete())
- out = const_cast<AType*>(apply(out->as<const AType*>()));
+ out = const_cast<AType*>(apply(out->as_type()));
return out;
} else {
return new AType(*in);
@@ -790,7 +835,7 @@ struct CEnv {
}
const AType* type(const AST* ast, const Subst& subst = Subst()) const {
const AType* ret = NULL;
- const ASymbol* sym = ast->to<const ASymbol*>();
+ const ASymbol* sym = ast->to_symbol();
if (sym) {
const AType** rec = tenv.ref(sym);
if (rec)
@@ -799,7 +844,7 @@ struct CEnv {
if (!ret)
ret = tenv.vars[ast];
if (ret)
- return tsubst.apply(subst.apply(ret))->to<const AType*>();
+ return tsubst.apply(subst.apply(ret))->to_type();
return NULL;
}
void def(const ASymbol* sym, const AST* c, const AType* t, CVal v) {
@@ -808,7 +853,7 @@ struct CEnv {
vals.def(sym, v);
}
const AST* resolve(const AST* ast) {
- const ASymbol* sym = ast->to<const ASymbol*>();
+ const ASymbol* sym = ast->to_symbol();
const AST** rec = code.ref(sym);
return rec ? *rec : ast;
}
@@ -846,11 +891,11 @@ struct CEnv {
CFunc currentFn; ///< Currently compiling function
- struct FreeVars : public std::vector<ASymbol*> {
+ struct FreeVars : public std::vector<const ASymbol*> {
FreeVars(ATuple* f, const std::string& n) : fn(f), implName(n) {}
ATuple* const fn;
const std::string implName;
- int32_t index(ASymbol* sym) {
+ int32_t index(const ASymbol* sym) {
const_iterator i = find(begin(), end(), sym);
if (i != end()) {
return i - begin() + 1;
diff --git a/src/unify.cpp b/src/unify.cpp
index ec5aa9a..51179d9 100644
--- a/src/unify.cpp
+++ b/src/unify.cpp
@@ -31,19 +31,19 @@ TEnv::buildSubst(const AType* genericT, const AType& argsT)
Subst subst;
// Build substitution to apply to generic type
- const ATuple* genericProtT = genericT->list_ref(1)->as<const ATuple*>();
+ const ATuple* genericProtT = genericT->list_ref(1)->as_tuple();
ATuple::const_iterator g = genericProtT->begin();
AType::const_iterator a = argsT.begin();
for (; a != argsT.end(); ++a, ++g) {
- const AType* genericArgT = (*g)->to<const AType*>();
- const AType* callArgT = (*a)->to<const AType*>();
+ const AType* genericArgT = (*g)->to_type();
+ const AType* callArgT = (*a)->to_type();
if (callArgT->kind == AType::EXPR) {
assert(genericArgT->kind == AType::EXPR);
ATuple::const_iterator gi = genericArgT->begin();
ATuple::const_iterator ci = callArgT->begin();
for (; gi != genericArgT->end(); ++gi, ++ci) {
- const AType* gT = (*gi)->to<const AType*>();
- const AType* aT = (*ci)->to<const AType*>();
+ const AType* gT = (*gi)->to_type();
+ const AType* aT = (*ci)->to_type();
if (gT && aT)
subst.add(gT, aT);
}
@@ -60,7 +60,7 @@ Constraints::constrain(TEnv& tenv, const AST* o, const AType* t)
{
assert(o);
assert(t);
- assert(!o->to<const AType*>());
+ assert(!o->to_type());
push_back(Constraint(tenv.var(o), t));
}
@@ -75,13 +75,13 @@ substitute(const AType* tup, const AType* from, const AType* to)
type->loc = (*i)->loc;
ret.push_back(type);
} else if (*i != to) {
- const AType* elem = (*i)->as<const AType*>();
+ const AType* elem = (*i)->as_type();
if (elem->kind == AType::EXPR)
ret.push_back(const_cast<AType*>(substitute(elem, from, to)));
else
ret.push_back(const_cast<AType*>(elem));
} else {
- ret.push_back(const_cast<AType*>((*i)->as<const AType*>()));
+ ret.push_back(const_cast<AType*>((*i)->as_type()));
}
}
return ret.head;
@@ -148,15 +148,15 @@ unify(const Constraints& constraints)
AType::const_iterator si = s->begin();
AType::const_iterator ti = t->begin();
for (; si != s->end() && ti != t->end(); ++si, ++ti) {
- const AType* st = (*si)->as<const AType*>();
- const AType* tt = (*ti)->as<const AType*>();
+ const AType* st = (*si)->as_type();
+ const AType* tt = (*ti)->as_type();
if (st->kind == AType::DOTS || tt->kind == AType::DOTS)
return unify(cp);
else
cp.push_back(Constraint(st, tt));
}
- if ( (si == s->end() && (ti == t->end() || (*ti)->as<const AType*>()->kind == AType::DOTS))
- || (ti == t->end() && (*si)->as<const AType*>()->kind == AType::DOTS))
+ if ( (si == s->end() && (ti == t->end() || (*ti)->as_type()->kind == AType::DOTS))
+ || (ti == t->end() && (*si)->as_type()->kind == AType::DOTS))
return unify(cp);
}
throw Error(s->loc,