diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/nix/src/libexpr/nixexpr.cc | 603 |
1 files changed, 263 insertions, 340 deletions
diff --git a/third_party/nix/src/libexpr/nixexpr.cc b/third_party/nix/src/libexpr/nixexpr.cc index 63cbef1ddf84..4147cbbf532b 100644 --- a/third_party/nix/src/libexpr/nixexpr.cc +++ b/third_party/nix/src/libexpr/nixexpr.cc @@ -1,438 +1,361 @@ #include "nixexpr.hh" +#include <cstdlib> #include "derivations.hh" #include "util.hh" -#include <cstdlib> - - namespace nix { - /* Displaying abstract syntax trees. */ -std::ostream & operator << (std::ostream & str, const Expr & e) -{ - e.show(str); - return str; -} - -static void showString(std::ostream & str, const string & s) -{ - str << '"'; - for (auto c : (string) s) - if (c == '"' || c == '\\' || c == '$') str << "\\" << c; - else if (c == '\n') str << "\\n"; - else if (c == '\r') str << "\\r"; - else if (c == '\t') str << "\\t"; - else str << c; - str << '"'; -} - -static void showId(std::ostream & str, const string & s) -{ - if (s.empty()) - str << "\"\""; - else if (s == "if") // FIXME: handle other keywords - str << '"' << s << '"'; - else { - char c = s[0]; - if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')) { - showString(str, s); - return; - } - for (auto c : s) - if (!((c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || - c == '_' || c == '\'' || c == '-')) { - showString(str, s); - return; - } - str << s; +std::ostream& operator<<(std::ostream& str, const Expr& e) { + e.show(str); + return str; +} + +static void showString(std::ostream& str, const string& s) { + str << '"'; + for (auto c : (string)s) + if (c == '"' || c == '\\' || c == '$') + str << "\\" << c; + else if (c == '\n') + str << "\\n"; + else if (c == '\r') + str << "\\r"; + else if (c == '\t') + str << "\\t"; + else + str << c; + str << '"'; +} + +static void showId(std::ostream& str, const string& s) { + if (s.empty()) + str << "\"\""; + else if (s == "if") // FIXME: handle other keywords + str << '"' << s << '"'; + else { + char c = s[0]; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')) { + showString(str, s); + return; } + for (auto c : s) + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c == '_' || c == '\'' || c == '-')) { + showString(str, s); + return; + } + str << s; + } } -std::ostream & operator << (std::ostream & str, const Symbol & sym) -{ - showId(str, *sym.s); - return str; +std::ostream& operator<<(std::ostream& str, const Symbol& sym) { + showId(str, *sym.s); + return str; } -void Expr::show(std::ostream & str) const -{ - abort(); -} +void Expr::show(std::ostream& str) const { abort(); } -void ExprInt::show(std::ostream & str) const -{ - str << n; -} +void ExprInt::show(std::ostream& str) const { str << n; } -void ExprFloat::show(std::ostream & str) const -{ - str << nf; -} +void ExprFloat::show(std::ostream& str) const { str << nf; } -void ExprString::show(std::ostream & str) const -{ - showString(str, s); -} +void ExprString::show(std::ostream& str) const { showString(str, s); } -void ExprPath::show(std::ostream & str) const -{ - str << s; -} +void ExprPath::show(std::ostream& str) const { str << s; } -void ExprVar::show(std::ostream & str) const -{ - str << name; -} +void ExprVar::show(std::ostream& str) const { str << name; } -void ExprSelect::show(std::ostream & str) const -{ - str << "(" << *e << ")." << showAttrPath(attrPath); - if (def) str << " or (" << *def << ")"; +void ExprSelect::show(std::ostream& str) const { + str << "(" << *e << ")." << showAttrPath(attrPath); + if (def) str << " or (" << *def << ")"; } -void ExprOpHasAttr::show(std::ostream & str) const -{ - str << "((" << *e << ") ? " << showAttrPath(attrPath) << ")"; +void ExprOpHasAttr::show(std::ostream& str) const { + str << "((" << *e << ") ? " << showAttrPath(attrPath) << ")"; } -void ExprAttrs::show(std::ostream & str) const -{ - if (recursive) str << "rec "; - str << "{ "; - for (auto & i : attrs) - if (i.second.inherited) - str << "inherit " << i.first << " " << "; "; - else - str << i.first << " = " << *i.second.e << "; "; - for (auto & i : dynamicAttrs) - str << "\"${" << *i.nameExpr << "}\" = " << *i.valueExpr << "; "; - str << "}"; +void ExprAttrs::show(std::ostream& str) const { + if (recursive) str << "rec "; + str << "{ "; + for (auto& i : attrs) + if (i.second.inherited) + str << "inherit " << i.first << " " + << "; "; + else + str << i.first << " = " << *i.second.e << "; "; + for (auto& i : dynamicAttrs) + str << "\"${" << *i.nameExpr << "}\" = " << *i.valueExpr << "; "; + str << "}"; } -void ExprList::show(std::ostream & str) const -{ - str << "[ "; - for (auto & i : elems) - str << "(" << *i << ") "; - str << "]"; +void ExprList::show(std::ostream& str) const { + str << "[ "; + for (auto& i : elems) str << "(" << *i << ") "; + str << "]"; } -void ExprLambda::show(std::ostream & str) const -{ - str << "("; - if (matchAttrs) { - str << "{ "; - bool first = true; - for (auto & i : formals->formals) { - if (first) first = false; else str << ", "; - str << i.name; - if (i.def) str << " ? " << *i.def; - } - if (formals->ellipsis) { - if (!first) str << ", "; - str << "..."; - } - str << " }"; - if (!arg.empty()) str << " @ "; +void ExprLambda::show(std::ostream& str) const { + str << "("; + if (matchAttrs) { + str << "{ "; + bool first = true; + for (auto& i : formals->formals) { + if (first) + first = false; + else + str << ", "; + str << i.name; + if (i.def) str << " ? " << *i.def; } - if (!arg.empty()) str << arg; - str << ": " << *body << ")"; -} - -void ExprLet::show(std::ostream & str) const -{ - str << "(let "; - for (auto & i : attrs->attrs) - if (i.second.inherited) { - str << "inherit " << i.first << "; "; - } - else - str << i.first << " = " << *i.second.e << "; "; - str << "in " << *body << ")"; -} - -void ExprWith::show(std::ostream & str) const -{ - str << "(with " << *attrs << "; " << *body << ")"; -} - -void ExprIf::show(std::ostream & str) const -{ - str << "(if " << *cond << " then " << *then << " else " << *else_ << ")"; + if (formals->ellipsis) { + if (!first) str << ", "; + str << "..."; + } + str << " }"; + if (!arg.empty()) str << " @ "; + } + if (!arg.empty()) str << arg; + str << ": " << *body << ")"; } -void ExprAssert::show(std::ostream & str) const -{ - str << "assert " << *cond << "; " << *body; +void ExprLet::show(std::ostream& str) const { + str << "(let "; + for (auto& i : attrs->attrs) + if (i.second.inherited) { + str << "inherit " << i.first << "; "; + } else + str << i.first << " = " << *i.second.e << "; "; + str << "in " << *body << ")"; } -void ExprOpNot::show(std::ostream & str) const -{ - str << "(! " << *e << ")"; +void ExprWith::show(std::ostream& str) const { + str << "(with " << *attrs << "; " << *body << ")"; } -void ExprConcatStrings::show(std::ostream & str) const -{ - bool first = true; - str << "("; - for (auto & i : *es) { - if (first) first = false; else str << " + "; - str << *i; - } - str << ")"; +void ExprIf::show(std::ostream& str) const { + str << "(if " << *cond << " then " << *then << " else " << *else_ << ")"; } -void ExprPos::show(std::ostream & str) const -{ - str << "__curPos"; +void ExprAssert::show(std::ostream& str) const { + str << "assert " << *cond << "; " << *body; } +void ExprOpNot::show(std::ostream& str) const { str << "(! " << *e << ")"; } -std::ostream & operator << (std::ostream & str, const Pos & pos) -{ - if (!pos) - str << "undefined position"; +void ExprConcatStrings::show(std::ostream& str) const { + bool first = true; + str << "("; + for (auto& i : *es) { + if (first) + first = false; else - str << (format(ANSI_BOLD "%1%" ANSI_NORMAL ":%2%:%3%") % (string) pos.file % pos.line % pos.column).str(); - return str; -} - - -string showAttrPath(const AttrPath & attrPath) -{ - std::ostringstream out; - bool first = true; - for (auto & i : attrPath) { - if (!first) out << '.'; else first = false; - if (i.symbol.set()) - out << i.symbol; - else - out << "\"${" << *i.expr << "}\""; - } - return out.str(); + str << " + "; + str << *i; + } + str << ")"; +} + +void ExprPos::show(std::ostream& str) const { str << "__curPos"; } + +std::ostream& operator<<(std::ostream& str, const Pos& pos) { + if (!pos) + str << "undefined position"; + else + str << (format(ANSI_BOLD "%1%" ANSI_NORMAL ":%2%:%3%") % (string)pos.file % + pos.line % pos.column) + .str(); + return str; +} + +string showAttrPath(const AttrPath& attrPath) { + std::ostringstream out; + bool first = true; + for (auto& i : attrPath) { + if (!first) + out << '.'; + else + first = false; + if (i.symbol.set()) + out << i.symbol; + else + out << "\"${" << *i.expr << "}\""; + } + return out.str(); } - Pos noPos; - /* Computing levels/displacements for variables. */ -void Expr::bindVars(const StaticEnv & env) -{ - abort(); -} - -void ExprInt::bindVars(const StaticEnv & env) -{ -} - -void ExprFloat::bindVars(const StaticEnv & env) -{ -} - -void ExprString::bindVars(const StaticEnv & env) -{ -} - -void ExprPath::bindVars(const StaticEnv & env) -{ -} - -void ExprVar::bindVars(const StaticEnv & env) -{ - /* Check whether the variable appears in the environment. If so, - set its level and displacement. */ - const StaticEnv * curEnv; - unsigned int level; - int withLevel = -1; - for (curEnv = &env, level = 0; curEnv; curEnv = curEnv->up, level++) { - if (curEnv->isWith) { - if (withLevel == -1) withLevel = level; - } else { - StaticEnv::Vars::const_iterator i = curEnv->vars.find(name); - if (i != curEnv->vars.end()) { - fromWith = false; - this->level = level; - displ = i->second; - return; - } - } +void Expr::bindVars(const StaticEnv& env) { abort(); } + +void ExprInt::bindVars(const StaticEnv& env) {} + +void ExprFloat::bindVars(const StaticEnv& env) {} + +void ExprString::bindVars(const StaticEnv& env) {} + +void ExprPath::bindVars(const StaticEnv& env) {} + +void ExprVar::bindVars(const StaticEnv& env) { + /* Check whether the variable appears in the environment. If so, + set its level and displacement. */ + const StaticEnv* curEnv; + unsigned int level; + int withLevel = -1; + for (curEnv = &env, level = 0; curEnv; curEnv = curEnv->up, level++) { + if (curEnv->isWith) { + if (withLevel == -1) withLevel = level; + } else { + StaticEnv::Vars::const_iterator i = curEnv->vars.find(name); + if (i != curEnv->vars.end()) { + fromWith = false; + this->level = level; + displ = i->second; + return; + } } + } - /* Otherwise, the variable must be obtained from the nearest - enclosing `with'. If there is no `with', then we can issue an - "undefined variable" error now. */ - if (withLevel == -1) throw UndefinedVarError(format("undefined variable '%1%' at %2%") % name % pos); + /* Otherwise, the variable must be obtained from the nearest + enclosing `with'. If there is no `with', then we can issue an + "undefined variable" error now. */ + if (withLevel == -1) + throw UndefinedVarError(format("undefined variable '%1%' at %2%") % name % + pos); - fromWith = true; - this->level = withLevel; + fromWith = true; + this->level = withLevel; } -void ExprSelect::bindVars(const StaticEnv & env) -{ - e->bindVars(env); - if (def) def->bindVars(env); - for (auto & i : attrPath) - if (!i.symbol.set()) - i.expr->bindVars(env); +void ExprSelect::bindVars(const StaticEnv& env) { + e->bindVars(env); + if (def) def->bindVars(env); + for (auto& i : attrPath) + if (!i.symbol.set()) i.expr->bindVars(env); } -void ExprOpHasAttr::bindVars(const StaticEnv & env) -{ - e->bindVars(env); - for (auto & i : attrPath) - if (!i.symbol.set()) - i.expr->bindVars(env); +void ExprOpHasAttr::bindVars(const StaticEnv& env) { + e->bindVars(env); + for (auto& i : attrPath) + if (!i.symbol.set()) i.expr->bindVars(env); } -void ExprAttrs::bindVars(const StaticEnv & env) -{ - const StaticEnv * dynamicEnv = &env; - StaticEnv newEnv(false, &env); +void ExprAttrs::bindVars(const StaticEnv& env) { + const StaticEnv* dynamicEnv = &env; + StaticEnv newEnv(false, &env); - if (recursive) { - dynamicEnv = &newEnv; + if (recursive) { + dynamicEnv = &newEnv; - unsigned int displ = 0; - for (auto & i : attrs) - newEnv.vars[i.first] = i.second.displ = displ++; + unsigned int displ = 0; + for (auto& i : attrs) newEnv.vars[i.first] = i.second.displ = displ++; - for (auto & i : attrs) - i.second.e->bindVars(i.second.inherited ? env : newEnv); - } + for (auto& i : attrs) + i.second.e->bindVars(i.second.inherited ? env : newEnv); + } - else - for (auto & i : attrs) - i.second.e->bindVars(env); + else + for (auto& i : attrs) i.second.e->bindVars(env); - for (auto & i : dynamicAttrs) { - i.nameExpr->bindVars(*dynamicEnv); - i.valueExpr->bindVars(*dynamicEnv); - } + for (auto& i : dynamicAttrs) { + i.nameExpr->bindVars(*dynamicEnv); + i.valueExpr->bindVars(*dynamicEnv); + } } -void ExprList::bindVars(const StaticEnv & env) -{ - for (auto & i : elems) - i->bindVars(env); +void ExprList::bindVars(const StaticEnv& env) { + for (auto& i : elems) i->bindVars(env); } -void ExprLambda::bindVars(const StaticEnv & env) -{ - StaticEnv newEnv(false, &env); +void ExprLambda::bindVars(const StaticEnv& env) { + StaticEnv newEnv(false, &env); - unsigned int displ = 0; + unsigned int displ = 0; - if (!arg.empty()) newEnv.vars[arg] = displ++; + if (!arg.empty()) newEnv.vars[arg] = displ++; - if (matchAttrs) { - for (auto & i : formals->formals) - newEnv.vars[i.name] = displ++; + if (matchAttrs) { + for (auto& i : formals->formals) newEnv.vars[i.name] = displ++; - for (auto & i : formals->formals) - if (i.def) i.def->bindVars(newEnv); - } + for (auto& i : formals->formals) + if (i.def) i.def->bindVars(newEnv); + } - body->bindVars(newEnv); + body->bindVars(newEnv); } -void ExprLet::bindVars(const StaticEnv & env) -{ - StaticEnv newEnv(false, &env); +void ExprLet::bindVars(const StaticEnv& env) { + StaticEnv newEnv(false, &env); - unsigned int displ = 0; - for (auto & i : attrs->attrs) - newEnv.vars[i.first] = i.second.displ = displ++; + unsigned int displ = 0; + for (auto& i : attrs->attrs) newEnv.vars[i.first] = i.second.displ = displ++; - for (auto & i : attrs->attrs) - i.second.e->bindVars(i.second.inherited ? env : newEnv); + for (auto& i : attrs->attrs) + i.second.e->bindVars(i.second.inherited ? env : newEnv); - body->bindVars(newEnv); + body->bindVars(newEnv); } -void ExprWith::bindVars(const StaticEnv & env) -{ - /* Does this `with' have an enclosing `with'? If so, record its - level so that `lookupVar' can look up variables in the previous - `with' if this one doesn't contain the desired attribute. */ - const StaticEnv * curEnv; - unsigned int level; - prevWith = 0; - for (curEnv = &env, level = 1; curEnv; curEnv = curEnv->up, level++) - if (curEnv->isWith) { - prevWith = level; - break; - } - - attrs->bindVars(env); - StaticEnv newEnv(true, &env); - body->bindVars(newEnv); -} +void ExprWith::bindVars(const StaticEnv& env) { + /* Does this `with' have an enclosing `with'? If so, record its + level so that `lookupVar' can look up variables in the previous + `with' if this one doesn't contain the desired attribute. */ + const StaticEnv* curEnv; + unsigned int level; + prevWith = 0; + for (curEnv = &env, level = 1; curEnv; curEnv = curEnv->up, level++) + if (curEnv->isWith) { + prevWith = level; + break; + } -void ExprIf::bindVars(const StaticEnv & env) -{ - cond->bindVars(env); - then->bindVars(env); - else_->bindVars(env); + attrs->bindVars(env); + StaticEnv newEnv(true, &env); + body->bindVars(newEnv); } -void ExprAssert::bindVars(const StaticEnv & env) -{ - cond->bindVars(env); - body->bindVars(env); +void ExprIf::bindVars(const StaticEnv& env) { + cond->bindVars(env); + then->bindVars(env); + else_->bindVars(env); } -void ExprOpNot::bindVars(const StaticEnv & env) -{ - e->bindVars(env); +void ExprAssert::bindVars(const StaticEnv& env) { + cond->bindVars(env); + body->bindVars(env); } -void ExprConcatStrings::bindVars(const StaticEnv & env) -{ - for (auto & i : *es) - i->bindVars(env); -} +void ExprOpNot::bindVars(const StaticEnv& env) { e->bindVars(env); } -void ExprPos::bindVars(const StaticEnv & env) -{ +void ExprConcatStrings::bindVars(const StaticEnv& env) { + for (auto& i : *es) i->bindVars(env); } +void ExprPos::bindVars(const StaticEnv& env) {} /* Storing function names. */ -void Expr::setName(Symbol & name) -{ -} - +void Expr::setName(Symbol& name) {} -void ExprLambda::setName(Symbol & name) -{ - this->name = name; - body->setName(name); +void ExprLambda::setName(Symbol& name) { + this->name = name; + body->setName(name); } - -string ExprLambda::showNamePos() const -{ - return (format("%1% at %2%") % (name.set() ? "'" + (string) name + "'" : "anonymous function") % pos).str(); +string ExprLambda::showNamePos() const { + return (format("%1% at %2%") % + (name.set() ? "'" + (string)name + "'" : "anonymous function") % pos) + .str(); } - - /* Symbol table. */ -size_t SymbolTable::totalSize() const -{ - size_t n = 0; - for (auto & i : symbols) - n += i.size(); - return n; +size_t SymbolTable::totalSize() const { + size_t n = 0; + for (auto& i : symbols) n += i.size(); + return n; } - -} +} // namespace nix |