about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/eval.cc13
-rw-r--r--src/libexpr/eval.hh3
-rw-r--r--src/libexpr/nixexpr.cc9
-rw-r--r--src/libexpr/nixexpr.hh7
-rw-r--r--src/libexpr/parser.y7
-rw-r--r--tests/lang/eval-okay-curpos.exp1
-rw-r--r--tests/lang/eval-okay-curpos.nix5
7 files changed, 43 insertions, 2 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index b3fc6791a2ae..7fb38c0fd79c 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -142,6 +142,9 @@ EvalState::EvalState()
     , sOutputs(symbols.create("outputs"))
     , sOutputName(symbols.create("outputName"))
     , sIgnoreNulls(symbols.create("__ignoreNulls"))
+    , sFile(symbols.create("file"))
+    , sLine(symbols.create("line"))
+    , sColumn(symbols.create("column"))
     , repair(false)
     , baseEnv(allocEnv(128))
     , staticBaseEnv(false, 0)
@@ -1039,6 +1042,16 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
 }
 
 
+void ExprPos::eval(EvalState & state, Env & env, Value & v)
+{
+    state.mkAttrs(v, 3);
+    mkString(*state.allocAttr(v, state.sFile), pos.file);
+    mkInt(*state.allocAttr(v, state.sLine), pos.line);
+    mkInt(*state.allocAttr(v, state.sColumn), pos.column);
+    v.attrs->sort();
+}
+
+
 void EvalState::strictForceValue(Value & v)
 {
     forceValue(v);
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index df34c7651c10..bcc029f5b9b9 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -94,7 +94,8 @@ public:
     SymbolTable symbols;
 
     const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue,
-        sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls;
+        sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls,
+        sFile, sLine, sColumn;
     Symbol sDerivationNix;
 
     /* If set, force copying files to the Nix store even if they
diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc
index d52f7eadbbe3..f4b4295e290c 100644
--- a/src/libexpr/nixexpr.cc
+++ b/src/libexpr/nixexpr.cc
@@ -130,6 +130,11 @@ void ExprConcatStrings::show(std::ostream & str)
     }
 }
 
+void ExprPos::show(std::ostream & str)
+{
+    str << "__curPos";
+}
+
 
 std::ostream & operator << (std::ostream & str, const Pos & pos)
 {
@@ -315,6 +320,10 @@ void ExprConcatStrings::bindVars(const StaticEnv & env)
         (*i)->bindVars(env);
 }
 
+void ExprPos::bindVars(const StaticEnv & env)
+{
+}
+
 
 /* Storing function names. */
 
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index 8336a48f42fc..61eb81fab138 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -282,6 +282,13 @@ struct ExprConcatStrings : Expr
     COMMON_METHODS
 };
 
+struct ExprPos : Expr
+{
+    Pos pos;
+    ExprPos(const Pos & pos) : pos(pos) { };
+    COMMON_METHODS
+};
+
 
 /* Static environments are used to map variable names onto (level,
    displacement) pairs used to obtain the value of the variable at
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index b4f72e599b66..7699cf502b79 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -355,7 +355,12 @@ expr_select
   ;
 
 expr_simple
-  : ID { $$ = new ExprVar(CUR_POS, data->symbols.create($1)); }
+  : ID {
+      if (strcmp($1, "__curPos") == 0)
+          $$ = new ExprPos(CUR_POS);
+      else
+          $$ = new ExprVar(CUR_POS, data->symbols.create($1));
+  }
   | INT { $$ = new ExprInt($1); }
   | '"' string_parts '"' {
       /* For efficiency, and to simplify parse trees a bit. */
diff --git a/tests/lang/eval-okay-curpos.exp b/tests/lang/eval-okay-curpos.exp
new file mode 100644
index 000000000000..65fd65b4d01f
--- /dev/null
+++ b/tests/lang/eval-okay-curpos.exp
@@ -0,0 +1 @@
+[ 3 7 4 9 ]
diff --git a/tests/lang/eval-okay-curpos.nix b/tests/lang/eval-okay-curpos.nix
new file mode 100644
index 000000000000..b79553df0bd3
--- /dev/null
+++ b/tests/lang/eval-okay-curpos.nix
@@ -0,0 +1,5 @@
+# Bla
+let
+  x = __curPos;
+    y = __curPos;
+in [ x.line x.column y.line y.column ]