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 NEGATE
|
||||
|
||||
%precedence '.'
|
||||
%precedence OR_KW
|
||||
|
||||
%%
|
||||
|
||||
start: expr { state->result = $1; };
|
||||
|
@ -248,10 +251,6 @@ expr_select
|
|||
{ $$ = new ExprSelect(CUR_POS, $1, std::move(*$3), nullptr); delete $3; }
|
||||
| expr_simple '.' attrpath OR_KW expr_select
|
||||
{ $$ = 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
|
||||
;
|
||||
|
||||
|
@ -263,6 +262,9 @@ expr_simple
|
|||
else
|
||||
$$ = 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); }
|
||||
| FLOAT_LIT { $$ = new ExprFloat($1); }
|
||||
| '"' string_parts '"' { $$ = $2; }
|
||||
|
|
|
@ -190,7 +190,13 @@ namespace nix {
|
|||
ASSERT_THAT(*b->value, IsIntEq(1));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, orCantBeUsed) {
|
||||
ASSERT_THROW(eval("let or = 1; in or"), Error);
|
||||
TEST_F(TrivialExpressionTest, orCanBeUsed) {
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue