don't repeatedly look up ast internal symbols

these symbols are used a *lot*, so it makes sense to cache them. this
mostly increases clarity of the code (however clear one may wish to call
the parser desugaring here), but it also provides a small performance
benefit.
This commit is contained in:
pennae 2024-01-15 16:52:18 +01:00
parent b596cc9e79
commit 09a1128d9e
5 changed files with 36 additions and 15 deletions

View file

@ -419,6 +419,16 @@ EvalState::EvalState(
, sPath(symbols.create("path")) , sPath(symbols.create("path"))
, sPrefix(symbols.create("prefix")) , sPrefix(symbols.create("prefix"))
, sOutputSpecified(symbols.create("outputSpecified")) , sOutputSpecified(symbols.create("outputSpecified"))
, exprSymbols{
.sub = symbols.create("__sub"),
.lessThan = symbols.create("__lessThan"),
.mul = symbols.create("__mul"),
.div = symbols.create("__div"),
.or_ = symbols.create("or"),
.findFile = symbols.create("__findFile"),
.nixPath = symbols.create("__nixPath"),
.body = symbols.create("body")
}
, repair(NoRepair) , repair(NoRepair)
, emptyBindings(0) , emptyBindings(0)
, rootFS( , rootFS(
@ -2808,7 +2818,7 @@ Expr * EvalState::parse(
const SourcePath & basePath, const SourcePath & basePath,
std::shared_ptr<StaticEnv> & staticEnv) std::shared_ptr<StaticEnv> & staticEnv)
{ {
auto result = parseExprFromBuf(text, length, origin, basePath, symbols, positions, rootFS); auto result = parseExprFromBuf(text, length, origin, basePath, symbols, positions, rootFS, exprSymbols);
result->bindVars(*this, staticEnv); result->bindVars(*this, staticEnv);

View file

@ -207,6 +207,8 @@ public:
sPrefix, sPrefix,
sOutputSpecified; sOutputSpecified;
const Expr::AstSymbols exprSymbols;
/** /**
* If set, force copying files to the Nix store even if they * If set, force copying files to the Nix store even if they
* already exist there. * already exist there.

View file

@ -140,6 +140,11 @@ std::string showAttrPath(const SymbolTable & symbols, const AttrPath & attrPath)
struct Expr struct Expr
{ {
struct AstSymbols {
Symbol sub, lessThan, mul, div, or_, findFile, nixPath, body;
};
static unsigned long nrExprs; static unsigned long nrExprs;
Expr() { Expr() {
nrExprs++; nrExprs++;

View file

@ -43,6 +43,7 @@ struct ParserState {
SourcePath basePath; SourcePath basePath;
PosTable::Origin origin; PosTable::Origin origin;
const ref<InputAccessor> rootFS; const ref<InputAccessor> rootFS;
const Expr::AstSymbols & s;
void dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos); void dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos);
void dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos); void dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos);

View file

@ -41,7 +41,8 @@ Expr * parseExprFromBuf(
const SourcePath & basePath, const SourcePath & basePath,
SymbolTable & symbols, SymbolTable & symbols,
PosTable & positions, PosTable & positions,
const ref<InputAccessor> rootFS); const ref<InputAccessor> rootFS,
const Expr::AstSymbols & astSymbols);
} }
@ -168,13 +169,13 @@ expr_if
expr_op expr_op
: '!' expr_op %prec NOT { $$ = new ExprOpNot($2); } : '!' expr_op %prec NOT { $$ = new ExprOpNot($2); }
| '-' expr_op %prec NEGATE { $$ = new ExprCall(CUR_POS, new ExprVar(state->symbols.create("__sub")), {new ExprInt(0), $2}); } | '-' expr_op %prec NEGATE { $$ = new ExprCall(CUR_POS, new ExprVar(state->s.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(state->at(@2), new ExprVar(state->symbols.create("__lessThan")), {$1, $3}); } | expr_op '<' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.lessThan), {$1, $3}); }
| expr_op LEQ expr_op { $$ = new ExprOpNot(new ExprCall(state->at(@2), new ExprVar(state->symbols.create("__lessThan")), {$3, $1})); } | expr_op LEQ expr_op { $$ = new ExprOpNot(new ExprCall(state->at(@2), new ExprVar(state->s.lessThan), {$3, $1})); }
| expr_op '>' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->symbols.create("__lessThan")), {$3, $1}); } | expr_op '>' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.lessThan), {$3, $1}); }
| expr_op GEQ expr_op { $$ = new ExprOpNot(new ExprCall(state->at(@2), new ExprVar(state->symbols.create("__lessThan")), {$1, $3})); } | expr_op GEQ expr_op { $$ = new ExprOpNot(new ExprCall(state->at(@2), new ExprVar(state->s.lessThan), {$1, $3})); }
| expr_op AND expr_op { $$ = new ExprOpAnd(state->at(@2), $1, $3); } | expr_op AND expr_op { $$ = new ExprOpAnd(state->at(@2), $1, $3); }
| expr_op OR expr_op { $$ = new ExprOpOr(state->at(@2), $1, $3); } | expr_op OR expr_op { $$ = new ExprOpOr(state->at(@2), $1, $3); }
| expr_op IMPL expr_op { $$ = new ExprOpImpl(state->at(@2), $1, $3); } | expr_op IMPL expr_op { $$ = new ExprOpImpl(state->at(@2), $1, $3); }
@ -182,9 +183,9 @@ expr_op
| 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(state->at(@2), false, new std::vector<std::pair<PosIdx, Expr *> >({{state->at(@1), $1}, {state->at(@3), $3}})); } { $$ = new ExprConcatStrings(state->at(@2), false, new std::vector<std::pair<PosIdx, Expr *> >({{state->at(@1), $1}, {state->at(@3), $3}})); }
| expr_op '-' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->symbols.create("__sub")), {$1, $3}); } | expr_op '-' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.sub), {$1, $3}); }
| expr_op '*' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->symbols.create("__mul")), {$1, $3}); } | expr_op '*' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.mul), {$1, $3}); }
| expr_op '/' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->symbols.create("__div")), {$1, $3}); } | expr_op '/' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.div), {$1, $3}); }
| expr_op CONCAT expr_op { $$ = new ExprOpConcatLists(state->at(@2), $1, $3); } | expr_op CONCAT expr_op { $$ = new ExprOpConcatLists(state->at(@2), $1, $3); }
| expr_app | expr_app
; ;
@ -208,7 +209,7 @@ expr_select
| /* Backwards compatibility: because Nixpkgs has a rarely used | /* Backwards compatibility: because Nixpkgs has a rarely used
function named or, allow stuff like map or [...]. */ function named or, allow stuff like map or [...]. */
expr_simple OR_KW expr_simple OR_KW
{ $$ = new ExprCall(CUR_POS, $1, {new ExprVar(CUR_POS, state->symbols.create("or"))}); } { $$ = new ExprCall(CUR_POS, $1, {new ExprVar(CUR_POS, state->s.or_)}); }
| expr_simple | expr_simple
; ;
@ -235,8 +236,8 @@ expr_simple
| SPATH { | SPATH {
std::string path($1.p + 1, $1.l - 2); std::string path($1.p + 1, $1.l - 2);
$$ = new ExprCall(CUR_POS, $$ = new ExprCall(CUR_POS,
new ExprVar(state->symbols.create("__findFile")), new ExprVar(state->s.findFile),
{new ExprVar(state->symbols.create("__nixPath")), {new ExprVar(state->s.nixPath),
new ExprString(std::move(path))}); new ExprString(std::move(path))});
} }
| URI { | URI {
@ -252,7 +253,7 @@ expr_simple
/* Let expressions `let {..., body = ...}' are just desugared /* Let expressions `let {..., body = ...}' are just desugared
into `(rec {..., body = ...}).body'. */ into `(rec {..., body = ...}).body'. */
| LET '{' binds '}' | LET '{' binds '}'
{ $3->recursive = true; $$ = new ExprSelect(noPos, $3, state->symbols.create("body")); } { $3->recursive = true; $$ = new ExprSelect(noPos, $3, state->s.body); }
| REC '{' binds '}' | REC '{' binds '}'
{ $3->recursive = true; $$ = $3; } { $3->recursive = true; $$ = $3; }
| '{' binds '}' | '{' binds '}'
@ -414,7 +415,8 @@ Expr * parseExprFromBuf(
const SourcePath & basePath, const SourcePath & basePath,
SymbolTable & symbols, SymbolTable & symbols,
PosTable & positions, PosTable & positions,
const ref<InputAccessor> rootFS) const ref<InputAccessor> rootFS,
const Expr::AstSymbols & astSymbols)
{ {
yyscan_t scanner; yyscan_t scanner;
ParserState state { ParserState state {
@ -423,6 +425,7 @@ Expr * parseExprFromBuf(
.basePath = basePath, .basePath = basePath,
.origin = {origin}, .origin = {origin},
.rootFS = rootFS, .rootFS = rootFS,
.s = astSymbols,
}; };
yylex_init(&scanner); yylex_init(&scanner);