aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/eval.hh
diff options
context:
space:
mode:
authorGuillaume Maudoux <guillaume.maudoux@tweag.io>2022-04-29 00:12:25 +0200
committerGuillaume Maudoux <guillaume.maudoux@tweag.io>2022-04-29 00:12:25 +0200
commite93b59fbc5ada40e77d6f2b2a8bbd8e482418d6a (patch)
treef9436753bba299d648a6721845a9465b34a50062 /src/libexpr/eval.hh
parentf6baa4d18845297f3f7fc2434b7ade93a45718e7 (diff)
parent35393dc2c65765acb6cc99d6a976eab62c28a51d (diff)
Merge remote-tracking branch 'origin/master' into coerce-string
Diffstat (limited to 'src/libexpr/eval.hh')
-rw-r--r--src/libexpr/eval.hh107
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);