diff options
Diffstat (limited to 'third_party/nix/src/libexpr/nixexpr.hh')
-rw-r--r-- | third_party/nix/src/libexpr/nixexpr.hh | 361 |
1 files changed, 0 insertions, 361 deletions
diff --git a/third_party/nix/src/libexpr/nixexpr.hh b/third_party/nix/src/libexpr/nixexpr.hh deleted file mode 100644 index 16b58dec2e84..000000000000 --- a/third_party/nix/src/libexpr/nixexpr.hh +++ /dev/null @@ -1,361 +0,0 @@ -#pragma once - -#include <map> -#include <optional> -#include <variant> - -#include <absl/container/flat_hash_map.h> - -#include "libexpr/symbol-table.hh" -#include "libexpr/value.hh" -#include "libutil/types.hh" // TODO(tazjin): audit this include - -namespace nix { - -MakeError(EvalError, Error); -MakeError(ParseError, Error); -MakeError(AssertionError, EvalError); -MakeError(ThrownError, AssertionError); -MakeError(Abort, EvalError); -MakeError(TypeError, EvalError); -MakeError(UndefinedVarError, Error); -MakeError(RestrictedPathError, Error); - -/* Position objects. */ - -struct Pos { - std::optional<Symbol> file; - unsigned int line, column; - Pos(const std::optional<Symbol>& file, unsigned int line, unsigned int column) - : file(file), line(line), column(column){}; - - // TODO(tazjin): remove this - empty pos is never useful - Pos() : file(std::nullopt), line(0), column(0){}; - - operator bool() const { return line != 0; } - - bool operator<(const Pos& p2) const { - if (!file.has_value()) { - return true; - } - - if (!line) { - return p2.line; - } - if (!p2.line) { - return false; - } - int d = ((std::string)file.value()).compare((std::string)p2.file.value()); - if (d < 0) { - return true; - } - if (d > 0) { - return false; - } - if (line < p2.line) { - return true; - } - if (line > p2.line) { - return false; - } - return column < p2.column; - } -}; - -extern Pos noPos; - -std::ostream& operator<<(std::ostream& str, const Pos& pos); - -struct Env; -struct Value; -class EvalState; -struct StaticEnv; - -/* An attribute path is a sequence of attribute names. */ -using AttrName = std::variant<Symbol, Expr*>; -using AttrPath = std::vector<AttrName>; -using AttrNameVector = std::vector<AttrName>; - -using VectorExprs = std::vector<nix::Expr*>; - -std::string showAttrPath(const AttrPath& attrPath); - -/* Abstract syntax of Nix expressions. */ - -struct Expr { - virtual ~Expr(){}; - virtual void show(std::ostream& str) const; - virtual void bindVars(const StaticEnv& env); - virtual void eval(EvalState& state, Env& env, Value& v); - virtual Value* maybeThunk(EvalState& state, Env& env); -}; - -std::ostream& operator<<(std::ostream& str, const Expr& e); - -#define COMMON_METHODS \ - void show(std::ostream& str) const; \ - void eval(EvalState& state, Env& env, Value& v); \ - void bindVars(const StaticEnv& env); - -struct ExprInt : Expr { - NixInt n; - Value v; - ExprInt(NixInt n) : n(n) { mkInt(v, n); }; - COMMON_METHODS - Value* maybeThunk(EvalState& state, Env& env); -}; - -struct ExprFloat : Expr { - NixFloat nf; - Value v; - ExprFloat(NixFloat nf) : nf(nf) { mkFloat(v, nf); }; - COMMON_METHODS - Value* maybeThunk(EvalState& state, Env& env); -}; - -struct ExprString : Expr { - Symbol s; - Value v; - ExprString(const Symbol& s) : s(s) { mkString(v, s); }; - COMMON_METHODS - Value* maybeThunk(EvalState& state, Env& env); -}; - -/* Temporary class used during parsing of indented strings. */ -struct ExprIndStr : Expr { - std::string s; - ExprIndStr(const std::string& s) : s(s){}; -}; - -struct ExprPath : Expr { - std::string s; - Value v; - ExprPath(const std::string& s) : s(s) { mkPathNoCopy(v, this->s.c_str()); }; - COMMON_METHODS - Value* maybeThunk(EvalState& state, Env& env); -}; - -struct ExprVar : Expr { - Pos pos; - Symbol name; - - /* Whether the variable comes from an environment (e.g. a rec, let - or function argument) or from a "with". */ - bool fromWith; - - /* In the former case, the value is obtained by going `level' - levels up from the current environment and getting the - `displ'th value in that environment. In the latter case, the - value is obtained by getting the attribute named `name' from - the set stored in the environment that is `level' levels up - from the current one.*/ - unsigned int level; - unsigned int displ; - - ExprVar(const Symbol& name) : name(name){}; - ExprVar(const Pos& pos, const Symbol& name) : pos(pos), name(name){}; - COMMON_METHODS - Value* maybeThunk(EvalState& state, Env& env); -}; - -// [tazjin] I *think* that this struct describes the syntactic -// construct for "selecting" something out of an attribute set, e.g. -// `a.b.c` => ExprSelect{"b", "c"}. -// -// Each path element has got a pointer to an expression, which seems -// to be the thing preceding its period, but afaict that is only set -// for the first one in a path. -struct ExprSelect : Expr { - Pos pos; - Expr *e, *def; - AttrPath attrPath; - ExprSelect(const Pos& pos, Expr* e, const AttrPath& attrPath, Expr* def) - : pos(pos), e(e), def(def), attrPath(attrPath){}; - ExprSelect(const Pos& pos, Expr* e, const Symbol& name) - : pos(pos), e(e), def(0) { - attrPath.push_back(AttrName(name)); - }; - COMMON_METHODS -}; - -struct ExprOpHasAttr : Expr { - Pos pos; - Expr* e; - AttrPath attrPath; - ExprOpHasAttr(Expr* e, const AttrPath& attrPath) : e(e), attrPath(attrPath){}; - ExprOpHasAttr(const Pos& pos, Expr* e, const AttrPath& attrPath) - : pos(pos), e(e), attrPath(attrPath){}; - COMMON_METHODS -}; - -struct ExprAttrs : Expr { - bool recursive; - - struct AttrDef { - bool inherited; - Expr* e; - Pos pos; - unsigned int displ; // displacement - AttrDef(Expr* e, const Pos& pos, bool inherited = false) - : inherited(inherited), e(e), pos(pos), displ(0){}; - AttrDef(){}; - }; - - using AttrDefs = absl::flat_hash_map<Symbol, AttrDef>; - AttrDefs attrs; - - struct DynamicAttrDef { - Expr *nameExpr, *valueExpr; - Pos pos; - DynamicAttrDef(Expr* nameExpr, Expr* valueExpr, const Pos& pos) - : nameExpr(nameExpr), valueExpr(valueExpr), pos(pos){}; - }; - - using DynamicAttrDefs = std::vector<DynamicAttrDef>; - DynamicAttrDefs dynamicAttrs; - - ExprAttrs() : recursive(false){}; - COMMON_METHODS -}; - -struct ExprList : Expr { - VectorExprs elems; - ExprList(){}; - COMMON_METHODS -}; - -struct Formal { - Symbol name; - Expr* def; // def = default, not definition - Formal(const Symbol& name, Expr* def) : name(name), def(def){}; -}; - -// Describes structured function arguments (e.g. `{ a }: ...`) -struct Formals { - using Formals_ = std::list<Formal>; - Formals_ formals; - std::set<Symbol> argNames; // used during parsing - bool ellipsis; -}; - -struct ExprLambda : Expr { - public: - Pos pos; - std::optional<Symbol> name; - Symbol arg; - bool matchAttrs; - Formals* formals; - Expr* body; - ExprLambda(const Pos& pos, const Symbol& arg, bool matchAttrs, - Formals* formals, Expr* body) - : pos(pos), - arg(arg), - matchAttrs(matchAttrs), - formals(formals), - body(body) { - if (!arg.empty() && formals && - formals->argNames.find(arg) != formals->argNames.end()) { - throw ParseError( - format("duplicate formal function argument '%1%' at %2%") % arg % - pos); - } - }; - void setName(Symbol& name); - std::string showNamePos() const; - COMMON_METHODS -}; - -struct ExprLet : Expr { - ExprAttrs* attrs; - Expr* body; - ExprLet(ExprAttrs* attrs, Expr* body) : attrs(attrs), body(body){}; - COMMON_METHODS -}; - -struct ExprWith : Expr { - Pos pos; - Expr *attrs, *body; - size_t prevWith; - ExprWith(const Pos& pos, Expr* attrs, Expr* body) - : pos(pos), attrs(attrs), body(body){}; - COMMON_METHODS -}; - -struct ExprIf : Expr { - Pos pos; - Expr *cond, *then, *else_; - ExprIf(Expr* cond, Expr* then, Expr* else_) - : cond(cond), then(then), else_(else_){}; - ExprIf(const Pos& pos, Expr* cond, Expr* then, Expr* else_) - : pos(pos), cond(cond), then(then), else_(else_){}; - COMMON_METHODS -}; - -struct ExprAssert : Expr { - Pos pos; - Expr *cond, *body; - ExprAssert(const Pos& pos, Expr* cond, Expr* body) - : pos(pos), cond(cond), body(body){}; - COMMON_METHODS -}; - -struct ExprOpNot : Expr { - Pos pos; - Expr* e; - explicit ExprOpNot(Expr* e) : e(e){}; - ExprOpNot(const Pos& pos, Expr* e) : pos(pos), e(e){}; - COMMON_METHODS -}; - -#define MakeBinOp(name, s) \ - struct name : Expr { \ - Pos pos; \ - Expr *e1, *e2; \ - name(Expr* e1, Expr* e2) : e1(e1), e2(e2){}; \ - name(const Pos& pos, Expr* e1, Expr* e2) : pos(pos), e1(e1), e2(e2){}; \ - void show(std::ostream& str) const { \ - str << "(" << *e1 << " " s " " << *e2 << ")"; \ - } \ - void bindVars(const StaticEnv& env) { \ - e1->bindVars(env); \ - e2->bindVars(env); \ - } \ - void eval(EvalState& state, Env& env, Value& v); \ - }; - -MakeBinOp(ExprApp, ""); -MakeBinOp(ExprOpEq, "=="); -MakeBinOp(ExprOpNEq, "!="); -MakeBinOp(ExprOpAnd, "&&"); -MakeBinOp(ExprOpOr, "||"); -MakeBinOp(ExprOpImpl, "->"); -MakeBinOp(ExprOpUpdate, "//"); -MakeBinOp(ExprOpConcatLists, "++"); - -struct ExprConcatStrings : Expr { - Pos pos; - bool forceString; - nix::VectorExprs* es; - ExprConcatStrings(const Pos& pos, bool forceString, nix::VectorExprs* es) - : pos(pos), forceString(forceString), es(es){}; - COMMON_METHODS -}; - -struct ExprPos : Expr { - Pos pos; - ExprPos(const Pos& pos) : pos(pos){}; - COMMON_METHODS -}; - -/* Static environments are used to map variable names onto (level, - displacement) pairs used to obtain the value of the variable at - runtime. */ -struct StaticEnv { - bool isWith; - const StaticEnv* up; - typedef absl::flat_hash_map<Symbol, unsigned int> Vars; - Vars vars; - StaticEnv(bool isWith, const StaticEnv* up) : isWith(isWith), up(up){}; -}; - -} // namespace nix |