mirror of
https://github.com/NixOS/nix
synced 2024-09-19 10:50:24 -04:00
libexpr: make "or"-as-variable less bogus
The previous place where OR_KW was inserted into the grammar to allow expressions like "map or [...]" led to a number of weird outcomes. By moving it to expr_simple, expressions using "or" as a variable are now parsed consistently with the rest of the language. Conflicts are prevented by telling Bison that OR_KW has higher precedence than '.'.
This commit is contained in:
parent
9300f855fc
commit
3b4892071d
|
@ -158,6 +158,9 @@ static void setDocPosition(const LexerState & lexerState, ExprLambda * lambda, P
|
||||||
%nonassoc '?'
|
%nonassoc '?'
|
||||||
%nonassoc NEGATE
|
%nonassoc NEGATE
|
||||||
|
|
||||||
|
%precedence '.'
|
||||||
|
%precedence OR_KW
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
start: expr { state->result = $1; };
|
start: expr { state->result = $1; };
|
||||||
|
@ -248,10 +251,6 @@ expr_select
|
||||||
{ $$ = new ExprSelect(CUR_POS, $1, std::move(*$3), nullptr); delete $3; }
|
{ $$ = new ExprSelect(CUR_POS, $1, std::move(*$3), nullptr); delete $3; }
|
||||||
| expr_simple '.' attrpath OR_KW expr_select
|
| expr_simple '.' attrpath OR_KW expr_select
|
||||||
{ $$ = new ExprSelect(CUR_POS, $1, std::move(*$3), $5); delete $3; }
|
{ $$ = new ExprSelect(CUR_POS, $1, std::move(*$3), $5); delete $3; }
|
||||||
| /* Backwards compatibility: because Nixpkgs has a rarely used
|
|
||||||
function named ‘or’, allow stuff like ‘map or [...]’. */
|
|
||||||
expr_simple OR_KW
|
|
||||||
{ $$ = new ExprCall(CUR_POS, $1, {new ExprVar(CUR_POS, state->s.or_)}); }
|
|
||||||
| expr_simple
|
| expr_simple
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -263,6 +262,9 @@ expr_simple
|
||||||
else
|
else
|
||||||
$$ = new ExprVar(CUR_POS, state->symbols.create($1));
|
$$ = new ExprVar(CUR_POS, state->symbols.create($1));
|
||||||
}
|
}
|
||||||
|
| /* Backwards compatibility: because Nixpkgs has a rarely used
|
||||||
|
function named ‘or’, allow stuff like ‘map or [...]’. */
|
||||||
|
OR_KW { $$ = new ExprVar(CUR_POS, state->s.or_); }
|
||||||
| INT_LIT { $$ = new ExprInt($1); }
|
| INT_LIT { $$ = new ExprInt($1); }
|
||||||
| FLOAT_LIT { $$ = new ExprFloat($1); }
|
| FLOAT_LIT { $$ = new ExprFloat($1); }
|
||||||
| '"' string_parts '"' { $$ = $2; }
|
| '"' string_parts '"' { $$ = $2; }
|
||||||
|
|
|
@ -190,7 +190,13 @@ namespace nix {
|
||||||
ASSERT_THAT(*b->value, IsIntEq(1));
|
ASSERT_THAT(*b->value, IsIntEq(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TrivialExpressionTest, orCantBeUsed) {
|
TEST_F(TrivialExpressionTest, orCanBeUsed) {
|
||||||
ASSERT_THROW(eval("let or = 1; in or"), Error);
|
auto v = eval("let or = 1; in or");
|
||||||
|
ASSERT_THAT(v, IsIntEq(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TrivialExpressionTest, orHasCorrectPrecedence) {
|
||||||
|
auto v = eval("let inherit (builtins) add; or = 2; in add 1 or");
|
||||||
|
ASSERT_THAT(v, IsIntEq(3));
|
||||||
}
|
}
|
||||||
} /* namespace nix */
|
} /* namespace nix */
|
||||||
|
|
Loading…
Reference in a new issue