Merge pull request #5341 from andir/libexpr-formals

libexpr: remove matchAttrs boolean from ExprLambda
This commit is contained in:
Eelco Dolstra 2021-10-07 11:58:56 +02:00 committed by GitHub
commit c9ee634f75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 18 additions and 18 deletions

View file

@ -1316,13 +1316,13 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
auto size = auto size =
(lambda.arg.empty() ? 0 : 1) + (lambda.arg.empty() ? 0 : 1) +
(lambda.matchAttrs ? lambda.formals->formals.size() : 0); (lambda.hasFormals() ? lambda.formals->formals.size() : 0);
Env & env2(allocEnv(size)); Env & env2(allocEnv(size));
env2.up = fun.lambda.env; env2.up = fun.lambda.env;
size_t displ = 0; size_t displ = 0;
if (!lambda.matchAttrs) if (!lambda.hasFormals())
env2.values[displ++] = &arg; env2.values[displ++] = &arg;
else { else {
@ -1402,7 +1402,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
} }
} }
if (!fun.isLambda() || !fun.lambda.fun->matchAttrs) { if (!fun.isLambda() || !fun.lambda.fun->hasFormals()) {
res = fun; res = fun;
return; return;
} }

View file

@ -231,7 +231,7 @@ static Flake getFlake(
if (auto outputs = vInfo.attrs->get(sOutputs)) { if (auto outputs = vInfo.attrs->get(sOutputs)) {
expectType(state, nFunction, *outputs->value, *outputs->pos); expectType(state, nFunction, *outputs->value, *outputs->pos);
if (outputs->value->isLambda() && outputs->value->lambda.fun->matchAttrs) { if (outputs->value->isLambda() && outputs->value->lambda.fun->hasFormals()) {
for (auto & formal : outputs->value->lambda.fun->formals->formals) { for (auto & formal : outputs->value->lambda.fun->formals->formals) {
if (formal.name != state.sSelf) if (formal.name != state.sSelf)
flake.inputs.emplace(formal.name, FlakeInput { flake.inputs.emplace(formal.name, FlakeInput {

View file

@ -124,7 +124,7 @@ void ExprList::show(std::ostream & str) const
void ExprLambda::show(std::ostream & str) const void ExprLambda::show(std::ostream & str) const
{ {
str << "("; str << "(";
if (matchAttrs) { if (hasFormals()) {
str << "{ "; str << "{ ";
bool first = true; bool first = true;
for (auto & i : formals->formals) { for (auto & i : formals->formals) {
@ -348,7 +348,7 @@ void ExprLambda::bindVars(const StaticEnv & env)
if (!arg.empty()) newEnv.vars[arg] = displ++; if (!arg.empty()) newEnv.vars[arg] = displ++;
if (matchAttrs) { if (hasFormals()) {
for (auto & i : formals->formals) for (auto & i : formals->formals)
newEnv.vars[i.name] = displ++; newEnv.vars[i.name] = displ++;

View file

@ -233,11 +233,10 @@ struct ExprLambda : Expr
Pos pos; Pos pos;
Symbol name; Symbol name;
Symbol arg; Symbol arg;
bool matchAttrs;
Formals * formals; Formals * formals;
Expr * body; Expr * body;
ExprLambda(const Pos & pos, const Symbol & arg, bool matchAttrs, Formals * formals, Expr * body) ExprLambda(const Pos & pos, const Symbol & arg, Formals * formals, Expr * body)
: pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body) : pos(pos), arg(arg), formals(formals), body(body)
{ {
if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end()) if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end())
throw ParseError({ throw ParseError({
@ -247,6 +246,7 @@ struct ExprLambda : Expr
}; };
void setName(Symbol & name); void setName(Symbol & name);
string showNamePos() const; string showNamePos() const;
inline bool hasFormals() const { return formals != nullptr; }
COMMON_METHODS COMMON_METHODS
}; };

View file

@ -324,13 +324,13 @@ expr: expr_function;
expr_function expr_function
: ID ':' expr_function : ID ':' expr_function
{ $$ = new ExprLambda(CUR_POS, data->symbols.create($1), false, 0, $3); } { $$ = new ExprLambda(CUR_POS, data->symbols.create($1), 0, $3); }
| '{' formals '}' ':' expr_function | '{' formals '}' ':' expr_function
{ $$ = new ExprLambda(CUR_POS, data->symbols.create(""), true, $2, $5); } { $$ = new ExprLambda(CUR_POS, data->symbols.create(""), $2, $5); }
| '{' formals '}' '@' ID ':' expr_function | '{' formals '}' '@' ID ':' expr_function
{ $$ = new ExprLambda(CUR_POS, data->symbols.create($5), true, $2, $7); } { $$ = new ExprLambda(CUR_POS, data->symbols.create($5), $2, $7); }
| ID '@' '{' formals '}' ':' expr_function | ID '@' '{' formals '}' ':' expr_function
{ $$ = new ExprLambda(CUR_POS, data->symbols.create($1), true, $4, $7); } { $$ = new ExprLambda(CUR_POS, data->symbols.create($1), $4, $7); }
| ASSERT expr ';' expr_function | ASSERT expr ';' expr_function
{ $$ = new ExprAssert(CUR_POS, $2, $4); } { $$ = new ExprAssert(CUR_POS, $2, $4); }
| WITH expr ';' expr_function | WITH expr ';' expr_function

View file

@ -2381,7 +2381,7 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args
.errPos = pos .errPos = pos
}); });
if (!args[0]->lambda.fun->matchAttrs) { if (!args[0]->lambda.fun->hasFormals()) {
state.mkAttrs(v, 0); state.mkAttrs(v, 0);
return; return;
} }

View file

@ -135,7 +135,7 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
if (location) posToXML(xmlAttrs, v.lambda.fun->pos); if (location) posToXML(xmlAttrs, v.lambda.fun->pos);
XMLOpenElement _(doc, "function", xmlAttrs); XMLOpenElement _(doc, "function", xmlAttrs);
if (v.lambda.fun->matchAttrs) { if (v.lambda.fun->hasFormals()) {
XMLAttrs attrs; XMLAttrs attrs;
if (!v.lambda.fun->arg.empty()) attrs["name"] = v.lambda.fun->arg; if (!v.lambda.fun->arg.empty()) attrs["name"] = v.lambda.fun->arg;
if (v.lambda.fun->formals->ellipsis) attrs["ellipsis"] = "1"; if (v.lambda.fun->formals->ellipsis) attrs["ellipsis"] = "1";

View file

@ -346,10 +346,10 @@ struct CmdFlakeCheck : FlakeCommand
auto checkOverlay = [&](const std::string & attrPath, Value & v, const Pos & pos) { auto checkOverlay = [&](const std::string & attrPath, Value & v, const Pos & pos) {
try { try {
state->forceValue(v, pos); state->forceValue(v, pos);
if (!v.isLambda() || v.lambda.fun->matchAttrs || std::string(v.lambda.fun->arg) != "final") if (!v.isLambda() || v.lambda.fun->hasFormals() || std::string(v.lambda.fun->arg) != "final")
throw Error("overlay does not take an argument named 'final'"); throw Error("overlay does not take an argument named 'final'");
auto body = dynamic_cast<ExprLambda *>(v.lambda.fun->body); auto body = dynamic_cast<ExprLambda *>(v.lambda.fun->body);
if (!body || body->matchAttrs || std::string(body->arg) != "prev") if (!body || body->hasFormals() || std::string(body->arg) != "prev")
throw Error("overlay does not take an argument named 'prev'"); throw Error("overlay does not take an argument named 'prev'");
// FIXME: if we have a 'nixpkgs' input, use it to // FIXME: if we have a 'nixpkgs' input, use it to
// evaluate the overlay. // evaluate the overlay.
@ -363,7 +363,7 @@ struct CmdFlakeCheck : FlakeCommand
try { try {
state->forceValue(v, pos); state->forceValue(v, pos);
if (v.isLambda()) { if (v.isLambda()) {
if (!v.lambda.fun->matchAttrs || !v.lambda.fun->formals->ellipsis) if (!v.lambda.fun->hasFormals() || !v.lambda.fun->formals->ellipsis)
throw Error("module must match an open attribute set ('{ config, ... }')"); throw Error("module must match an open attribute set ('{ config, ... }')");
} else if (v.type() == nAttrs) { } else if (v.type() == nAttrs) {
for (auto & attr : *v.attrs) for (auto & attr : *v.attrs)