diff options
Diffstat (limited to 'src/libexpr/parser/parser.cc')
-rw-r--r-- | src/libexpr/parser/parser.cc | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/src/libexpr/parser/parser.cc b/src/libexpr/parser/parser.cc index b7a105fe7..6d496d141 100644 --- a/src/libexpr/parser/parser.cc +++ b/src/libexpr/parser/parser.cc @@ -113,6 +113,29 @@ struct ExprState return std::make_unique<ExprCall>(pos, std::make_unique<ExprVar>(fn), std::move(args)); } + std::unique_ptr<Expr> pipe(PosIdx pos, State & state, bool flip = false) + { + if (!state.xpSettings.isEnabled(Xp::PipeOperator)) + throw ParseError({ + .msg = HintFmt("Pipe operator is disabled"), + .pos = state.positions[pos] + }); + + // Reverse the order compared to normal function application: arg |> fn + std::unique_ptr<Expr> fn, arg; + if (flip) { + fn = popExprOnly(); + arg = popExprOnly(); + } else { + arg = popExprOnly(); + fn = popExprOnly(); + } + std::vector<std::unique_ptr<Expr>> args{1}; + args[0] = std::move(arg); + + return std::make_unique<ExprCall>(pos, std::move(fn), std::move(args)); + } + std::unique_ptr<Expr> order(PosIdx pos, bool less, State & state) { return call(pos, state.s.lessThan, !less); @@ -162,6 +185,8 @@ struct ExprState [&] (Op::concat) { return applyBinary<ExprOpConcatLists>(pos); }, [&] (has_attr & a) { return applyUnary<ExprOpHasAttr>(std::move(a.path)); }, [&] (Op::unary_minus) { return negate(pos, state); }, + [&] (Op::pipe_right) { return pipe(pos, state, true); }, + [&] (Op::pipe_left) { return pipe(pos, state); }, })(op) }; } @@ -631,7 +656,7 @@ template<> struct BuildAST<grammar::expr::path> : p::maybe_nothing {}; template<> struct BuildAST<grammar::expr::uri> { static void apply(const auto & in, ExprState & s, State & ps) { - static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals); + bool noURLLiterals = ps.xpSettings.isEnabled(Xp::NoUrlLiterals); if (noURLLiterals) throw ParseError({ .msg = HintFmt("URL literals are disabled"), @@ -832,7 +857,8 @@ Expr * EvalState::parse( size_t length, Pos::Origin origin, const SourcePath & basePath, - std::shared_ptr<StaticEnv> & staticEnv) + std::shared_ptr<StaticEnv> & staticEnv, + const ExperimentalFeatureSettings & xpSettings) { parser::State s = { symbols, @@ -840,6 +866,7 @@ Expr * EvalState::parse( basePath, positions.addOrigin(origin, length), exprSymbols, + xpSettings }; parser::ExprState x; |