From fc33fd86b7727365caab44c05a90d5b52209131b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Nov 2013 20:14:54 +0100 Subject: [PATCH] Add a symbol __curPos that expands to the current source location I.e. an attribute set { file = ; line = ; column = ; }. --- src/libexpr/eval.cc | 13 +++++++++++++ src/libexpr/eval.hh | 3 ++- src/libexpr/nixexpr.cc | 9 +++++++++ src/libexpr/nixexpr.hh | 7 +++++++ src/libexpr/parser.y | 7 ++++++- tests/lang/eval-okay-curpos.exp | 1 + tests/lang/eval-okay-curpos.nix | 5 +++++ 7 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 tests/lang/eval-okay-curpos.exp create mode 100644 tests/lang/eval-okay-curpos.nix diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index b3fc6791a..7fb38c0fd 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 df34c7651..bcc029f5b 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 d52f7eadb..f4b4295e2 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 8336a48f4..61eb81fab 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 b4f72e599..7699cf502 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 000000000..65fd65b4d --- /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 000000000..b79553df0 --- /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 ]