aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/eval.hh
diff options
context:
space:
mode:
authorBen Burdette <bburdette@protonmail.com>2022-04-28 12:32:57 -0600
committerBen Burdette <bburdette@protonmail.com>2022-04-28 12:32:57 -0600
commit6e19947993119dec3c9fb9581150d1184948bae9 (patch)
tree978fd122eb69168974a3a90063114b97b976f8f3 /src/libexpr/eval.hh
parent93b8d315087921b0a024bf87555ac6c3bca6882d (diff)
parent4bb111c8d4c5692db2f735c2803f632f8c30b6ab (diff)
Merge branch 'master' into debug-merge-master
Diffstat (limited to 'src/libexpr/eval.hh')
-rw-r--r--src/libexpr/eval.hh103
1 files changed, 73 insertions, 30 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 11f5707a4..76bd63ca6 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -23,7 +23,7 @@ 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);
void printEnvBindings(const Expr &expr, const Env &env);
void printEnvBindings(const StaticEnv &se, const Env &env, int lvl = 0);
@@ -32,7 +32,7 @@ struct PrimOp
{
PrimOpFun fun;
size_t arity;
- Symbol name;
+ std::string name;
std::vector<std::string> args;
const char * doc = nullptr;
};
@@ -57,7 +57,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;
@@ -84,6 +85,9 @@ 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,
@@ -222,7 +226,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);
@@ -234,14 +238,14 @@ public:
/* Evaluation the expression, then verify that it has the expected
type. */
inline bool evalBool(Env & env, Expr * e);
- inline bool evalBool(Env & env, Expr * e, const Pos & pos);
+ inline bool evalBool(Env & env, Expr * e, const PosIdx pos);
inline void evalAttrs(Env & env, Expr * e, Value & v);
/* 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);
@@ -251,33 +255,72 @@ public:
void forceValueDeep(Value & v);
/* Force `v', and then verify that it has the expected type. */
- NixInt forceInt(Value & v, const Pos & pos);
- NixFloat forceFloat(Value & v, const Pos & pos);
- bool forceBool(Value & v, const Pos & pos);
+ NixInt forceInt(Value & v, const PosIdx pos);
+ NixFloat forceFloat(Value & v, const PosIdx pos);
+ bool forceBool(Value & v, const PosIdx pos);
- void forceAttrs(Value & v, const Pos & pos);
+ void forceAttrs(Value & v, const PosIdx pos);
template <typename Callable>
inline void forceAttrs(Value & v, Callable getPos);
- inline void forceList(Value & v, const Pos & pos);
- void forceFunction(Value & v, const Pos & pos); // either lambda or primop
- std::string_view forceString(Value & v, const Pos & pos = noPos);
- std::string_view forceString(Value & v, PathSet & context, const Pos & pos = noPos);
- std::string_view forceStringNoCtx(Value & v, const Pos & pos = noPos);
+ inline void forceList(Value & v, const PosIdx pos);
+ void forceFunction(Value & v, const PosIdx pos); // either lambda or primop
+ std::string_view forceString(Value & v, const PosIdx pos = noPos);
+ std::string_view forceString(Value & v, PathSet & context, const PosIdx pos = noPos);
+ std::string_view forceStringNoCtx(Value & v, const PosIdx pos = noPos);
+
+ [[gnu::noinline, gnu::noreturn]]
+ void throwEvalError(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 throwEvalError(const char * s, const std::string & s2) const;
+ [[gnu::noinline, gnu::noreturn]]
+ void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s,
+ const std::string & s2) const;
+ [[gnu::noinline, gnu::noreturn]]
+ void throwEvalError(const PosIdx pos, const char * s, const std::string & s2) const;
+ [[gnu::noinline, gnu::noreturn]]
+ void throwEvalError(const char * s, const std::string & s2, const std::string & 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 throwTypeError(const PosIdx pos, const char * s) 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 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);
@@ -286,10 +329,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);
+ Path coerceToPath(const PosIdx pos, Value & v, PathSet & context);
/* Like coerceToPath, but the result must be a store path. */
- StorePath coerceToStorePath(const Pos & pos, Value & v, PathSet & context);
+ StorePath coerceToStorePath(const PosIdx pos, Value & v, PathSet & context);
public:
@@ -322,7 +365,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;
@@ -350,9 +393,9 @@ public:
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);
@@ -366,7 +409,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);
@@ -378,9 +421,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);
+ void concatLists(Value & v, size_t nrLists, Value * * lists, const PosIdx pos);
/* Print statistics. */
void printStats();
@@ -408,7 +451,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;
@@ -416,7 +459,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;
@@ -427,9 +470,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;
};