aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-25 15:38:37 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-25 15:38:37 +0000
commitc2ba4313fb7f2e257f6205eb3fa366376c3010b0 (patch)
tree4d857a59d23a0bee1d8fd241dfe72769c1473f9a /src/libexpr
parent25eedf085d9b3a1ad7d0e6969b050a2f73234ae3 (diff)
* Implemented lists.
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval-test.cc70
1 files changed, 63 insertions, 7 deletions
diff --git a/src/libexpr/eval-test.cc b/src/libexpr/eval-test.cc
index 8f02d8cc5..c40912c13 100644
--- a/src/libexpr/eval-test.cc
+++ b/src/libexpr/eval-test.cc
@@ -27,6 +27,7 @@ struct Env
typedef enum {
tInt = 1,
tAttrs,
+ tList,
tThunk,
tLambda,
tCopy,
@@ -42,6 +43,10 @@ struct Value
int integer;
Bindings * attrs;
struct {
+ unsigned int length;
+ Value * elems;
+ } list;
+ struct {
Env * env;
Expr expr;
} thunk;
@@ -64,9 +69,15 @@ std::ostream & operator << (std::ostream & str, Value & v)
case tAttrs:
str << "{ ";
foreach (Bindings::iterator, i, *v.attrs)
- str << i->first << " = " << i->second << "; ";
+ str << aterm2String(i->first) << " = " << i->second << "; ";
str << "}";
break;
+ case tList:
+ str << "[ ";
+ for (unsigned int n = 0; n < v.list.length; ++n)
+ str << v.list.elems[n] << " ";
+ str << "]";
+ break;
case tThunk:
str << "<CODE>";
break;
@@ -141,9 +152,7 @@ static Value * lookupVar(Env * env, Sym name)
}
-unsigned long nrValues = 0;
-
-unsigned long nrEnvs = 0;
+unsigned long nrValues = 0, nrEnvs = 0;
static Env * allocEnv()
{
@@ -207,7 +216,7 @@ static void eval(Env * env, Expr e, Value & v)
return;
}
- Expr e2;
+ Expr e1, e2;
if (matchSelect(e, e2, name)) {
eval(env, e2, v);
if (v.type != tAttrs) throw TypeError("expected attribute set");
@@ -310,7 +319,52 @@ static void eval(Env * env, Expr e, Value & v)
return;
}
- abort();
+ if (matchList(e, es)) {
+ v.type = tList;
+ v.list.length = ATgetLength(es);
+ v.list.elems = new Value[v.list.length]; // !!! check destructor
+ for (unsigned int n = 0; n < v.list.length; ++n, es = ATgetNext(es)) {
+ v.list.elems[n].type = tThunk;
+ v.list.elems[n].thunk.env = env;
+ v.list.elems[n].thunk.expr = ATgetFirst(es);
+ }
+ return;
+ }
+
+ if (matchOpConcat(e, e1, e2)) {
+ Value v1; eval(env, e1, v1);
+ if (v1.type != tList) throw TypeError("list expecteed");
+ Value v2; eval(env, e2, v2);
+ if (v2.type != tList) throw TypeError("list expecteed");
+ v.type = tList;
+ v.list.length = v1.list.length + v2.list.length;
+ v.list.elems = new Value[v.list.length];
+ /* !!! This loses sharing with the original lists. We could
+ use a tCopy node, but that would use more memory. */
+ for (unsigned int n = 0; n < v1.list.length; ++n)
+ v.list.elems[n] = v1.list.elems[n];
+ for (unsigned int n = 0; n < v2.list.length; ++n)
+ v.list.elems[n + v1.list.length] = v2.list.elems[n];
+ return;
+ }
+
+ throw Error("unsupported term");
+}
+
+
+static void strictEval(Env * env, Expr e, Value & v)
+{
+ eval(env, e, v);
+
+ if (v.type == tAttrs) {
+ foreach (Bindings::iterator, i, *v.attrs)
+ forceValue(i->second);
+ }
+
+ else if (v.type == tList) {
+ for (unsigned int n = 0; n < v.list.length; ++n)
+ forceValue(v.list.elems[n]);
+ }
}
@@ -320,7 +374,7 @@ void doTest(string s)
Expr e = parseExprFromString(state, s, "/");
printMsg(lvlError, format(">>>>> %1%") % e);
Value v;
- eval(0, e, v);
+ strictEval(0, e, v);
printMsg(lvlError, format("result: %1%") % v);
}
@@ -348,6 +402,8 @@ void run(Strings args)
doTest("with { x = 1; }; x");
doTest("let x = 2; in with { x = 1; }; x"); // => 2
doTest("with { x = 1; }; with { x = 2; }; x"); // => 1
+ doTest("[ 1 2 3 ]");
+ doTest("[ 1 2 ] ++ [ 3 4 5 ]");
printMsg(lvlError, format("alloced %1% values") % nrValues);
printMsg(lvlError, format("alloced %1% environments") % nrEnvs);