Compare commits
2 Commits
master
...
nix-lang-e
Author | SHA1 | Date |
---|---|---|
Eelco Dolstra | 2d52180455 | |
Eelco Dolstra | 64ea7cc437 |
|
@ -1386,6 +1386,23 @@ void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
|||
}
|
||||
|
||||
|
||||
void ExprInclude::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
Value vPath;
|
||||
path->eval(state, env, vPath);
|
||||
|
||||
PathSet context;
|
||||
auto realPath = state.checkSourcePath(
|
||||
state.toRealPath(state.coerceToPath(pos, vPath, context), context));
|
||||
|
||||
printTalkative("including file '%1%'", realPath);
|
||||
|
||||
auto e = state.parseExprFromFile(resolveExprPath(realPath), *staticEnv);
|
||||
|
||||
e->eval(state, env, v);
|
||||
}
|
||||
|
||||
|
||||
void EvalState::forceValueDeep(Value & v)
|
||||
{
|
||||
std::set<const Value *> seen;
|
||||
|
|
|
@ -109,6 +109,7 @@ in { return IN; }
|
|||
rec { return REC; }
|
||||
inherit { return INHERIT; }
|
||||
or { return OR_KW; }
|
||||
include { return INCLUDE; }
|
||||
\.\.\. { return ELLIPSIS; }
|
||||
|
||||
\=\= { return EQ; }
|
||||
|
|
|
@ -191,6 +191,11 @@ void ExprPos::show(std::ostream & str)
|
|||
str << "__curPos";
|
||||
}
|
||||
|
||||
void ExprInclude::show(std::ostream & str)
|
||||
{
|
||||
str << "(include " << *path << ")";
|
||||
}
|
||||
|
||||
|
||||
std::ostream & operator << (std::ostream & str, const Pos & pos)
|
||||
{
|
||||
|
@ -402,6 +407,24 @@ void ExprPos::bindVars(const StaticEnv & env)
|
|||
{
|
||||
}
|
||||
|
||||
void ExprInclude::bindVars(const StaticEnv & env)
|
||||
{
|
||||
path->bindVars(env);
|
||||
|
||||
/* Copy the static environment so that ExprInclude::eval() can
|
||||
pass it to parseExprFromFile(). FIXME: if there are many uses
|
||||
of 'include' in the same scope, we should cache this. */
|
||||
|
||||
const StaticEnv * srcEnv = &env;
|
||||
StaticEnv * * dstEnv = &staticEnv;
|
||||
|
||||
while (srcEnv) {
|
||||
*dstEnv = new StaticEnv(*srcEnv);
|
||||
srcEnv = srcEnv->up;
|
||||
dstEnv = (StaticEnv * *) &(*dstEnv)->up;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Storing function names. */
|
||||
|
||||
|
|
|
@ -86,9 +86,9 @@ struct Expr
|
|||
std::ostream & operator << (std::ostream & str, Expr & e);
|
||||
|
||||
#define COMMON_METHODS \
|
||||
void show(std::ostream & str); \
|
||||
void eval(EvalState & state, Env & env, Value & v); \
|
||||
void bindVars(const StaticEnv & env);
|
||||
void show(std::ostream & str) override; \
|
||||
void eval(EvalState & state, Env & env, Value & v) override; \
|
||||
void bindVars(const StaticEnv & env) override;
|
||||
|
||||
struct ExprInt : Expr
|
||||
{
|
||||
|
@ -326,6 +326,15 @@ struct ExprPos : Expr
|
|||
COMMON_METHODS
|
||||
};
|
||||
|
||||
struct ExprInclude : Expr
|
||||
{
|
||||
Pos pos;
|
||||
Expr * path;
|
||||
StaticEnv * staticEnv;
|
||||
ExprInclude(const Pos & pos, Expr * path) : pos(pos), path(path) { };
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
||||
/* Static environments are used to map variable names onto (level,
|
||||
displacement) pairs used to obtain the value of the variable at
|
||||
|
|
|
@ -270,7 +270,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err
|
|||
%token <nf> FLOAT
|
||||
%token <path> PATH HPATH SPATH
|
||||
%token <uri> URI
|
||||
%token IF THEN ELSE ASSERT WITH LET IN REC INHERIT EQ NEQ AND OR IMPL OR_KW
|
||||
%token IF THEN ELSE ASSERT WITH LET IN REC INHERIT EQ NEQ AND OR IMPL OR_KW INCLUDE
|
||||
%token DOLLAR_CURLY /* == ${ */
|
||||
%token IND_STRING_OPEN IND_STRING_CLOSE
|
||||
%token ELLIPSIS
|
||||
|
@ -348,6 +348,7 @@ expr_app
|
|||
: expr_app expr_select
|
||||
{ $$ = new ExprApp(CUR_POS, $1, $2); }
|
||||
| expr_select { $$ = $1; }
|
||||
| INCLUDE expr_select { $$ = new ExprInclude(CUR_POS, $2); }
|
||||
;
|
||||
|
||||
expr_select
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
true
|
|
@ -0,0 +1,16 @@
|
|||
assert include ./include-1.nix == 1;
|
||||
assert let x = 100; in include ./include-1.nix == 1;
|
||||
assert with { x = 123; }; include ./include-1.nix == 1;
|
||||
|
||||
assert let x = 2; in include ./include-2.nix == 3;
|
||||
assert let x = 3; in include ./include-2.nix == 4;
|
||||
assert let x = 3; in let x = 4; in include ./include-2.nix == 5;
|
||||
assert let x = 3; in let x = 4; in include ./include-2.nix == 5;
|
||||
assert let x = 6; in with { x = 7; }; include ./include-2.nix == 7;
|
||||
assert with { x = 0; }; let x = 6; in with { x = 7; }; include ./include-2.nix == 7;
|
||||
assert with { x = 0; }; let x = 6; in with { x = 7; }; let x = 7; in include ./include-2.nix == 8;
|
||||
assert with { x = 8; }; include ./include-2.nix == 9;
|
||||
|
||||
assert (let x = 10; in include ./include-3.nix) == 3628800;
|
||||
|
||||
true
|
|
@ -0,0 +1 @@
|
|||
let x = 1; in x
|
|
@ -0,0 +1 @@
|
|||
1 + x
|
|
@ -0,0 +1 @@
|
|||
if x > 0 then x * (let x_ = x; in let x = x_ - 1; in include ./include-3.nix) else 1
|
Loading…
Reference in New Issue