aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-03-07 04:35:13 +0000
committerDavid Robillard <d@drobilla.net>2009-03-07 04:35:13 +0000
commitb754068a1e11cf480469836c6a04c6614f4d63c5 (patch)
tree7aa986f288e6b967db5b2de664acbe29a13690d3
parent6d9b8a06e9d9fece731d045db2f815f261db09c3 (diff)
downloadresp-b754068a1e11cf480469836c6a04c6614f4d63c5.tar.gz
resp-b754068a1e11cf480469836c6a04c6614f4d63c5.tar.bz2
resp-b754068a1e11cf480469836c6a04c6614f4d63c5.zip
Stream based serialisation of AST nodes (can write arbitrarily large expressions without chewing memory).
git-svn-id: http://svn.drobilla.net/resp/tuplr@75 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--Makefile2
-rw-r--r--llvm.cpp4
-rw-r--r--tuplr.hpp32
-rw-r--r--write.cpp55
4 files changed, 68 insertions, 25 deletions
diff --git a/Makefile b/Makefile
index 001c37d..5ab2806 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ LLVM_LDFLAGS=`llvm-config --ldflags --libs core jit native`
CXXFLAGS=-O0 -g -Wall -Wextra -Wno-unused-parameter $(LLVM_CXXFLAGS)
LDFLAGS=$(LLVM_LDFLAGS) -lm
-tuplr: tuplr.o typing.o llvm.o
+tuplr: tuplr.o typing.o llvm.o write.o
g++ -o $@ $^ $(LDFLAGS)
%.o: %.cpp tuplr.hpp
diff --git a/llvm.cpp b/llvm.cpp
index c0c46c9..3ccb1d7 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -540,7 +540,7 @@ eval(CEnv& cenv, const string& name, istream& is)
cenv.optimise(f);
cenv.log.out << call(resultType, cenv.engine.engine->getPointerToFunction(f))
- << " : " << resultType->str() << endl;
+ << " : " << resultType << endl;
} catch (Error& e) {
cenv.log.err << e.what() << endl;
return 1;
@@ -584,7 +584,7 @@ repl(CEnv& cenv)
} else {
cenv.log.out << "; " << cenv.compile(body);
}
- cenv.log.out << " : " << cenv.tenv.type(body)->str() << endl;
+ cenv.log.out << " : " << cenv.tenv.type(body) << endl;
} catch (Error& e) {
cenv.log.err << e.what() << endl;
}
diff --git a/tuplr.hpp b/tuplr.hpp
index 29b8463..a931f8c 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -22,6 +22,7 @@
#include <iostream>
#include <list>
#include <map>
+#include <sstream>
#include <string>
#include <vector>
#include <boost/format.hpp>
@@ -95,19 +96,22 @@ struct CEngine; ///< Backend data (opaque)
struct TEnv; ///< Type-Time Environment
struct CEnv; ///< Compile-Time Environment
+struct AST;
+extern ostream& operator<<(ostream& out, const AST* ast);
+
/// Base class for all AST nodes
struct AST {
AST(Cursor c=Cursor()) : loc(c) {}
virtual ~AST() {}
- virtual string str() const = 0;
virtual bool operator==(const AST& o) const = 0;
virtual bool contains(const AST* child) const { return false; }
virtual void constrain(TEnv& tenv) const {}
virtual void lift(CEnv& cenv) {}
+ string str() const { ostringstream ss; ss << this; return ss.str(); }
Cursor loc;
private:
friend class CEnv;
- virtual CValue compile(CEnv& cenv) = 0;
+ virtual CValue compile(CEnv& cenv) = 0;
};
/// Literal value
@@ -118,7 +122,6 @@ struct ASTLiteral : public AST {
const ASTLiteral<VT>* r = dynamic_cast<const ASTLiteral<VT>*>(&rhs);
return (r && (val == r->val));
}
- string str() const { return (format("%1%") % val).str(); }
void constrain(TEnv& tenv) const;
CValue compile(CEnv& cenv);
const VT val;
@@ -127,12 +130,12 @@ struct ASTLiteral : public AST {
/// Symbol, e.g. "a"
struct ASTSymbol : public AST {
bool operator==(const AST& rhs) const { return this == &rhs; }
- string str() const { return cppstr; }
void lift(CEnv& cenv);
CValue compile(CEnv& cenv);
private:
friend class PEnv;
ASTSymbol(const string& s, Cursor c) : AST(c), cppstr(s) {}
+ friend ostream& operator<<(ostream&, const AST*);
const string cppstr;
};
@@ -147,12 +150,6 @@ struct ASTTuple : public AST, public vector<AST*> {
push_back(a);
va_end(args);
}
- string str() const {
- string ret = "(";
- for (size_t i = 0; i != size(); ++i)
- ret += (at(i) ? at(i)->str() : "NULL") + ((i != size() - 1) ? " " : "");
- return ret + ")";
- }
bool operator==(const AST& rhs) const {
const ASTTuple* rt = dynamic_cast<const ASTTuple*>(&rhs);
if (!rt || rt->size() != size()) return false;
@@ -189,14 +186,6 @@ struct AType : public ASTTuple {
push_back(a);
va_end(args);
}
- string str() const {
- switch (kind) {
- case VAR: return (format("?%1%") % id).str();
- case PRIM: return at(0)->str();
- case EXPR: return ASTTuple::str();
- }
- return ""; // never reached
- }
void constrain(TEnv& tenv) const {}
CValue compile(CEnv& cenv) { return NULL; }
bool var() const { return kind == VAR; }
@@ -241,10 +230,9 @@ struct Funcs : public list< pair<AType*, CFunction> > {
/// Closure (first-class function with captured lexical bindings)
struct ASTClosure : public ASTTuple {
- ASTClosure(Cursor c, ASTTuple* p, AST* b, const string& n="")
- : ASTTuple(c, 0, p, b, NULL), name(n) {}
+ ASTClosure(Cursor c, ASTSymbol* fn, ASTTuple* p, AST* b, const string& n="")
+ : ASTTuple(c, fn, p, b, NULL), name(n) {}
bool operator==(const AST& rhs) const { return this == &rhs; }
- string str() const { return (format("%1%") % this).str(); }
void constrain(TEnv& tenv) const;
void lift(CEnv& cenv);
CValue compile(CEnv& cenv);
@@ -392,7 +380,7 @@ inline AST*
parseFn(PEnv& penv, const SExp& exp, void* arg)
{
SExp::List::const_iterator a = exp.list.begin(); ++a;
- return new ASTClosure(exp.loc,
+ return new ASTClosure(exp.loc, penv.sym("fn"),
new ASTTuple(pmap(penv, *a++)),
parseExpression(penv, *a++));
}
diff --git a/write.cpp b/write.cpp
new file mode 100644
index 0000000..b5784ab
--- /dev/null
+++ b/write.cpp
@@ -0,0 +1,55 @@
+/* Tuplr Serialisation
+ * Copyright (C) 2008-2009 David Robillard <dave@drobilla.net>
+ *
+ * Tuplr is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Affero General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * Tuplr is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Tuplr. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tuplr.hpp"
+
+ostream&
+operator<<(ostream& out, const AST* ast)
+{
+#define TRY_WRITE_LITERAL(T) \
+ const ASTLiteral<T>* lit ## T = dynamic_cast<const ASTLiteral<T>*>(ast); \
+ if (lit ## T) \
+ return out << (lit ## T)->val;
+
+ TRY_WRITE_LITERAL(int32_t);
+ TRY_WRITE_LITERAL(float);
+ TRY_WRITE_LITERAL(bool);
+
+ const ASTSymbol* sym = dynamic_cast<const ASTSymbol*>(ast);
+ if (sym)
+ return out << sym->cppstr;
+
+ const AType* type = dynamic_cast<const AType*>(ast);
+ if (type) {
+ switch (type->kind) {
+ case AType::VAR: return out << "?" << type->id;
+ case AType::PRIM: return out << type->at(0);
+ case AType::EXPR: break; // will catch Tuple case below
+ }
+ }
+
+ const ASTTuple* tup = dynamic_cast<const ASTTuple*>(ast);
+ if (tup) {
+ out << "(";
+ for (size_t i = 0; i != tup->size(); ++i)
+ out << tup->at(i) << ((i != tup->size() - 1) ? " " : "");
+ return out << ")";
+ }
+
+ return out << "?";
+}
+