diff options
Diffstat (limited to 'third_party/nix/src/libexpr/nixexpr.hh')
-rw-r--r-- | third_party/nix/src/libexpr/nixexpr.hh | 503 |
1 files changed, 235 insertions, 268 deletions
diff --git a/third_party/nix/src/libexpr/nixexpr.hh b/third_party/nix/src/libexpr/nixexpr.hh index 665a42987dc1..efc4398c2371 100644 --- a/third_party/nix/src/libexpr/nixexpr.hh +++ b/third_party/nix/src/libexpr/nixexpr.hh @@ -1,342 +1,309 @@ #pragma once -#include "value.hh" -#include "symbol-table.hh" - #include <map> - +#include "symbol-table.hh" +#include "value.hh" 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 -{ - Symbol file; - unsigned int line, column; - Pos() : line(0), column(0) { }; - Pos(const Symbol & file, unsigned int line, unsigned int column) - : file(file), line(line), column(column) { }; - operator bool() const - { - return line != 0; - } - bool operator < (const Pos & p2) const - { - if (!line) return p2.line; - if (!p2.line) return false; - int d = ((string) file).compare((string) p2.file); - 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; - } +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 { + Symbol file; + unsigned int line, column; + Pos() : line(0), column(0){}; + Pos(const Symbol& file, unsigned int line, unsigned int column) + : file(file), line(line), column(column){}; + operator bool() const { return line != 0; } + bool operator<(const Pos& p2) const { + if (!line) return p2.line; + if (!p2.line) return false; + int d = ((string)file).compare((string)p2.file); + 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); - +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. */ -struct AttrName -{ - Symbol symbol; - Expr * expr; - AttrName(const Symbol & s) : symbol(s) {}; - AttrName(Expr * e) : expr(e) {}; +struct AttrName { + Symbol symbol; + Expr* expr; + AttrName(const Symbol& s) : symbol(s){}; + AttrName(Expr* e) : expr(e){}; }; typedef std::vector<AttrName> AttrPath; -string showAttrPath(const AttrPath & attrPath); - +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); - virtual void setName(Symbol & name); +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); + virtual void setName(Symbol& name); }; -std::ostream & operator << (std::ostream & str, const Expr & e); +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); +#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 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 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); +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 -{ - string s; - ExprIndStr(const string & s) : s(s) { }; +struct ExprIndStr : Expr { + string s; + ExprIndStr(const string& s) : s(s){}; }; -struct ExprPath : Expr -{ - string s; - Value v; - ExprPath(const string & s) : s(s) { mkPathNoCopy(v, this->s.c_str()); }; - COMMON_METHODS - Value * maybeThunk(EvalState & state, Env & env); +struct ExprPath : Expr { + string s; + Value v; + ExprPath(const 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); +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); }; -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 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 -{ - Expr * e; - AttrPath attrPath; - ExprOpHasAttr(Expr * e, const AttrPath & attrPath) : e(e), attrPath(attrPath) { }; - COMMON_METHODS +struct ExprOpHasAttr : Expr { + Expr* e; + AttrPath attrPath; + ExprOpHasAttr(Expr* e, const AttrPath& attrPath) : 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) { }; - AttrDef() { }; - }; - typedef std::map<Symbol, AttrDef> AttrDefs; - AttrDefs attrs; - struct DynamicAttrDef { - Expr * nameExpr, * valueExpr; - Pos pos; - DynamicAttrDef(Expr * nameExpr, Expr * valueExpr, const Pos & pos) - : nameExpr(nameExpr), valueExpr(valueExpr), pos(pos) { }; - }; - typedef std::vector<DynamicAttrDef> DynamicAttrDefs; - DynamicAttrDefs dynamicAttrs; - ExprAttrs() : recursive(false) { }; - 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){}; + AttrDef(){}; + }; + typedef std::map<Symbol, AttrDef> AttrDefs; + AttrDefs attrs; + struct DynamicAttrDef { + Expr *nameExpr, *valueExpr; + Pos pos; + DynamicAttrDef(Expr* nameExpr, Expr* valueExpr, const Pos& pos) + : nameExpr(nameExpr), valueExpr(valueExpr), pos(pos){}; + }; + typedef std::vector<DynamicAttrDef> DynamicAttrDefs; + DynamicAttrDefs dynamicAttrs; + ExprAttrs() : recursive(false){}; + COMMON_METHODS }; -struct ExprList : Expr -{ - std::vector<Expr *> elems; - ExprList() { }; - COMMON_METHODS +struct ExprList : Expr { + std::vector<Expr*> elems; + ExprList(){}; + COMMON_METHODS }; -struct Formal -{ - Symbol name; - Expr * def; - Formal(const Symbol & name, Expr * def) : name(name), def(def) { }; +struct Formal { + Symbol name; + Expr* def; + Formal(const Symbol& name, Expr* def) : name(name), def(def){}; }; -struct Formals -{ - typedef std::list<Formal> Formals_; - Formals_ formals; - std::set<Symbol> argNames; // used during parsing - bool ellipsis; +struct Formals { + typedef std::list<Formal> Formals_; + Formals_ formals; + std::set<Symbol> argNames; // used during parsing + bool ellipsis; }; -struct ExprLambda : Expr -{ - Pos pos; - 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); - string showNamePos() const; - COMMON_METHODS +struct ExprLambda : Expr { + Pos pos; + 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); + string showNamePos() const; + COMMON_METHODS }; -struct ExprLet : Expr -{ - ExprAttrs * attrs; - Expr * body; - ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { }; - 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 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 -{ - Expr * cond, * then, * else_; - ExprIf(Expr * cond, Expr * then, Expr * else_) : cond(cond), then(then), else_(else_) { }; - COMMON_METHODS +struct ExprIf : Expr { + Expr *cond, *then, *else_; + ExprIf(Expr* cond, Expr* then, Expr* else_) + : 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 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 -{ - Expr * e; - ExprOpNot(Expr * e) : e(e) { }; - COMMON_METHODS +struct ExprOpNot : Expr { + Expr* e; + ExprOpNot(Expr* e) : 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; - vector<Expr *> * es; - ExprConcatStrings(const Pos & pos, bool forceString, vector<Expr *> * es) - : pos(pos), forceString(forceString), es(es) { }; - 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; + vector<Expr*>* es; + ExprConcatStrings(const Pos& pos, bool forceString, vector<Expr*>* es) + : pos(pos), forceString(forceString), es(es){}; + COMMON_METHODS }; -struct ExprPos : Expr -{ - Pos pos; - ExprPos(const Pos & pos) : pos(pos) { }; - 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 std::map<Symbol, unsigned int> Vars; - Vars vars; - StaticEnv(bool isWith, const StaticEnv * up) : isWith(isWith), up(up) { }; +struct StaticEnv { + bool isWith; + const StaticEnv* up; + typedef std::map<Symbol, unsigned int> Vars; + Vars vars; + StaticEnv(bool isWith, const StaticEnv* up) : isWith(isWith), up(up){}; }; - -} +} // namespace nix |