about summary refs log tree commit diff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-02-04T16·03+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-02-04T16·03+0000
commit9b44480612dd30a7292ec94a88e4018b8f18e3f0 (patch)
tree0c83114806a4f7724a5dd8dcb0694103e70acb71 /src/libexpr/eval.cc
parentc4f7ae4aa5fc7071cfa853ec5d75aaf00e7a97fc (diff)
* Use a map to lookup primops.
* Various performance improvements in the evaluator.
* Do not link against unused (and missing!) libraries (-lsglr, etc.).

Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc68
1 files changed, 53 insertions, 15 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index bbb1393f8388..802b83aa160d 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -3,12 +3,52 @@
 #include "primops.hh"
 
 
+static void addPrimOp(ATermMap & map, const string & name, void * f)
+{
+    map.set(name, (ATerm) ATmakeBlob(0, f));
+}
+
+
+static void * lookupPrimOp(ATermMap & map, ATerm name)
+{
+    ATermBlob b = (ATermBlob) map.get(name);
+    if (!b) return 0;
+    return ATgetBlobData(b);
+}
+
+
 EvalState::EvalState()
-    : normalForms(32768, 75)
+    : normalForms(32768, 50)
 {
     blackHole = ATmake("BlackHole()");
     if (!blackHole) throw Error("cannot build black hole");
+    
     nrEvaluated = nrCached = 0;
+
+    addPrimOp0("true", primTrue);
+    addPrimOp0("false", primFalse);
+    addPrimOp0("null", primNull);
+
+    addPrimOp1("import", primImport);
+    addPrimOp1("derivation", primDerivation);
+    addPrimOp1("baseNameOf", primBaseNameOf);
+    addPrimOp1("toString", primToString);
+    addPrimOp1("isNull", primIsNull);
+
+    primOpsAll.add(primOps0);
+    primOpsAll.add(primOps1);
+}
+
+
+void EvalState::addPrimOp0(const string & name, PrimOp0 primOp)
+{
+    addPrimOp(primOps0, name, (void *) primOp);
+}
+
+
+void EvalState::addPrimOp1(const string & name, PrimOp1 primOp)
+{
+    addPrimOp(primOps1, name, (void *) primOp);
 }
 
 
@@ -130,7 +170,7 @@ Expr evalExpr2(EvalState & state, Expr e)
 {
     ATMatcher m;
     Expr e1, e2, e3, e4;
-    string s1;
+    ATerm name;
 
     /* Normal forms. */
     if (atMatch(m, e) >> "Str" ||
@@ -144,11 +184,12 @@ Expr evalExpr2(EvalState & state, Expr e)
         return e;
 
     /* Any encountered variables must be undeclared or primops. */
-    if (atMatch(m, e) >> "Var" >> s1) {
-        if (s1 == "null") return primNull(state);
-        if (s1 == "true") return ATmake("Bool(True)");
-        if (s1 == "false") return ATmake("Bool(False)");
-        return e;
+    if (atMatch(m, e) >> "Var" >> name) {
+        PrimOp0 primOp = (PrimOp0) lookupPrimOp(state.primOps0, name);
+        if (primOp)
+            return primOp(state);
+        else
+            return e;
     }
 
     /* Function application. */
@@ -160,13 +201,9 @@ Expr evalExpr2(EvalState & state, Expr e)
         e1 = evalExpr(state, e1);
 
         /* Is it a primop or a function? */
-        if (atMatch(m, e1) >> "Var" >> s1) {
-            if (s1 == "import") return primImport(state, e2);
-            if (s1 == "derivation") return primDerivation(state, e2);
-            if (s1 == "toString") return primToString(state, e2);
-            if (s1 == "baseNameOf") return primBaseNameOf(state, e2);
-            if (s1 == "isNull") return primIsNull(state, e2);
-            else throw badTerm("undefined variable/primop", e1);
+        if (atMatch(m, e1) >> "Var" >> name) {
+            PrimOp1 primOp = (PrimOp1) lookupPrimOp(state.primOps1, name);
+            if (primOp) return primOp(state, e2); else abort();
         }
 
         else if (atMatch(m, e1) >> "Function" >> formals >> e4)
@@ -177,6 +214,7 @@ Expr evalExpr2(EvalState & state, Expr e)
     }
 
     /* Attribute selection. */
+    string s1;
     if (atMatch(m, e) >> "Select" >> e1 >> s1) {
         Expr a = queryAttr(evalExpr(state, e1), s1);
         if (!a) throw badTerm(format("missing attribute `%1%'") % s1, e);
@@ -261,7 +299,7 @@ Expr evalExpr(EvalState & state, Expr e)
 Expr evalFile(EvalState & state, const Path & path)
 {
     startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
-    Expr e = parseExprFromFile(path);
+    Expr e = parseExprFromFile(state, path);
     return evalExpr(state, e);
 }