make parser utility functions members of ParseData

all of them need access to parser state in some way. make them members
to allow this without fussing so much.

(cherry picked from commit 1b09b80afac27c67157d4b315c237fa7bb9b8d08)
Change-Id: I3145c95666a5617b735eff7cb403c54c0fe86347
This commit is contained in:
eldritch horrors 2024-03-08 05:17:52 +01:00
parent ba16d99124
commit 60e3a05175

View file

@ -26,6 +26,15 @@
#include "eval-settings.hh" #include "eval-settings.hh"
#include "globals.hh" #include "globals.hh"
// using C a struct allows us to avoid having to define the special
// members that using string_view here would implicitly delete.
struct StringToken {
const char * p;
size_t l;
bool hasIndentation;
operator std::string_view() const { return {p, l}; }
};
namespace nix { namespace nix {
#define YYLTYPE ::nix::ParserLocation #define YYLTYPE ::nix::ParserLocation
@ -60,19 +69,18 @@ namespace nix {
Expr * result; Expr * result;
SourcePath basePath; SourcePath basePath;
PosTable::Origin origin; PosTable::Origin origin;
void dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos);
void dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos);
void addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * e, const PosIdx pos);
Formals * validateFormals(Formals * formals, PosIdx pos = noPos, Symbol arg = {});
Expr * stripIndentation(const PosIdx pos,
std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>> && es);
PosIdx makeCurPos(const ParserLocation & loc);
}; };
} }
// using C a struct allows us to avoid having to define the special
// members that using string_view here would implicitly delete.
struct StringToken {
const char * p;
size_t l;
bool hasIndentation;
operator std::string_view() const { return {p, l}; }
};
#define YY_DECL int yylex \ #define YY_DECL int yylex \
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param, yyscan_t yyscanner, nix::ParseData * data) (YYSTYPE * yylval_param, YYLTYPE * yylloc_param, yyscan_t yyscanner, nix::ParseData * data)
@ -93,7 +101,7 @@ using namespace nix;
namespace nix { namespace nix {
static void dupAttr(const EvalState & state, const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos) void ParseData::dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos)
{ {
throw ParseError({ throw ParseError({
.msg = hintfmt("attribute '%1%' already defined at %2%", .msg = hintfmt("attribute '%1%' already defined at %2%",
@ -102,7 +110,7 @@ static void dupAttr(const EvalState & state, const AttrPath & attrPath, const Po
}); });
} }
static void dupAttr(const EvalState & state, Symbol attr, const PosIdx pos, const PosIdx prevPos) void ParseData::dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos)
{ {
throw ParseError({ throw ParseError({
.msg = hintfmt("attribute '%1%' already defined at %2%", state.symbols[attr], state.positions[prevPos]), .msg = hintfmt("attribute '%1%' already defined at %2%", state.symbols[attr], state.positions[prevPos]),
@ -111,8 +119,7 @@ static void dupAttr(const EvalState & state, Symbol attr, const PosIdx pos, cons
} }
static void addAttr(ExprAttrs * attrs, AttrPath && attrPath, void ParseData::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * e, const PosIdx pos)
Expr * e, const PosIdx pos, const nix::EvalState & state)
{ {
AttrPath::iterator i; AttrPath::iterator i;
// All attrpaths have at least one attr // All attrpaths have at least one attr
@ -125,10 +132,10 @@ static void addAttr(ExprAttrs * attrs, AttrPath && attrPath,
if (j != attrs->attrs.end()) { if (j != attrs->attrs.end()) {
if (!j->second.inherited) { if (!j->second.inherited) {
ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e); ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e);
if (!attrs2) dupAttr(state, attrPath, pos, j->second.pos); if (!attrs2) dupAttr(attrPath, pos, j->second.pos);
attrs = attrs2; attrs = attrs2;
} else } else
dupAttr(state, attrPath, pos, j->second.pos); dupAttr(attrPath, pos, j->second.pos);
} else { } else {
ExprAttrs * nested = new ExprAttrs; ExprAttrs * nested = new ExprAttrs;
attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos); attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos);
@ -155,12 +162,12 @@ static void addAttr(ExprAttrs * attrs, AttrPath && attrPath,
for (auto & ad : ae->attrs) { for (auto & ad : ae->attrs) {
auto j2 = jAttrs->attrs.find(ad.first); auto j2 = jAttrs->attrs.find(ad.first);
if (j2 != jAttrs->attrs.end()) // Attr already defined in iAttrs, error. if (j2 != jAttrs->attrs.end()) // Attr already defined in iAttrs, error.
dupAttr(state, ad.first, j2->second.pos, ad.second.pos); dupAttr(ad.first, j2->second.pos, ad.second.pos);
jAttrs->attrs.emplace(ad.first, ad.second); jAttrs->attrs.emplace(ad.first, ad.second);
} }
jAttrs->dynamicAttrs.insert(jAttrs->dynamicAttrs.end(), ae->dynamicAttrs.begin(), ae->dynamicAttrs.end()); jAttrs->dynamicAttrs.insert(jAttrs->dynamicAttrs.end(), ae->dynamicAttrs.begin(), ae->dynamicAttrs.end());
} else { } else {
dupAttr(state, attrPath, pos, j->second.pos); dupAttr(attrPath, pos, j->second.pos);
} }
} else { } else {
// This attr path is not defined. Let's create it. // This attr path is not defined. Let's create it.
@ -173,8 +180,7 @@ static void addAttr(ExprAttrs * attrs, AttrPath && attrPath,
} }
static Formals * validateFormals(ParseData & data, Formals * formals, Formals * ParseData::validateFormals(Formals * formals, PosIdx pos, Symbol arg)
PosIdx pos = noPos, Symbol arg = {})
{ {
std::sort(formals->formals.begin(), formals->formals.end(), std::sort(formals->formals.begin(), formals->formals.end(),
[] (const auto & a, const auto & b) { [] (const auto & a, const auto & b) {
@ -190,21 +196,21 @@ static Formals * validateFormals(ParseData & data, Formals * formals,
} }
if (duplicate) if (duplicate)
throw ParseError({ throw ParseError({
.msg = hintfmt("duplicate formal function argument '%1%'", data.symbols[duplicate->first]), .msg = hintfmt("duplicate formal function argument '%1%'", symbols[duplicate->first]),
.errPos = data.state.positions[duplicate->second] .errPos = state.positions[duplicate->second]
}); });
if (arg && formals->has(arg)) if (arg && formals->has(arg))
throw ParseError({ throw ParseError({
.msg = hintfmt("duplicate formal function argument '%1%'", data.symbols[arg]), .msg = hintfmt("duplicate formal function argument '%1%'", symbols[arg]),
.errPos = data.state.positions[pos] .errPos = state.positions[pos]
}); });
return formals; return formals;
} }
static Expr * stripIndentation(const PosIdx pos, SymbolTable & symbols, Expr * ParseData::stripIndentation(const PosIdx pos,
std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>> && es) std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>> && es)
{ {
if (es.empty()) return new ExprString(""); if (es.empty()) return new ExprString("");
@ -301,12 +307,12 @@ static Expr * stripIndentation(const PosIdx pos, SymbolTable & symbols,
} }
static inline PosIdx makeCurPos(const YYLTYPE & loc, ParseData * data) PosIdx ParseData::makeCurPos(const ParserLocation & loc)
{ {
return data->state.positions.add(data->origin, loc.first_line, loc.first_column); return state.positions.add(origin, loc.first_line, loc.first_column);
} }
#define CUR_POS makeCurPos(*yylocp, data) #define CUR_POS data->makeCurPos(*yylocp)
} }
@ -316,7 +322,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err
{ {
throw ParseError({ throw ParseError({
.msg = hintfmt(error), .msg = hintfmt(error),
.errPos = data->state.positions[makeCurPos(*loc, data)] .errPos = data->state.positions[data->makeCurPos(*loc)]
}); });
} }
@ -386,16 +392,16 @@ expr_function
: ID ':' expr_function : ID ':' expr_function
{ $$ = new ExprLambda(CUR_POS, data->symbols.create($1), 0, $3); } { $$ = new ExprLambda(CUR_POS, data->symbols.create($1), 0, $3); }
| '{' formals '}' ':' expr_function | '{' formals '}' ':' expr_function
{ $$ = new ExprLambda(CUR_POS, validateFormals(*data, $2), $5); } { $$ = new ExprLambda(CUR_POS, data->validateFormals($2), $5); }
| '{' formals '}' '@' ID ':' expr_function | '{' formals '}' '@' ID ':' expr_function
{ {
auto arg = data->symbols.create($5); auto arg = data->symbols.create($5);
$$ = new ExprLambda(CUR_POS, arg, validateFormals(*data, $2, CUR_POS, arg), $7); $$ = new ExprLambda(CUR_POS, arg, data->validateFormals($2, CUR_POS, arg), $7);
} }
| ID '@' '{' formals '}' ':' expr_function | ID '@' '{' formals '}' ':' expr_function
{ {
auto arg = data->symbols.create($1); auto arg = data->symbols.create($1);
$$ = new ExprLambda(CUR_POS, arg, validateFormals(*data, $4, CUR_POS, arg), $7); $$ = new ExprLambda(CUR_POS, arg, data->validateFormals($4, CUR_POS, arg), $7);
} }
| ASSERT expr ';' expr_function | ASSERT expr ';' expr_function
{ $$ = new ExprAssert(CUR_POS, $2, $4); } { $$ = new ExprAssert(CUR_POS, $2, $4); }
@ -422,21 +428,21 @@ expr_op
| '-' expr_op %prec NEGATE { $$ = new ExprCall(CUR_POS, new ExprVar(data->symbols.create("__sub")), {new ExprInt(0), $2}); } | '-' expr_op %prec NEGATE { $$ = new ExprCall(CUR_POS, new ExprVar(data->symbols.create("__sub")), {new ExprInt(0), $2}); }
| expr_op EQ expr_op { $$ = new ExprOpEq($1, $3); } | expr_op EQ expr_op { $$ = new ExprOpEq($1, $3); }
| expr_op NEQ expr_op { $$ = new ExprOpNEq($1, $3); } | expr_op NEQ expr_op { $$ = new ExprOpNEq($1, $3); }
| expr_op '<' expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__lessThan")), {$1, $3}); } | expr_op '<' expr_op { $$ = new ExprCall(data->makeCurPos(@2), new ExprVar(data->symbols.create("__lessThan")), {$1, $3}); }
| expr_op LEQ expr_op { $$ = new ExprOpNot(new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__lessThan")), {$3, $1})); } | expr_op LEQ expr_op { $$ = new ExprOpNot(new ExprCall(data->makeCurPos(@2), new ExprVar(data->symbols.create("__lessThan")), {$3, $1})); }
| expr_op '>' expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__lessThan")), {$3, $1}); } | expr_op '>' expr_op { $$ = new ExprCall(data->makeCurPos(@2), new ExprVar(data->symbols.create("__lessThan")), {$3, $1}); }
| expr_op GEQ expr_op { $$ = new ExprOpNot(new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__lessThan")), {$1, $3})); } | expr_op GEQ expr_op { $$ = new ExprOpNot(new ExprCall(data->makeCurPos(@2), new ExprVar(data->symbols.create("__lessThan")), {$1, $3})); }
| expr_op AND expr_op { $$ = new ExprOpAnd(makeCurPos(@2, data), $1, $3); } | expr_op AND expr_op { $$ = new ExprOpAnd(data->makeCurPos(@2), $1, $3); }
| expr_op OR expr_op { $$ = new ExprOpOr(makeCurPos(@2, data), $1, $3); } | expr_op OR expr_op { $$ = new ExprOpOr(data->makeCurPos(@2), $1, $3); }
| expr_op IMPL expr_op { $$ = new ExprOpImpl(makeCurPos(@2, data), $1, $3); } | expr_op IMPL expr_op { $$ = new ExprOpImpl(data->makeCurPos(@2), $1, $3); }
| expr_op UPDATE expr_op { $$ = new ExprOpUpdate(makeCurPos(@2, data), $1, $3); } | expr_op UPDATE expr_op { $$ = new ExprOpUpdate(data->makeCurPos(@2), $1, $3); }
| expr_op '?' attrpath { $$ = new ExprOpHasAttr($1, std::move(*$3)); delete $3; } | expr_op '?' attrpath { $$ = new ExprOpHasAttr($1, std::move(*$3)); delete $3; }
| expr_op '+' expr_op | expr_op '+' expr_op
{ $$ = new ExprConcatStrings(makeCurPos(@2, data), false, new std::vector<std::pair<PosIdx, Expr *> >({{makeCurPos(@1, data), $1}, {makeCurPos(@3, data), $3}})); } { $$ = new ExprConcatStrings(data->makeCurPos(@2), false, new std::vector<std::pair<PosIdx, Expr *> >({{data->makeCurPos(@1), $1}, {data->makeCurPos(@3), $3}})); }
| expr_op '-' expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__sub")), {$1, $3}); } | expr_op '-' expr_op { $$ = new ExprCall(data->makeCurPos(@2), new ExprVar(data->symbols.create("__sub")), {$1, $3}); }
| expr_op '*' expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__mul")), {$1, $3}); } | expr_op '*' expr_op { $$ = new ExprCall(data->makeCurPos(@2), new ExprVar(data->symbols.create("__mul")), {$1, $3}); }
| expr_op '/' expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__div")), {$1, $3}); } | expr_op '/' expr_op { $$ = new ExprCall(data->makeCurPos(@2), new ExprVar(data->symbols.create("__div")), {$1, $3}); }
| expr_op CONCAT expr_op { $$ = new ExprOpConcatLists(makeCurPos(@2, data), $1, $3); } | expr_op CONCAT expr_op { $$ = new ExprOpConcatLists(data->makeCurPos(@2), $1, $3); }
| expr_app | expr_app
; ;
@ -475,12 +481,12 @@ expr_simple
| FLOAT { $$ = new ExprFloat($1); } | FLOAT { $$ = new ExprFloat($1); }
| '"' string_parts '"' { $$ = $2; } | '"' string_parts '"' { $$ = $2; }
| IND_STRING_OPEN ind_string_parts IND_STRING_CLOSE { | IND_STRING_OPEN ind_string_parts IND_STRING_CLOSE {
$$ = stripIndentation(CUR_POS, data->symbols, std::move(*$2)); $$ = data->stripIndentation(CUR_POS, std::move(*$2));
delete $2; delete $2;
} }
| path_start PATH_END | path_start PATH_END
| path_start string_parts_interpolated PATH_END { | path_start string_parts_interpolated PATH_END {
$2->insert($2->begin(), {makeCurPos(@1, data), $1}); $2->insert($2->begin(), {data->makeCurPos(@1), $1});
$$ = new ExprConcatStrings(CUR_POS, false, $2); $$ = new ExprConcatStrings(CUR_POS, false, $2);
} }
| SPATH { | SPATH {
@ -519,13 +525,13 @@ string_parts
string_parts_interpolated string_parts_interpolated
: string_parts_interpolated STR : string_parts_interpolated STR
{ $$ = $1; $1->emplace_back(makeCurPos(@2, data), new ExprString(std::string($2))); } { $$ = $1; $1->emplace_back(data->makeCurPos(@2), new ExprString(std::string($2))); }
| string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->emplace_back(makeCurPos(@2, data), $3); } | string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->emplace_back(data->makeCurPos(@2), $3); }
| DOLLAR_CURLY expr '}' { $$ = new std::vector<std::pair<PosIdx, Expr *>>; $$->emplace_back(makeCurPos(@1, data), $2); } | DOLLAR_CURLY expr '}' { $$ = new std::vector<std::pair<PosIdx, Expr *>>; $$->emplace_back(data->makeCurPos(@1), $2); }
| STR DOLLAR_CURLY expr '}' { | STR DOLLAR_CURLY expr '}' {
$$ = new std::vector<std::pair<PosIdx, Expr *>>; $$ = new std::vector<std::pair<PosIdx, Expr *>>;
$$->emplace_back(makeCurPos(@1, data), new ExprString(std::string($1))); $$->emplace_back(data->makeCurPos(@1), new ExprString(std::string($1)));
$$->emplace_back(makeCurPos(@2, data), $3); $$->emplace_back(data->makeCurPos(@2), $3);
} }
; ;
@ -550,19 +556,19 @@ path_start
; ;
ind_string_parts ind_string_parts
: ind_string_parts IND_STR { $$ = $1; $1->emplace_back(makeCurPos(@2, data), $2); } : ind_string_parts IND_STR { $$ = $1; $1->emplace_back(data->makeCurPos(@2), $2); }
| ind_string_parts DOLLAR_CURLY expr '}' { $$ = $1; $1->emplace_back(makeCurPos(@2, data), $3); } | ind_string_parts DOLLAR_CURLY expr '}' { $$ = $1; $1->emplace_back(data->makeCurPos(@2), $3); }
| { $$ = new std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>>; } | { $$ = new std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>>; }
; ;
binds binds
: binds attrpath '=' expr ';' { $$ = $1; addAttr($$, std::move(*$2), $4, makeCurPos(@2, data), data->state); delete $2; } : binds attrpath '=' expr ';' { $$ = $1; data->addAttr($$, std::move(*$2), $4, data->makeCurPos(@2)); delete $2; }
| binds INHERIT attrs ';' | binds INHERIT attrs ';'
{ $$ = $1; { $$ = $1;
for (auto & i : *$3) { for (auto & i : *$3) {
if ($$->attrs.find(i.symbol) != $$->attrs.end()) if ($$->attrs.find(i.symbol) != $$->attrs.end())
dupAttr(data->state, i.symbol, makeCurPos(@3, data), $$->attrs[i.symbol].pos); data->dupAttr(i.symbol, data->makeCurPos(@3), $$->attrs[i.symbol].pos);
auto pos = makeCurPos(@3, data); auto pos = data->makeCurPos(@3);
$$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, true)); $$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, true));
} }
delete $3; delete $3;
@ -572,12 +578,12 @@ binds
/* !!! Should ensure sharing of the expression in $4. */ /* !!! Should ensure sharing of the expression in $4. */
for (auto & i : *$6) { for (auto & i : *$6) {
if ($$->attrs.find(i.symbol) != $$->attrs.end()) if ($$->attrs.find(i.symbol) != $$->attrs.end())
dupAttr(data->state, i.symbol, makeCurPos(@6, data), $$->attrs[i.symbol].pos); data->dupAttr(i.symbol, data->makeCurPos(@6), $$->attrs[i.symbol].pos);
$$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprSelect(CUR_POS, $4, i.symbol), makeCurPos(@6, data))); $$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprSelect(CUR_POS, $4, i.symbol), data->makeCurPos(@6)));
} }
delete $6; delete $6;
} }
| { $$ = new ExprAttrs(makeCurPos(@0, data)); } | { $$ = new ExprAttrs(data->makeCurPos(@0)); }
; ;
attrs attrs
@ -591,7 +597,7 @@ attrs
} else } else
throw ParseError({ throw ParseError({
.msg = hintfmt("dynamic attributes not allowed in inherit"), .msg = hintfmt("dynamic attributes not allowed in inherit"),
.errPos = data->state.positions[makeCurPos(@2, data)] .errPos = data->state.positions[data->makeCurPos(@2)]
}); });
} }
| { $$ = new AttrPath; } | { $$ = new AttrPath; }