diff options
author | Guillaume Maudoux <guillaume.maudoux@tweag.io> | 2022-04-29 00:12:25 +0200 |
---|---|---|
committer | Guillaume Maudoux <guillaume.maudoux@tweag.io> | 2022-04-29 00:12:25 +0200 |
commit | e93b59fbc5ada40e77d6f2b2a8bbd8e482418d6a (patch) | |
tree | f9436753bba299d648a6721845a9465b34a50062 /src/libexpr/eval.hh | |
parent | f6baa4d18845297f3f7fc2434b7ade93a45718e7 (diff) | |
parent | 35393dc2c65765acb6cc99d6a976eab62c28a51d (diff) |
Merge remote-tracking branch 'origin/master' into coerce-string
Diffstat (limited to 'src/libexpr/eval.hh')
-rw-r--r-- | src/libexpr/eval.hh | 107 |
1 files changed, 67 insertions, 40 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index fd0961bdc..4c7d92dbc 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -23,14 +23,14 @@ class StorePath; enum RepairFlag : bool; -typedef void (* PrimOpFun) (EvalState & state, const Pos & pos, Value * * args, Value & v); +typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v); struct PrimOp { PrimOpFun fun; size_t arity; - Symbol name; + std::string name; std::vector<std::string> args; const char * doc = nullptr; }; @@ -53,7 +53,8 @@ void copyContext(const Value & v, PathSet & context); typedef std::map<Path, StorePath> SrcToStore; -std::ostream & operator << (std::ostream & str, const Value & v); +std::ostream & printValue(const EvalState & state, std::ostream & str, const Value & v); +std::string printValue(const EvalState & state, const Value & v); typedef std::pair<std::string, std::string> SearchPathElem; @@ -73,12 +74,15 @@ class EvalState { public: SymbolTable symbols; + PosTable positions; + + static inline std::string derivationNixPath = "//builtin/derivation.nix"; const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue, sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls, sFile, sLine, sColumn, sFunctor, sToString, sRight, sWrong, sStructuredAttrs, sBuilder, sArgs, - sContentAddressed, + sContentAddressed, sImpure, sOutputHash, sOutputHashAlgo, sOutputHashMode, sRecurseForDerivations, sDescription, sSelf, sEpsilon, sStartSet, sOperator, sKey, sPath, @@ -149,12 +153,6 @@ public: std::shared_ptr<Store> buildStore = nullptr); ~EvalState(); - void requireExperimentalFeatureOnEvaluation( - const ExperimentalFeature &, - const std::string_view fName, - const Pos & pos - ); - void addToSearchPath(const std::string & s); SearchPath getSearchPath() { return searchPath; } @@ -211,7 +209,7 @@ public: /* Look up a file in the search path. */ Path findFile(const std::string_view path); - Path findFile(SearchPath & searchPath, const std::string_view path, const Pos & pos = noPos); + Path findFile(SearchPath & searchPath, const std::string_view path, const PosIdx pos = noPos); /* If the specified search path element is a URI, download it. */ std::pair<bool, std::string> resolveSearchPathElem(const SearchPathElem & elem); @@ -222,14 +220,15 @@ public: /* Evaluation the expression, then verify that it has the expected type. */ - inline bool evalBool(Env & env, Expr * e, const Pos & pos, std::string_view errorCtx); - inline void evalAttrs(Env & env, Expr * e, Value & v, const Pos & pos, std::string_view errorCtx); + inline bool evalBool(Env & env, Expr * e); + inline bool evalBool(Env & env, Expr * e, const PosIdx pos, std::string_view errorCtx); + inline void evalAttrs(Env & env, Expr * e, Value & v, const PosIdx pos, std::string_view errorCtx); /* If `v' is a thunk, enter it and overwrite `v' with the result of the evaluation of the thunk. If `v' is a delayed function application, call the function and overwrite `v' with the result. Otherwise, this is a no-op. */ - inline void forceValue(Value & v, const Pos & pos); + inline void forceValue(Value & v, const PosIdx pos); template <typename Callable> inline void forceValue(Value & v, Callable getPos); @@ -239,33 +238,61 @@ public: void forceValueDeep(Value & v); /* Force `v', and then verify that it has the expected type. */ - NixInt forceInt(Value & v, const Pos & pos, std::string_view errorCtx); - NixFloat forceFloat(Value & v, const Pos & pos, std::string_view errorCtx); - bool forceBool(Value & v, const Pos & pos, std::string_view errorCtx); + NixInt forceInt(Value & v, const PosIdx pos, std::string_view errorCtx); + NixFloat forceFloat(Value & v, const PosIdx pos, std::string_view errorCtx); + bool forceBool(Value & v, const PosIdx pos, std::string_view errorCtx); - void forceAttrs(Value & v, const Pos & pos, std::string_view errorCtx); + void forceAttrs(Value & v, const PosIdx pos, std::string_view errorCtx); template <typename Callable> inline void forceAttrs(Value & v, Callable getPos, std::string_view errorCtx); - inline void forceList(Value & v, const Pos & pos, std::string_view errorCtx); - void forceFunction(Value & v, const Pos & pos, std::string_view errorCtx); // either lambda or primop - std::string_view forceString(Value & v, const Pos & pos, std::string_view errorCtx); - std::string_view forceString(Value & v, PathSet & context, const Pos & pos, std::string_view errorCtx); - std::string_view forceStringNoCtx(Value & v, const Pos & pos, std::string_view errorCtx); + inline void forceList(Value & v, const PosIdx pos, std::string_view errorCtx); + void forceFunction(Value & v, const PosIdx pos, std::string_view errorCtx); // either lambda or primop + std::string_view forceString(Value & v, const PosIdx pos, std::string_view errorCtx); + std::string_view forceString(Value & v, PathSet & context, const PosIdx pos, std::string_view errorCtx); + std::string_view forceStringNoCtx(Value & v, const PosIdx pos, std::string_view errorCtx); + + [[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s, const Value & v) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalError(const char * s, const std::string_view s2) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string_view s2) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s, const std::string_view s2) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalError(const char * s, const std::string_view s2, const std::string_view s3) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalError(const char * s, const Value & v) const; + [[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const char * s) const; + [[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const char * s, const Value & v) const; + [[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, const Symbol s2) const; + [[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol s2) const; + [[gnu::noinline, gnu::noreturn]] void throwTypeError(const char * s, const Value & v) const; + [[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const PosIdx, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const; + [[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const PosIdx, const nix::Suggestions&, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const; + [[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const char*, std::string_view, const Pos &, std::string_view) const; + [[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const; + [[gnu::noinline, gnu::noreturn]] void throwEvalErrorWithTrace(const char*, std::string_view, std::string_view, nix::PosIdx, std::string_view) const; + [[gnu::noinline, gnu::noreturn]] void throwAssertionError(const PosIdx pos, const char * s, const std::string & s1) const; + [[gnu::noinline, gnu::noreturn]] void throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1) const; + [[gnu::noinline, gnu::noreturn]] void throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1) const; + + [[gnu::noinline]] void addErrorTrace(Error & e, const char * s, const std::string & s2) const; + [[gnu::noinline]] void addErrorTrace(Error & e, const PosIdx pos, const char * s, const std::string & s2) const; +public: /* Return true iff the value `v' denotes a derivation (i.e. a set with attribute `type = "derivation"'). */ bool isDerivation(Value & v); - std::optional<std::string> tryAttrsToString(const Pos & pos, Value & v, + std::optional<std::string> tryAttrsToString(const PosIdx pos, Value & v, PathSet & context, bool coerceMore = false, bool copyToStore = true); /* String coercion. Converts strings, paths and derivations to a string. If `coerceMore' is set, also converts nulls, integers, booleans and lists to a string. If `copyToStore' is set, referenced paths are copied to the Nix store as a side effect. */ - BackedStringView coerceToString(const Pos & pos, Value & v, PathSet & context, + BackedStringView coerceToString(const PosIdx pos, Value & v, PathSet & context, bool coerceMore = false, bool copyToStore = true, bool canonicalizePath = true, std::string_view errorCtx = ""); @@ -275,10 +302,10 @@ public: /* Path coercion. Converts strings, paths and derivations to a path. The result is guaranteed to be a canonicalised, absolute path. Nothing is copied to the store. */ - Path coerceToPath(const Pos & pos, Value & v, PathSet & context, std::string_view errorCtx); + Path coerceToPath(const PosIdx pos, Value & v, PathSet & context, std::string_view errorCtx); /* Like coerceToPath, but the result must be a store path. */ - StorePath coerceToStorePath(const Pos & pos, Value & v, PathSet & context, std::string_view errorCtx); + StorePath coerceToStorePath(const PosIdx pos, Value & v, PathSet & context, std::string_view errorCtx); public: @@ -311,7 +338,7 @@ public: struct Doc { Pos pos; - std::optional<Symbol> name; + std::optional<std::string> name; size_t arity; std::vector<std::string> args; const char * doc; @@ -334,14 +361,14 @@ public: /* Do a deep equality test between two values. That is, list elements and attributes are compared recursively. */ - bool eqValues(Value & v1, Value & v2, const Pos & pos, std::string_view errorCtx); + bool eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_view errorCtx); bool isFunctor(Value & fun); // FIXME: use std::span - void callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const Pos & pos); + void callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos); - void callFunction(Value & fun, Value & arg, Value & vRes, const Pos & pos) + void callFunction(Value & fun, Value & arg, Value & vRes, const PosIdx pos) { Value * args[] = {&arg}; callFunction(fun, 1, args, vRes, pos); @@ -355,7 +382,7 @@ public: inline Value * allocValue(); inline Env & allocEnv(size_t size); - Value * allocAttr(Value & vAttrs, const Symbol & name); + Value * allocAttr(Value & vAttrs, Symbol name); Value * allocAttr(Value & vAttrs, std::string_view name); Bindings * allocBindings(size_t capacity); @@ -367,9 +394,9 @@ public: void mkList(Value & v, size_t length); void mkThunk_(Value & v, Expr * expr); - void mkPos(Value & v, ptr<Pos> pos); + void mkPos(Value & v, PosIdx pos); - void concatLists(Value & v, size_t nrLists, Value * * lists, const Pos & pos, std::string_view errorCtx); + void concatLists(Value & v, size_t nrLists, Value * * lists, const PosIdx pos, std::string_view errorCtx); /* Print statistics. */ void printStats(); @@ -397,7 +424,7 @@ private: bool countCalls; - typedef std::map<Symbol, size_t> PrimOpCalls; + typedef std::map<std::string, size_t> PrimOpCalls; PrimOpCalls primOpCalls; typedef std::map<ExprLambda *, size_t> FunctionCalls; @@ -405,7 +432,7 @@ private: void incrFunctionCall(ExprLambda * fun); - typedef std::map<Pos, size_t> AttrSelects; + typedef std::map<PosIdx, size_t> AttrSelects; AttrSelects attrSelects; friend struct ExprOpUpdate; @@ -416,9 +443,9 @@ private: friend struct ExprFloat; friend struct ExprPath; friend struct ExprSelect; - friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v); - friend void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v); - friend void prim_split(EvalState & state, const Pos & pos, Value * * args, Value & v); + friend void prim_getAttr(EvalState & state, const PosIdx pos, Value * * args, Value & v); + friend void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v); + friend void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v); friend struct Value; }; @@ -430,7 +457,7 @@ std::string showType(const Value & v); /* Decode a context string ‘!<name>!<path>’ into a pair <path, name>. */ -std::pair<std::string, std::string> decodeContext(std::string_view s); +NixStringContextElem decodeContext(const Store & store, std::string_view s); /* If `path' refers to a directory, then append "/default.nix". */ Path resolveExprPath(Path path); |