Use Value::normalType on all forced values instead of Value::type
This commit is contained in:
parent
9f056f7afd
commit
22ead43a0b
15 changed files with 199 additions and 213 deletions
|
@ -67,7 +67,7 @@ std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attr
|
||||||
|
|
||||||
if (apType == apAttr) {
|
if (apType == apAttr) {
|
||||||
|
|
||||||
if (v->type != tAttrs)
|
if (v->normalType() != nAttrs)
|
||||||
throw TypeError(
|
throw TypeError(
|
||||||
"the expression selected by the selection path '%1%' should be a set but is %2%",
|
"the expression selected by the selection path '%1%' should be a set but is %2%",
|
||||||
attrPath,
|
attrPath,
|
||||||
|
|
|
@ -390,14 +390,14 @@ Value & AttrCursor::forceValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root->db && (!cachedValue || std::get_if<placeholder_t>(&cachedValue->second))) {
|
if (root->db && (!cachedValue || std::get_if<placeholder_t>(&cachedValue->second))) {
|
||||||
if (v.type == tString)
|
if (v.normalType() == nString)
|
||||||
cachedValue = {root->db->setString(getKey(), v.string.s, v.string.context),
|
cachedValue = {root->db->setString(getKey(), v.string.s, v.string.context),
|
||||||
string_t{v.string.s, {}}};
|
string_t{v.string.s, {}}};
|
||||||
else if (v.type == tPath)
|
else if (v.normalType() == nPath)
|
||||||
cachedValue = {root->db->setString(getKey(), v.path), v.path};
|
cachedValue = {root->db->setString(getKey(), v.path), v.path};
|
||||||
else if (v.type == tBool)
|
else if (v.normalType() == nBool)
|
||||||
cachedValue = {root->db->setBool(getKey(), v.boolean), v.boolean};
|
cachedValue = {root->db->setBool(getKey(), v.boolean), v.boolean};
|
||||||
else if (v.type == tAttrs)
|
else if (v.normalType() == nAttrs)
|
||||||
; // FIXME: do something?
|
; // FIXME: do something?
|
||||||
else
|
else
|
||||||
cachedValue = {root->db->setMisc(getKey()), misc_t()};
|
cachedValue = {root->db->setMisc(getKey()), misc_t()};
|
||||||
|
@ -442,7 +442,7 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol name, bool forceErro
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue();
|
||||||
|
|
||||||
if (v.type != tAttrs)
|
if (v.normalType() != nAttrs)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
//throw TypeError("'%s' is not an attribute set", getAttrPathStr());
|
//throw TypeError("'%s' is not an attribute set", getAttrPathStr());
|
||||||
|
|
||||||
|
@ -512,10 +512,10 @@ std::string AttrCursor::getString()
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue();
|
||||||
|
|
||||||
if (v.type != tString && v.type != tPath)
|
if (v.normalType() != nString && v.normalType() != nPath)
|
||||||
throw TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.normalType()));
|
throw TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.normalType()));
|
||||||
|
|
||||||
return v.type == tString ? v.string.s : v.path;
|
return v.normalType() == nString ? v.string.s : v.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t AttrCursor::getStringWithContext()
|
string_t AttrCursor::getStringWithContext()
|
||||||
|
@ -543,9 +543,9 @@ string_t AttrCursor::getStringWithContext()
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue();
|
||||||
|
|
||||||
if (v.type == tString)
|
if (v.normalType() == nString)
|
||||||
return {v.string.s, v.getContext()};
|
return {v.string.s, v.getContext()};
|
||||||
else if (v.type == tPath)
|
else if (v.normalType() == nPath)
|
||||||
return {v.path, {}};
|
return {v.path, {}};
|
||||||
else
|
else
|
||||||
throw TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.normalType()));
|
throw TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.normalType()));
|
||||||
|
@ -567,7 +567,7 @@ bool AttrCursor::getBool()
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue();
|
||||||
|
|
||||||
if (v.type != tBool)
|
if (v.normalType() != nBool)
|
||||||
throw TypeError("'%s' is not a Boolean", getAttrPathStr());
|
throw TypeError("'%s' is not a Boolean", getAttrPathStr());
|
||||||
|
|
||||||
return v.boolean;
|
return v.boolean;
|
||||||
|
@ -589,7 +589,7 @@ std::vector<Symbol> AttrCursor::getAttrs()
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue();
|
||||||
|
|
||||||
if (v.type != tAttrs)
|
if (v.normalType() != nAttrs)
|
||||||
throw TypeError("'%s' is not an attribute set", getAttrPathStr());
|
throw TypeError("'%s' is not an attribute set", getAttrPathStr());
|
||||||
|
|
||||||
std::vector<Symbol> attrs;
|
std::vector<Symbol> attrs;
|
||||||
|
|
|
@ -56,7 +56,7 @@ void EvalState::forceValue(Value & v, const Pos & pos)
|
||||||
inline void EvalState::forceAttrs(Value & v)
|
inline void EvalState::forceAttrs(Value & v)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v);
|
||||||
if (v.type != tAttrs)
|
if (v.normalType() != nAttrs)
|
||||||
throwTypeError("value is %1% while a set was expected", v);
|
throwTypeError("value is %1% while a set was expected", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ inline void EvalState::forceAttrs(Value & v)
|
||||||
inline void EvalState::forceAttrs(Value & v, const Pos & pos)
|
inline void EvalState::forceAttrs(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type != tAttrs)
|
if (v.normalType() != nAttrs)
|
||||||
throwTypeError(pos, "value is %1% while a set was expected", v);
|
throwTypeError(pos, "value is %1% while a set was expected", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -947,7 +947,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e)
|
||||||
{
|
{
|
||||||
Value v;
|
Value v;
|
||||||
e->eval(*this, env, v);
|
e->eval(*this, env, v);
|
||||||
if (v.type != tBool)
|
if (v.normalType() != nBool)
|
||||||
throwTypeError("value is %1% while a Boolean was expected", v);
|
throwTypeError("value is %1% while a Boolean was expected", v);
|
||||||
return v.boolean;
|
return v.boolean;
|
||||||
}
|
}
|
||||||
|
@ -957,7 +957,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const Pos & pos)
|
||||||
{
|
{
|
||||||
Value v;
|
Value v;
|
||||||
e->eval(*this, env, v);
|
e->eval(*this, env, v);
|
||||||
if (v.type != tBool)
|
if (v.normalType() != nBool)
|
||||||
throwTypeError(pos, "value is %1% while a Boolean was expected", v);
|
throwTypeError(pos, "value is %1% while a Boolean was expected", v);
|
||||||
return v.boolean;
|
return v.boolean;
|
||||||
}
|
}
|
||||||
|
@ -966,7 +966,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const Pos & pos)
|
||||||
inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v)
|
inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v)
|
||||||
{
|
{
|
||||||
e->eval(*this, env, v);
|
e->eval(*this, env, v);
|
||||||
if (v.type != tAttrs)
|
if (v.normalType() != nAttrs)
|
||||||
throwTypeError("value is %1% while a set was expected", v);
|
throwTypeError("value is %1% while a set was expected", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1066,7 +1066,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
Value nameVal;
|
Value nameVal;
|
||||||
i.nameExpr->eval(state, *dynamicEnv, nameVal);
|
i.nameExpr->eval(state, *dynamicEnv, nameVal);
|
||||||
state.forceValue(nameVal, i.pos);
|
state.forceValue(nameVal, i.pos);
|
||||||
if (nameVal.type == tNull)
|
if (nameVal.normalType() == nNull)
|
||||||
continue;
|
continue;
|
||||||
state.forceStringNoCtx(nameVal);
|
state.forceStringNoCtx(nameVal);
|
||||||
Symbol nameSym = state.symbols.create(nameVal.string.s);
|
Symbol nameSym = state.symbols.create(nameVal.string.s);
|
||||||
|
@ -1151,7 +1151,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
Symbol name = getName(i, state, env);
|
Symbol name = getName(i, state, env);
|
||||||
if (def) {
|
if (def) {
|
||||||
state.forceValue(*vAttrs, pos);
|
state.forceValue(*vAttrs, pos);
|
||||||
if (vAttrs->type != tAttrs ||
|
if (vAttrs->normalType() != nAttrs ||
|
||||||
(j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
|
(j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
|
||||||
{
|
{
|
||||||
def->eval(state, env, v);
|
def->eval(state, env, v);
|
||||||
|
@ -1191,7 +1191,7 @@ void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
||||||
state.forceValue(*vAttrs);
|
state.forceValue(*vAttrs);
|
||||||
Bindings::iterator j;
|
Bindings::iterator j;
|
||||||
Symbol name = getName(i, state, env);
|
Symbol name = getName(i, state, env);
|
||||||
if (vAttrs->type != tAttrs ||
|
if (vAttrs->normalType() != nAttrs ||
|
||||||
(j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
|
(j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
|
||||||
{
|
{
|
||||||
mkBool(v, false);
|
mkBool(v, false);
|
||||||
|
@ -1269,7 +1269,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fun.type == tAttrs) {
|
if (fun.normalType() == nAttrs) {
|
||||||
auto found = fun.attrs->find(sFunctor);
|
auto found = fun.attrs->find(sFunctor);
|
||||||
if (found != fun.attrs->end()) {
|
if (found != fun.attrs->end()) {
|
||||||
/* fun may be allocated on the stack of the calling function,
|
/* fun may be allocated on the stack of the calling function,
|
||||||
|
@ -1368,7 +1368,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
||||||
{
|
{
|
||||||
forceValue(fun);
|
forceValue(fun);
|
||||||
|
|
||||||
if (fun.type == tAttrs) {
|
if (fun.normalType() == nAttrs) {
|
||||||
auto found = fun.attrs->find(sFunctor);
|
auto found = fun.attrs->find(sFunctor);
|
||||||
if (found != fun.attrs->end()) {
|
if (found != fun.attrs->end()) {
|
||||||
Value * v = allocValue();
|
Value * v = allocValue();
|
||||||
|
@ -1562,7 +1562,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
NixFloat nf = 0;
|
NixFloat nf = 0;
|
||||||
|
|
||||||
bool first = !forceString;
|
bool first = !forceString;
|
||||||
ValueType firstType = tString;
|
NormalType firstType = nString;
|
||||||
|
|
||||||
for (auto & i : *es) {
|
for (auto & i : *es) {
|
||||||
Value vTmp;
|
Value vTmp;
|
||||||
|
@ -1573,36 +1573,36 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
since paths are copied when they are used in a derivation),
|
since paths are copied when they are used in a derivation),
|
||||||
and none of the strings are allowed to have contexts. */
|
and none of the strings are allowed to have contexts. */
|
||||||
if (first) {
|
if (first) {
|
||||||
firstType = vTmp.type;
|
firstType = vTmp.normalType();
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstType == tInt) {
|
if (firstType == nInt) {
|
||||||
if (vTmp.type == tInt) {
|
if (vTmp.normalType() == nInt) {
|
||||||
n += vTmp.integer;
|
n += vTmp.integer;
|
||||||
} else if (vTmp.type == tFloat) {
|
} else if (vTmp.normalType() == nFloat) {
|
||||||
// Upgrade the type from int to float;
|
// Upgrade the type from int to float;
|
||||||
firstType = tFloat;
|
firstType = nFloat;
|
||||||
nf = n;
|
nf = n;
|
||||||
nf += vTmp.fpoint;
|
nf += vTmp.fpoint;
|
||||||
} else
|
} else
|
||||||
throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp));
|
throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp));
|
||||||
} else if (firstType == tFloat) {
|
} else if (firstType == nFloat) {
|
||||||
if (vTmp.type == tInt) {
|
if (vTmp.normalType() == nInt) {
|
||||||
nf += vTmp.integer;
|
nf += vTmp.integer;
|
||||||
} else if (vTmp.type == tFloat) {
|
} else if (vTmp.normalType() == nFloat) {
|
||||||
nf += vTmp.fpoint;
|
nf += vTmp.fpoint;
|
||||||
} else
|
} else
|
||||||
throwEvalError(pos, "cannot add %1% to a float", showType(vTmp));
|
throwEvalError(pos, "cannot add %1% to a float", showType(vTmp));
|
||||||
} else
|
} else
|
||||||
s << state.coerceToString(pos, vTmp, context, false, firstType == tString);
|
s << state.coerceToString(pos, vTmp, context, false, firstType == nString);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstType == tInt)
|
if (firstType == nInt)
|
||||||
mkInt(v, n);
|
mkInt(v, n);
|
||||||
else if (firstType == tFloat)
|
else if (firstType == nFloat)
|
||||||
mkFloat(v, nf);
|
mkFloat(v, nf);
|
||||||
else if (firstType == tPath) {
|
else if (firstType == nPath) {
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
throwEvalError(pos, "a string that refers to a store path cannot be appended to a path");
|
throwEvalError(pos, "a string that refers to a store path cannot be appended to a path");
|
||||||
auto path = canonPath(s.str());
|
auto path = canonPath(s.str());
|
||||||
|
@ -1629,7 +1629,7 @@ void EvalState::forceValueDeep(Value & v)
|
||||||
|
|
||||||
forceValue(v);
|
forceValue(v);
|
||||||
|
|
||||||
if (v.type == tAttrs) {
|
if (v.normalType() == nAttrs) {
|
||||||
for (auto & i : *v.attrs)
|
for (auto & i : *v.attrs)
|
||||||
try {
|
try {
|
||||||
recurse(*i.value);
|
recurse(*i.value);
|
||||||
|
@ -1652,7 +1652,7 @@ void EvalState::forceValueDeep(Value & v)
|
||||||
NixInt EvalState::forceInt(Value & v, const Pos & pos)
|
NixInt EvalState::forceInt(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type != tInt)
|
if (v.normalType() != nInt)
|
||||||
throwTypeError(pos, "value is %1% while an integer was expected", v);
|
throwTypeError(pos, "value is %1% while an integer was expected", v);
|
||||||
return v.integer;
|
return v.integer;
|
||||||
}
|
}
|
||||||
|
@ -1661,9 +1661,9 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos)
|
||||||
NixFloat EvalState::forceFloat(Value & v, const Pos & pos)
|
NixFloat EvalState::forceFloat(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type == tInt)
|
if (v.normalType() == nInt)
|
||||||
return v.integer;
|
return v.integer;
|
||||||
else if (v.type != tFloat)
|
else if (v.normalType() != nFloat)
|
||||||
throwTypeError(pos, "value is %1% while a float was expected", v);
|
throwTypeError(pos, "value is %1% while a float was expected", v);
|
||||||
return v.fpoint;
|
return v.fpoint;
|
||||||
}
|
}
|
||||||
|
@ -1672,7 +1672,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos)
|
||||||
bool EvalState::forceBool(Value & v, const Pos & pos)
|
bool EvalState::forceBool(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type != tBool)
|
if (v.normalType() != nBool)
|
||||||
throwTypeError(pos, "value is %1% while a Boolean was expected", v);
|
throwTypeError(pos, "value is %1% while a Boolean was expected", v);
|
||||||
return v.boolean;
|
return v.boolean;
|
||||||
}
|
}
|
||||||
|
@ -1680,14 +1680,14 @@ bool EvalState::forceBool(Value & v, const Pos & pos)
|
||||||
|
|
||||||
bool EvalState::isFunctor(Value & fun)
|
bool EvalState::isFunctor(Value & fun)
|
||||||
{
|
{
|
||||||
return fun.type == tAttrs && fun.attrs->find(sFunctor) != fun.attrs->end();
|
return fun.normalType() == nAttrs && fun.attrs->find(sFunctor) != fun.attrs->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::forceFunction(Value & v, const Pos & pos)
|
void EvalState::forceFunction(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type != tLambda && v.type != tPrimOp && v.type != tPrimOpApp && !isFunctor(v))
|
if (v.normalType() != nFunction && !isFunctor(v))
|
||||||
throwTypeError(pos, "value is %1% while a function was expected", v);
|
throwTypeError(pos, "value is %1% while a function was expected", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1695,7 +1695,7 @@ void EvalState::forceFunction(Value & v, const Pos & pos)
|
||||||
string EvalState::forceString(Value & v, const Pos & pos)
|
string EvalState::forceString(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type != tString) {
|
if (v.normalType() != nString) {
|
||||||
if (pos)
|
if (pos)
|
||||||
throwTypeError(pos, "value is %1% while a string was expected", v);
|
throwTypeError(pos, "value is %1% while a string was expected", v);
|
||||||
else
|
else
|
||||||
|
@ -1761,11 +1761,11 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos)
|
||||||
|
|
||||||
bool EvalState::isDerivation(Value & v)
|
bool EvalState::isDerivation(Value & v)
|
||||||
{
|
{
|
||||||
if (v.type != tAttrs) return false;
|
if (v.normalType() != nAttrs) return false;
|
||||||
Bindings::iterator i = v.attrs->find(sType);
|
Bindings::iterator i = v.attrs->find(sType);
|
||||||
if (i == v.attrs->end()) return false;
|
if (i == v.attrs->end()) return false;
|
||||||
forceValue(*i->value);
|
forceValue(*i->value);
|
||||||
if (i->value->type != tString) return false;
|
if (i->value->normalType() != nString) return false;
|
||||||
return strcmp(i->value->string.s, "derivation") == 0;
|
return strcmp(i->value->string.s, "derivation") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1790,17 +1790,17 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
|
||||||
|
|
||||||
string s;
|
string s;
|
||||||
|
|
||||||
if (v.type == tString) {
|
if (v.normalType() == nString) {
|
||||||
copyContext(v, context);
|
copyContext(v, context);
|
||||||
return v.string.s;
|
return v.string.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.type == tPath) {
|
if (v.normalType() == nPath) {
|
||||||
Path path(canonPath(v.path));
|
Path path(canonPath(v.path));
|
||||||
return copyToStore ? copyPathToStore(context, path) : path;
|
return copyToStore ? copyPathToStore(context, path) : path;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.type == tAttrs) {
|
if (v.normalType() == nAttrs) {
|
||||||
auto maybeString = tryAttrsToString(pos, v, context, coerceMore, copyToStore);
|
auto maybeString = tryAttrsToString(pos, v, context, coerceMore, copyToStore);
|
||||||
if (maybeString) {
|
if (maybeString) {
|
||||||
return *maybeString;
|
return *maybeString;
|
||||||
|
@ -1810,18 +1810,18 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
|
||||||
return coerceToString(pos, *i->value, context, coerceMore, copyToStore);
|
return coerceToString(pos, *i->value, context, coerceMore, copyToStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.type == tExternal)
|
if (v.normalType() == nExternal)
|
||||||
return v.external->coerceToString(pos, context, coerceMore, copyToStore);
|
return v.external->coerceToString(pos, context, coerceMore, copyToStore);
|
||||||
|
|
||||||
if (coerceMore) {
|
if (coerceMore) {
|
||||||
|
|
||||||
/* Note that `false' is represented as an empty string for
|
/* Note that `false' is represented as an empty string for
|
||||||
shell scripting convenience, just like `null'. */
|
shell scripting convenience, just like `null'. */
|
||||||
if (v.type == tBool && v.boolean) return "1";
|
if (v.normalType() == nBool && v.boolean) return "1";
|
||||||
if (v.type == tBool && !v.boolean) return "";
|
if (v.normalType() == nBool && !v.boolean) return "";
|
||||||
if (v.type == tInt) return std::to_string(v.integer);
|
if (v.normalType() == nInt) return std::to_string(v.integer);
|
||||||
if (v.type == tFloat) return std::to_string(v.fpoint);
|
if (v.normalType() == nFloat) return std::to_string(v.fpoint);
|
||||||
if (v.type == tNull) return "";
|
if (v.normalType() == nNull) return "";
|
||||||
|
|
||||||
if (v.isList()) {
|
if (v.isList()) {
|
||||||
string result;
|
string result;
|
||||||
|
@ -1884,40 +1884,38 @@ bool EvalState::eqValues(Value & v1, Value & v2)
|
||||||
if (&v1 == &v2) return true;
|
if (&v1 == &v2) return true;
|
||||||
|
|
||||||
// Special case type-compatibility between float and int
|
// Special case type-compatibility between float and int
|
||||||
if (v1.type == tInt && v2.type == tFloat)
|
if (v1.normalType() == nInt && v2.normalType() == nFloat)
|
||||||
return v1.integer == v2.fpoint;
|
return v1.integer == v2.fpoint;
|
||||||
if (v1.type == tFloat && v2.type == tInt)
|
if (v1.normalType() == nFloat && v2.normalType() == nInt)
|
||||||
return v1.fpoint == v2.integer;
|
return v1.fpoint == v2.integer;
|
||||||
|
|
||||||
// All other types are not compatible with each other.
|
// All other types are not compatible with each other.
|
||||||
if (v1.type != v2.type) return false;
|
if (v1.normalType() != v2.normalType()) return false;
|
||||||
|
|
||||||
switch (v1.type) {
|
switch (v1.normalType()) {
|
||||||
|
|
||||||
case tInt:
|
case nInt:
|
||||||
return v1.integer == v2.integer;
|
return v1.integer == v2.integer;
|
||||||
|
|
||||||
case tBool:
|
case nBool:
|
||||||
return v1.boolean == v2.boolean;
|
return v1.boolean == v2.boolean;
|
||||||
|
|
||||||
case tString:
|
case nString:
|
||||||
return strcmp(v1.string.s, v2.string.s) == 0;
|
return strcmp(v1.string.s, v2.string.s) == 0;
|
||||||
|
|
||||||
case tPath:
|
case nPath:
|
||||||
return strcmp(v1.path, v2.path) == 0;
|
return strcmp(v1.path, v2.path) == 0;
|
||||||
|
|
||||||
case tNull:
|
case nNull:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case tList1:
|
case nList:
|
||||||
case tList2:
|
|
||||||
case tListN:
|
|
||||||
if (v1.listSize() != v2.listSize()) return false;
|
if (v1.listSize() != v2.listSize()) return false;
|
||||||
for (size_t n = 0; n < v1.listSize(); ++n)
|
for (size_t n = 0; n < v1.listSize(); ++n)
|
||||||
if (!eqValues(*v1.listElems()[n], *v2.listElems()[n])) return false;
|
if (!eqValues(*v1.listElems()[n], *v2.listElems()[n])) return false;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case tAttrs: {
|
case nAttrs: {
|
||||||
/* If both sets denote a derivation (type = "derivation"),
|
/* If both sets denote a derivation (type = "derivation"),
|
||||||
then compare their outPaths. */
|
then compare their outPaths. */
|
||||||
if (isDerivation(v1) && isDerivation(v2)) {
|
if (isDerivation(v1) && isDerivation(v2)) {
|
||||||
|
@ -1939,15 +1937,13 @@ bool EvalState::eqValues(Value & v1, Value & v2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Functions are incomparable. */
|
/* Functions are incomparable. */
|
||||||
case tLambda:
|
case nFunction:
|
||||||
case tPrimOp:
|
|
||||||
case tPrimOpApp:
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case tExternal:
|
case nExternal:
|
||||||
return *v1.external == *v2.external;
|
return *v1.external == *v2.external;
|
||||||
|
|
||||||
case tFloat:
|
case nFloat:
|
||||||
return v1.fpoint == v2.fpoint;
|
return v1.fpoint == v2.fpoint;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -120,7 +120,7 @@ static FlakeInput parseFlakeInput(EvalState & state,
|
||||||
expectType(state, nString, *attr.value, *attr.pos);
|
expectType(state, nString, *attr.value, *attr.pos);
|
||||||
input.follows = parseInputPath(attr.value->string.s);
|
input.follows = parseInputPath(attr.value->string.s);
|
||||||
} else {
|
} else {
|
||||||
if (attr.value->type == tString)
|
if (attr.value->normalType() == nString)
|
||||||
attrs.emplace(attr.name, attr.value->string.s);
|
attrs.emplace(attr.name, attr.value->string.s);
|
||||||
else
|
else
|
||||||
throw TypeError("flake input attribute '%s' is %s while a string is expected",
|
throw TypeError("flake input attribute '%s' is %s while a string is expected",
|
||||||
|
@ -235,17 +235,17 @@ static Flake getFlake(
|
||||||
|
|
||||||
for (auto & setting : *nixConfig->value->attrs) {
|
for (auto & setting : *nixConfig->value->attrs) {
|
||||||
forceTrivialValue(state, *setting.value, *setting.pos);
|
forceTrivialValue(state, *setting.value, *setting.pos);
|
||||||
if (setting.value->type == tString)
|
if (setting.value->normalType() == nString)
|
||||||
flake.config.settings.insert({setting.name, state.forceStringNoCtx(*setting.value, *setting.pos)});
|
flake.config.settings.insert({setting.name, state.forceStringNoCtx(*setting.value, *setting.pos)});
|
||||||
else if (setting.value->type == tInt)
|
else if (setting.value->normalType() == nInt)
|
||||||
flake.config.settings.insert({setting.name, state.forceInt(*setting.value, *setting.pos)});
|
flake.config.settings.insert({setting.name, state.forceInt(*setting.value, *setting.pos)});
|
||||||
else if (setting.value->type == tBool)
|
else if (setting.value->normalType() == nBool)
|
||||||
flake.config.settings.insert({setting.name, state.forceBool(*setting.value, *setting.pos)});
|
flake.config.settings.insert({setting.name, state.forceBool(*setting.value, *setting.pos)});
|
||||||
else if (setting.value->isList()) {
|
else if (setting.value->normalType() == nList) {
|
||||||
std::vector<std::string> ss;
|
std::vector<std::string> ss;
|
||||||
for (unsigned int n = 0; n < setting.value->listSize(); ++n) {
|
for (unsigned int n = 0; n < setting.value->listSize(); ++n) {
|
||||||
auto elem = setting.value->listElems()[n];
|
auto elem = setting.value->listElems()[n];
|
||||||
if (elem->type != tString)
|
if (elem->normalType() != nString)
|
||||||
throw TypeError("list element in flake configuration setting '%s' is %s while a string is expected",
|
throw TypeError("list element in flake configuration setting '%s' is %s while a string is expected",
|
||||||
setting.name, showType(*setting.value));
|
setting.name, showType(*setting.value));
|
||||||
ss.push_back(state.forceStringNoCtx(*elem, *setting.pos));
|
ss.push_back(state.forceStringNoCtx(*elem, *setting.pos));
|
||||||
|
|
|
@ -128,7 +128,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
|
||||||
if (!outTI->isList()) throw errMsg;
|
if (!outTI->isList()) throw errMsg;
|
||||||
Outputs result;
|
Outputs result;
|
||||||
for (auto i = outTI->listElems(); i != outTI->listElems() + outTI->listSize(); ++i) {
|
for (auto i = outTI->listElems(); i != outTI->listElems() + outTI->listSize(); ++i) {
|
||||||
if ((*i)->type != tString) throw errMsg;
|
if ((*i)->normalType() != nString) throw errMsg;
|
||||||
auto out = outputs.find((*i)->string.s);
|
auto out = outputs.find((*i)->string.s);
|
||||||
if (out == outputs.end()) throw errMsg;
|
if (out == outputs.end()) throw errMsg;
|
||||||
result.insert(*out);
|
result.insert(*out);
|
||||||
|
@ -172,20 +172,20 @@ StringSet DrvInfo::queryMetaNames()
|
||||||
bool DrvInfo::checkMeta(Value & v)
|
bool DrvInfo::checkMeta(Value & v)
|
||||||
{
|
{
|
||||||
state->forceValue(v);
|
state->forceValue(v);
|
||||||
if (v.isList()) {
|
if (v.normalType() == nList) {
|
||||||
for (unsigned int n = 0; n < v.listSize(); ++n)
|
for (unsigned int n = 0; n < v.listSize(); ++n)
|
||||||
if (!checkMeta(*v.listElems()[n])) return false;
|
if (!checkMeta(*v.listElems()[n])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (v.type == tAttrs) {
|
else if (v.normalType() == nAttrs) {
|
||||||
Bindings::iterator i = v.attrs->find(state->sOutPath);
|
Bindings::iterator i = v.attrs->find(state->sOutPath);
|
||||||
if (i != v.attrs->end()) return false;
|
if (i != v.attrs->end()) return false;
|
||||||
for (auto & i : *v.attrs)
|
for (auto & i : *v.attrs)
|
||||||
if (!checkMeta(*i.value)) return false;
|
if (!checkMeta(*i.value)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return v.type == tInt || v.type == tBool || v.type == tString ||
|
else return v.normalType() == nInt || v.normalType() == nBool || v.normalType() == nString ||
|
||||||
v.type == tFloat;
|
v.normalType() == nFloat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ Value * DrvInfo::queryMeta(const string & name)
|
||||||
string DrvInfo::queryMetaString(const string & name)
|
string DrvInfo::queryMetaString(const string & name)
|
||||||
{
|
{
|
||||||
Value * v = queryMeta(name);
|
Value * v = queryMeta(name);
|
||||||
if (!v || v->type != tString) return "";
|
if (!v || v->normalType() != nString) return "";
|
||||||
return v->string.s;
|
return v->string.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,8 +210,8 @@ NixInt DrvInfo::queryMetaInt(const string & name, NixInt def)
|
||||||
{
|
{
|
||||||
Value * v = queryMeta(name);
|
Value * v = queryMeta(name);
|
||||||
if (!v) return def;
|
if (!v) return def;
|
||||||
if (v->type == tInt) return v->integer;
|
if (v->normalType() == nInt) return v->integer;
|
||||||
if (v->type == tString) {
|
if (v->normalType() == nString) {
|
||||||
/* Backwards compatibility with before we had support for
|
/* Backwards compatibility with before we had support for
|
||||||
integer meta fields. */
|
integer meta fields. */
|
||||||
NixInt n;
|
NixInt n;
|
||||||
|
@ -224,8 +224,8 @@ NixFloat DrvInfo::queryMetaFloat(const string & name, NixFloat def)
|
||||||
{
|
{
|
||||||
Value * v = queryMeta(name);
|
Value * v = queryMeta(name);
|
||||||
if (!v) return def;
|
if (!v) return def;
|
||||||
if (v->type == tFloat) return v->fpoint;
|
if (v->normalType() == nFloat) return v->fpoint;
|
||||||
if (v->type == tString) {
|
if (v->normalType() == nString) {
|
||||||
/* Backwards compatibility with before we had support for
|
/* Backwards compatibility with before we had support for
|
||||||
float meta fields. */
|
float meta fields. */
|
||||||
NixFloat n;
|
NixFloat n;
|
||||||
|
@ -239,8 +239,8 @@ bool DrvInfo::queryMetaBool(const string & name, bool def)
|
||||||
{
|
{
|
||||||
Value * v = queryMeta(name);
|
Value * v = queryMeta(name);
|
||||||
if (!v) return def;
|
if (!v) return def;
|
||||||
if (v->type == tBool) return v->boolean;
|
if (v->normalType() == nBool) return v->boolean;
|
||||||
if (v->type == tString) {
|
if (v->normalType() == nString) {
|
||||||
/* Backwards compatibility with before we had support for
|
/* Backwards compatibility with before we had support for
|
||||||
Boolean meta fields. */
|
Boolean meta fields. */
|
||||||
if (strcmp(v->string.s, "true") == 0) return true;
|
if (strcmp(v->string.s, "true") == 0) return true;
|
||||||
|
@ -331,7 +331,7 @@ static void getDerivations(EvalState & state, Value & vIn,
|
||||||
/* Process the expression. */
|
/* Process the expression. */
|
||||||
if (!getDerivation(state, v, pathPrefix, drvs, done, ignoreAssertionFailures)) ;
|
if (!getDerivation(state, v, pathPrefix, drvs, done, ignoreAssertionFailures)) ;
|
||||||
|
|
||||||
else if (v.type == tAttrs) {
|
else if (v.normalType() == nAttrs) {
|
||||||
|
|
||||||
/* !!! undocumented hackery to support combining channels in
|
/* !!! undocumented hackery to support combining channels in
|
||||||
nix-env.cc. */
|
nix-env.cc. */
|
||||||
|
@ -353,7 +353,7 @@ static void getDerivations(EvalState & state, Value & vIn,
|
||||||
/* If the value of this attribute is itself a set,
|
/* If the value of this attribute is itself a set,
|
||||||
should we recurse into it? => Only if it has a
|
should we recurse into it? => Only if it has a
|
||||||
`recurseForDerivations = true' attribute. */
|
`recurseForDerivations = true' attribute. */
|
||||||
if (i->value->type == tAttrs) {
|
if (i->value->normalType() == nAttrs) {
|
||||||
Bindings::iterator j = i->value->attrs->find(state.sRecurseForDerivations);
|
Bindings::iterator j = i->value->attrs->find(state.sRecurseForDerivations);
|
||||||
if (j != i->value->attrs->end() && state.forceBool(*j->value, *j->pos))
|
if (j != i->value->attrs->end() && state.forceBool(*j->value, *j->pos))
|
||||||
getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures);
|
getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures);
|
||||||
|
@ -362,7 +362,7 @@ static void getDerivations(EvalState & state, Value & vIn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (v.isList()) {
|
else if (v.normalType() == nList) {
|
||||||
for (unsigned int n = 0; n < v.listSize(); ++n) {
|
for (unsigned int n = 0; n < v.listSize(); ++n) {
|
||||||
string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
|
string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
|
||||||
if (getDerivation(state, *v.listElems()[n], pathPrefix2, drvs, done, ignoreAssertionFailures))
|
if (getDerivation(state, *v.listElems()[n], pathPrefix2, drvs, done, ignoreAssertionFailures))
|
||||||
|
|
|
@ -356,24 +356,20 @@ static void prim_typeOf(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
string t;
|
string t;
|
||||||
switch (args[0]->type) {
|
switch (args[0]->normalType()) {
|
||||||
case tInt: t = "int"; break;
|
case nInt: t = "int"; break;
|
||||||
case tBool: t = "bool"; break;
|
case nBool: t = "bool"; break;
|
||||||
case tString: t = "string"; break;
|
case nString: t = "string"; break;
|
||||||
case tPath: t = "path"; break;
|
case nPath: t = "path"; break;
|
||||||
case tNull: t = "null"; break;
|
case nNull: t = "null"; break;
|
||||||
case tAttrs: t = "set"; break;
|
case nAttrs: t = "set"; break;
|
||||||
case tList1: case tList2: case tListN: t = "list"; break;
|
case nList: t = "list"; break;
|
||||||
case tLambda:
|
case nFunction: t = "lambda"; break;
|
||||||
case tPrimOp:
|
case nExternal:
|
||||||
case tPrimOpApp:
|
|
||||||
t = "lambda";
|
|
||||||
break;
|
|
||||||
case tExternal:
|
|
||||||
t = args[0]->external->typeOf();
|
t = args[0]->external->typeOf();
|
||||||
break;
|
break;
|
||||||
case tFloat: t = "float"; break;
|
case nFloat: t = "float"; break;
|
||||||
default: abort();
|
case nThunk: abort();
|
||||||
}
|
}
|
||||||
mkString(v, state.symbols.create(t));
|
mkString(v, state.symbols.create(t));
|
||||||
}
|
}
|
||||||
|
@ -393,7 +389,7 @@ static RegisterPrimOp primop_typeOf({
|
||||||
static void prim_isNull(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isNull(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tNull);
|
mkBool(v, args[0]->normalType() == nNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_isNull({
|
static RegisterPrimOp primop_isNull({
|
||||||
|
@ -413,18 +409,7 @@ static RegisterPrimOp primop_isNull({
|
||||||
static void prim_isFunction(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isFunction(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
bool res;
|
mkBool(v, args[0]->normalType() == nFunction);
|
||||||
switch (args[0]->type) {
|
|
||||||
case tLambda:
|
|
||||||
case tPrimOp:
|
|
||||||
case tPrimOpApp:
|
|
||||||
res = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mkBool(v, res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_isFunction({
|
static RegisterPrimOp primop_isFunction({
|
||||||
|
@ -440,7 +425,7 @@ static RegisterPrimOp primop_isFunction({
|
||||||
static void prim_isInt(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isInt(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tInt);
|
mkBool(v, args[0]->normalType() == nInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_isInt({
|
static RegisterPrimOp primop_isInt({
|
||||||
|
@ -456,7 +441,7 @@ static RegisterPrimOp primop_isInt({
|
||||||
static void prim_isFloat(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isFloat(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tFloat);
|
mkBool(v, args[0]->normalType() == nFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_isFloat({
|
static RegisterPrimOp primop_isFloat({
|
||||||
|
@ -472,7 +457,7 @@ static RegisterPrimOp primop_isFloat({
|
||||||
static void prim_isString(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isString(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tString);
|
mkBool(v, args[0]->normalType() == nString);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_isString({
|
static RegisterPrimOp primop_isString({
|
||||||
|
@ -488,7 +473,7 @@ static RegisterPrimOp primop_isString({
|
||||||
static void prim_isBool(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isBool(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tBool);
|
mkBool(v, args[0]->normalType() == nBool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_isBool({
|
static RegisterPrimOp primop_isBool({
|
||||||
|
@ -504,7 +489,7 @@ static RegisterPrimOp primop_isBool({
|
||||||
static void prim_isPath(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isPath(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tPath);
|
mkBool(v, args[0]->normalType() == nPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_isPath({
|
static RegisterPrimOp primop_isPath({
|
||||||
|
@ -520,20 +505,20 @@ struct CompareValues
|
||||||
{
|
{
|
||||||
bool operator () (const Value * v1, const Value * v2) const
|
bool operator () (const Value * v1, const Value * v2) const
|
||||||
{
|
{
|
||||||
if (v1->type == tFloat && v2->type == tInt)
|
if (v1->normalType() == nFloat && v2->normalType() == nInt)
|
||||||
return v1->fpoint < v2->integer;
|
return v1->fpoint < v2->integer;
|
||||||
if (v1->type == tInt && v2->type == tFloat)
|
if (v1->normalType() == nInt && v2->normalType() == nFloat)
|
||||||
return v1->integer < v2->fpoint;
|
return v1->integer < v2->fpoint;
|
||||||
if (v1->type != v2->type)
|
if (v1->normalType() != v2->normalType())
|
||||||
throw EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
throw EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
||||||
switch (v1->type) {
|
switch (v1->normalType()) {
|
||||||
case tInt:
|
case nInt:
|
||||||
return v1->integer < v2->integer;
|
return v1->integer < v2->integer;
|
||||||
case tFloat:
|
case nFloat:
|
||||||
return v1->fpoint < v2->fpoint;
|
return v1->fpoint < v2->fpoint;
|
||||||
case tString:
|
case nString:
|
||||||
return strcmp(v1->string.s, v2->string.s) < 0;
|
return strcmp(v1->string.s, v2->string.s) < 0;
|
||||||
case tPath:
|
case nPath:
|
||||||
return strcmp(v1->path, v2->path) < 0;
|
return strcmp(v1->path, v2->path) < 0;
|
||||||
default:
|
default:
|
||||||
throw EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
throw EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2));
|
||||||
|
@ -777,7 +762,7 @@ static RegisterPrimOp primop_deepSeq({
|
||||||
static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->type == tString)
|
if (args[0]->normalType() == nString)
|
||||||
printError("trace: %1%", args[0]->string.s);
|
printError("trace: %1%", args[0]->string.s);
|
||||||
else
|
else
|
||||||
printError("trace: %1%", *args[0]);
|
printError("trace: %1%", *args[0]);
|
||||||
|
@ -902,7 +887,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
|
|
||||||
if (ignoreNulls) {
|
if (ignoreNulls) {
|
||||||
state.forceValue(*i->value, pos);
|
state.forceValue(*i->value, pos);
|
||||||
if (i->value->type == tNull) continue;
|
if (i->value->normalType() == nNull) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i->name == state.sContentAddressed) {
|
if (i->name == state.sContentAddressed) {
|
||||||
|
@ -1308,7 +1293,7 @@ static void prim_dirOf(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path dir = dirOf(state.coerceToString(pos, *args[0], context, false, false));
|
Path dir = dirOf(state.coerceToString(pos, *args[0], context, false, false));
|
||||||
if (args[0]->type == tPath) mkPath(v, dir.c_str()); else mkString(v, dir, context);
|
if (args[0]->normalType() == nPath) mkPath(v, dir.c_str()); else mkString(v, dir, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_dirOf({
|
static RegisterPrimOp primop_dirOf({
|
||||||
|
@ -1808,7 +1793,7 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
||||||
});
|
});
|
||||||
|
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->type != tLambda)
|
if (args[0]->normalType() != nFunction)
|
||||||
throw TypeError({
|
throw TypeError({
|
||||||
.hint = hintfmt(
|
.hint = hintfmt(
|
||||||
"first argument in call to 'filterSource' is not a function but %1%",
|
"first argument in call to 'filterSource' is not a function but %1%",
|
||||||
|
@ -2074,7 +2059,7 @@ static RegisterPrimOp primop_hasAttr({
|
||||||
static void prim_isAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tAttrs);
|
mkBool(v, args[0]->normalType() == nAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_isAttrs({
|
static RegisterPrimOp primop_isAttrs({
|
||||||
|
@ -2337,7 +2322,7 @@ static RegisterPrimOp primop_mapAttrs({
|
||||||
static void prim_isList(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isList(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->isList());
|
mkBool(v, args[0]->normalType() == nList);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_isList({
|
static RegisterPrimOp primop_isList({
|
||||||
|
@ -2831,7 +2816,7 @@ static void prim_add(EvalState & state, const Pos & pos, Value * * args, Value &
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
if (args[0]->type == tFloat || args[1]->type == tFloat)
|
if (args[0]->normalType() == nFloat || args[1]->normalType() == nFloat)
|
||||||
mkFloat(v, state.forceFloat(*args[0], pos) + state.forceFloat(*args[1], pos));
|
mkFloat(v, state.forceFloat(*args[0], pos) + state.forceFloat(*args[1], pos));
|
||||||
else
|
else
|
||||||
mkInt(v, state.forceInt(*args[0], pos) + state.forceInt(*args[1], pos));
|
mkInt(v, state.forceInt(*args[0], pos) + state.forceInt(*args[1], pos));
|
||||||
|
@ -2850,7 +2835,7 @@ static void prim_sub(EvalState & state, const Pos & pos, Value * * args, Value &
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
if (args[0]->type == tFloat || args[1]->type == tFloat)
|
if (args[0]->normalType() == nFloat || args[1]->normalType() == nFloat)
|
||||||
mkFloat(v, state.forceFloat(*args[0], pos) - state.forceFloat(*args[1], pos));
|
mkFloat(v, state.forceFloat(*args[0], pos) - state.forceFloat(*args[1], pos));
|
||||||
else
|
else
|
||||||
mkInt(v, state.forceInt(*args[0], pos) - state.forceInt(*args[1], pos));
|
mkInt(v, state.forceInt(*args[0], pos) - state.forceInt(*args[1], pos));
|
||||||
|
@ -2869,7 +2854,7 @@ static void prim_mul(EvalState & state, const Pos & pos, Value * * args, Value &
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
if (args[0]->type == tFloat || args[1]->type == tFloat)
|
if (args[0]->normalType() == nFloat || args[1]->normalType() == nFloat)
|
||||||
mkFloat(v, state.forceFloat(*args[0], pos) * state.forceFloat(*args[1], pos));
|
mkFloat(v, state.forceFloat(*args[0], pos) * state.forceFloat(*args[1], pos));
|
||||||
else
|
else
|
||||||
mkInt(v, state.forceInt(*args[0], pos) * state.forceInt(*args[1], pos));
|
mkInt(v, state.forceInt(*args[0], pos) * state.forceInt(*args[1], pos));
|
||||||
|
@ -2896,7 +2881,7 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value &
|
||||||
.errPos = pos
|
.errPos = pos
|
||||||
});
|
});
|
||||||
|
|
||||||
if (args[0]->type == tFloat || args[1]->type == tFloat) {
|
if (args[0]->normalType() == nFloat || args[1]->normalType() == nFloat) {
|
||||||
mkFloat(v, state.forceFloat(*args[0], pos) / state.forceFloat(*args[1], pos));
|
mkFloat(v, state.forceFloat(*args[0], pos) / state.forceFloat(*args[1], pos));
|
||||||
} else {
|
} else {
|
||||||
NixInt i1 = state.forceInt(*args[0], pos);
|
NixInt i1 = state.forceInt(*args[0], pos);
|
||||||
|
|
|
@ -17,7 +17,7 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar
|
||||||
|
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0]);
|
||||||
|
|
||||||
if (args[0]->type == tAttrs) {
|
if (args[0]->normalType() == nAttrs) {
|
||||||
|
|
||||||
state.forceAttrs(*args[0], pos);
|
state.forceAttrs(*args[0], pos);
|
||||||
|
|
||||||
|
|
|
@ -85,25 +85,25 @@ static void fetchTree(
|
||||||
|
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0]);
|
||||||
|
|
||||||
if (args[0]->type == tAttrs) {
|
if (args[0]->normalType() == nAttrs) {
|
||||||
state.forceAttrs(*args[0], pos);
|
state.forceAttrs(*args[0], pos);
|
||||||
|
|
||||||
fetchers::Attrs attrs;
|
fetchers::Attrs attrs;
|
||||||
|
|
||||||
for (auto & attr : *args[0]->attrs) {
|
for (auto & attr : *args[0]->attrs) {
|
||||||
state.forceValue(*attr.value);
|
state.forceValue(*attr.value);
|
||||||
if (attr.value->type == tPath || attr.value->type == tString)
|
if (attr.value->normalType() == nPath || attr.value->normalType() == nString)
|
||||||
addURI(
|
addURI(
|
||||||
state,
|
state,
|
||||||
attrs,
|
attrs,
|
||||||
attr.name,
|
attr.name,
|
||||||
state.coerceToString(*attr.pos, *attr.value, context, false, false)
|
state.coerceToString(*attr.pos, *attr.value, context, false, false)
|
||||||
);
|
);
|
||||||
else if (attr.value->type == tString)
|
else if (attr.value->normalType() == nString)
|
||||||
addURI(state, attrs, attr.name, attr.value->string.s);
|
addURI(state, attrs, attr.name, attr.value->string.s);
|
||||||
else if (attr.value->type == tBool)
|
else if (attr.value->normalType() == nBool)
|
||||||
attrs.emplace(attr.name, Explicit<bool>{attr.value->boolean});
|
attrs.emplace(attr.name, Explicit<bool>{attr.value->boolean});
|
||||||
else if (attr.value->type == tInt)
|
else if (attr.value->normalType() == nInt)
|
||||||
attrs.emplace(attr.name, attr.value->integer);
|
attrs.emplace(attr.name, attr.value->integer);
|
||||||
else
|
else
|
||||||
throw TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected",
|
throw TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected",
|
||||||
|
@ -163,7 +163,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
|
||||||
|
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0]);
|
||||||
|
|
||||||
if (args[0]->type == tAttrs) {
|
if (args[0]->normalType() == nAttrs) {
|
||||||
|
|
||||||
state.forceAttrs(*args[0], pos);
|
state.forceAttrs(*args[0], pos);
|
||||||
|
|
||||||
|
|
|
@ -16,30 +16,30 @@ void printValueAsJSON(EvalState & state, bool strict,
|
||||||
|
|
||||||
if (strict) state.forceValue(v);
|
if (strict) state.forceValue(v);
|
||||||
|
|
||||||
switch (v.type) {
|
switch (v.normalType()) {
|
||||||
|
|
||||||
case tInt:
|
case nInt:
|
||||||
out.write(v.integer);
|
out.write(v.integer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tBool:
|
case nBool:
|
||||||
out.write(v.boolean);
|
out.write(v.boolean);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tString:
|
case nString:
|
||||||
copyContext(v, context);
|
copyContext(v, context);
|
||||||
out.write(v.string.s);
|
out.write(v.string.s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tPath:
|
case nPath:
|
||||||
out.write(state.copyPathToStore(context, v.path));
|
out.write(state.copyPathToStore(context, v.path));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tNull:
|
case nNull:
|
||||||
out.write(nullptr);
|
out.write(nullptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tAttrs: {
|
case nAttrs: {
|
||||||
auto maybeString = state.tryAttrsToString(noPos, v, context, false, false);
|
auto maybeString = state.tryAttrsToString(noPos, v, context, false, false);
|
||||||
if (maybeString) {
|
if (maybeString) {
|
||||||
out.write(*maybeString);
|
out.write(*maybeString);
|
||||||
|
@ -61,7 +61,7 @@ void printValueAsJSON(EvalState & state, bool strict,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case tList1: case tList2: case tListN: {
|
case nList: {
|
||||||
auto list(out.list());
|
auto list(out.list());
|
||||||
for (unsigned int n = 0; n < v.listSize(); ++n) {
|
for (unsigned int n = 0; n < v.listSize(); ++n) {
|
||||||
auto placeholder(list.placeholder());
|
auto placeholder(list.placeholder());
|
||||||
|
@ -70,15 +70,18 @@ void printValueAsJSON(EvalState & state, bool strict,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case tExternal:
|
case nExternal:
|
||||||
v.external->printValueAsJSON(state, strict, out, context);
|
v.external->printValueAsJSON(state, strict, out, context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tFloat:
|
case nFloat:
|
||||||
out.write(v.fpoint);
|
out.write(v.fpoint);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case nThunk:
|
||||||
|
throw TypeError("cannot convert %1% to JSON", showType(v));
|
||||||
|
|
||||||
|
case nFunction:
|
||||||
throw TypeError("cannot convert %1% to JSON", showType(v));
|
throw TypeError("cannot convert %1% to JSON", showType(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,31 +58,31 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
|
||||||
|
|
||||||
if (strict) state.forceValue(v);
|
if (strict) state.forceValue(v);
|
||||||
|
|
||||||
switch (v.type) {
|
switch (v.normalType()) {
|
||||||
|
|
||||||
case tInt:
|
case nInt:
|
||||||
doc.writeEmptyElement("int", singletonAttrs("value", (format("%1%") % v.integer).str()));
|
doc.writeEmptyElement("int", singletonAttrs("value", (format("%1%") % v.integer).str()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tBool:
|
case nBool:
|
||||||
doc.writeEmptyElement("bool", singletonAttrs("value", v.boolean ? "true" : "false"));
|
doc.writeEmptyElement("bool", singletonAttrs("value", v.boolean ? "true" : "false"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tString:
|
case nString:
|
||||||
/* !!! show the context? */
|
/* !!! show the context? */
|
||||||
copyContext(v, context);
|
copyContext(v, context);
|
||||||
doc.writeEmptyElement("string", singletonAttrs("value", v.string.s));
|
doc.writeEmptyElement("string", singletonAttrs("value", v.string.s));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tPath:
|
case nPath:
|
||||||
doc.writeEmptyElement("path", singletonAttrs("value", v.path));
|
doc.writeEmptyElement("path", singletonAttrs("value", v.path));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tNull:
|
case nNull:
|
||||||
doc.writeEmptyElement("null");
|
doc.writeEmptyElement("null");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tAttrs:
|
case nAttrs:
|
||||||
if (state.isDerivation(v)) {
|
if (state.isDerivation(v)) {
|
||||||
XMLAttrs xmlAttrs;
|
XMLAttrs xmlAttrs;
|
||||||
|
|
||||||
|
@ -92,14 +92,14 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
|
||||||
a = v.attrs->find(state.sDrvPath);
|
a = v.attrs->find(state.sDrvPath);
|
||||||
if (a != v.attrs->end()) {
|
if (a != v.attrs->end()) {
|
||||||
if (strict) state.forceValue(*a->value);
|
if (strict) state.forceValue(*a->value);
|
||||||
if (a->value->type == tString)
|
if (a->value->normalType() == nString)
|
||||||
xmlAttrs["drvPath"] = drvPath = a->value->string.s;
|
xmlAttrs["drvPath"] = drvPath = a->value->string.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
a = v.attrs->find(state.sOutPath);
|
a = v.attrs->find(state.sOutPath);
|
||||||
if (a != v.attrs->end()) {
|
if (a != v.attrs->end()) {
|
||||||
if (strict) state.forceValue(*a->value);
|
if (strict) state.forceValue(*a->value);
|
||||||
if (a->value->type == tString)
|
if (a->value->normalType() == nString)
|
||||||
xmlAttrs["outPath"] = a->value->string.s;
|
xmlAttrs["outPath"] = a->value->string.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,14 +118,19 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tList1: case tList2: case tListN: {
|
case nList: {
|
||||||
XMLOpenElement _(doc, "list");
|
XMLOpenElement _(doc, "list");
|
||||||
for (unsigned int n = 0; n < v.listSize(); ++n)
|
for (unsigned int n = 0; n < v.listSize(); ++n)
|
||||||
printValueAsXML(state, strict, location, *v.listElems()[n], doc, context, drvsSeen);
|
printValueAsXML(state, strict, location, *v.listElems()[n], doc, context, drvsSeen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case tLambda: {
|
case nFunction: {
|
||||||
|
if (!v.isLambda()) {
|
||||||
|
// FIXME: Serialize primops and primopapps
|
||||||
|
doc.writeEmptyElement("unevaluated");
|
||||||
|
break;
|
||||||
|
}
|
||||||
XMLAttrs xmlAttrs;
|
XMLAttrs xmlAttrs;
|
||||||
if (location) posToXML(xmlAttrs, v.lambda.fun->pos);
|
if (location) posToXML(xmlAttrs, v.lambda.fun->pos);
|
||||||
XMLOpenElement _(doc, "function", xmlAttrs);
|
XMLOpenElement _(doc, "function", xmlAttrs);
|
||||||
|
@ -143,15 +148,15 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case tExternal:
|
case nExternal:
|
||||||
v.external->printValueAsXML(state, strict, location, doc, context, drvsSeen);
|
v.external->printValueAsXML(state, strict, location, doc, context, drvsSeen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tFloat:
|
case nFloat:
|
||||||
doc.writeEmptyElement("float", singletonAttrs("value", (format("%1%") % v.fpoint).str()));
|
doc.writeEmptyElement("float", singletonAttrs("value", (format("%1%") % v.fpoint).str()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case nThunk:
|
||||||
doc.writeEmptyElement("unevaluated");
|
doc.writeEmptyElement("unevaluated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1138,38 +1138,38 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
i.queryName(), j)
|
i.queryName(), j)
|
||||||
});
|
});
|
||||||
else {
|
else {
|
||||||
if (v->type == tString) {
|
if (v->normalType() == nString) {
|
||||||
attrs2["type"] = "string";
|
attrs2["type"] = "string";
|
||||||
attrs2["value"] = v->string.s;
|
attrs2["value"] = v->string.s;
|
||||||
xml.writeEmptyElement("meta", attrs2);
|
xml.writeEmptyElement("meta", attrs2);
|
||||||
} else if (v->type == tInt) {
|
} else if (v->normalType() == nInt) {
|
||||||
attrs2["type"] = "int";
|
attrs2["type"] = "int";
|
||||||
attrs2["value"] = (format("%1%") % v->integer).str();
|
attrs2["value"] = (format("%1%") % v->integer).str();
|
||||||
xml.writeEmptyElement("meta", attrs2);
|
xml.writeEmptyElement("meta", attrs2);
|
||||||
} else if (v->type == tFloat) {
|
} else if (v->normalType() == nFloat) {
|
||||||
attrs2["type"] = "float";
|
attrs2["type"] = "float";
|
||||||
attrs2["value"] = (format("%1%") % v->fpoint).str();
|
attrs2["value"] = (format("%1%") % v->fpoint).str();
|
||||||
xml.writeEmptyElement("meta", attrs2);
|
xml.writeEmptyElement("meta", attrs2);
|
||||||
} else if (v->type == tBool) {
|
} else if (v->normalType() == nBool) {
|
||||||
attrs2["type"] = "bool";
|
attrs2["type"] = "bool";
|
||||||
attrs2["value"] = v->boolean ? "true" : "false";
|
attrs2["value"] = v->boolean ? "true" : "false";
|
||||||
xml.writeEmptyElement("meta", attrs2);
|
xml.writeEmptyElement("meta", attrs2);
|
||||||
} else if (v->isList()) {
|
} else if (v->normalType() == nList) {
|
||||||
attrs2["type"] = "strings";
|
attrs2["type"] = "strings";
|
||||||
XMLOpenElement m(xml, "meta", attrs2);
|
XMLOpenElement m(xml, "meta", attrs2);
|
||||||
for (unsigned int j = 0; j < v->listSize(); ++j) {
|
for (unsigned int j = 0; j < v->listSize(); ++j) {
|
||||||
if (v->listElems()[j]->type != tString) continue;
|
if (v->listElems()[j]->normalType() != nString) continue;
|
||||||
XMLAttrs attrs3;
|
XMLAttrs attrs3;
|
||||||
attrs3["value"] = v->listElems()[j]->string.s;
|
attrs3["value"] = v->listElems()[j]->string.s;
|
||||||
xml.writeEmptyElement("string", attrs3);
|
xml.writeEmptyElement("string", attrs3);
|
||||||
}
|
}
|
||||||
} else if (v->type == tAttrs) {
|
} else if (v->normalType() == nAttrs) {
|
||||||
attrs2["type"] = "strings";
|
attrs2["type"] = "strings";
|
||||||
XMLOpenElement m(xml, "meta", attrs2);
|
XMLOpenElement m(xml, "meta", attrs2);
|
||||||
Bindings & attrs = *v->attrs;
|
Bindings & attrs = *v->attrs;
|
||||||
for (auto &i : attrs) {
|
for (auto &i : attrs) {
|
||||||
Attr & a(*attrs.find(i.name));
|
Attr & a(*attrs.find(i.name));
|
||||||
if(a.value->type != tString) continue;
|
if(a.value->normalType() != nString) continue;
|
||||||
XMLAttrs attrs3;
|
XMLAttrs attrs3;
|
||||||
attrs3["type"] = i.name;
|
attrs3["type"] = i.name;
|
||||||
attrs3["value"] = a.value->string.s;
|
attrs3["value"] = a.value->string.s;
|
||||||
|
|
|
@ -97,10 +97,10 @@ struct CmdEval : MixJSON, InstallableCommand
|
||||||
recurse = [&](Value & v, const Pos & pos, const Path & path)
|
recurse = [&](Value & v, const Pos & pos, const Path & path)
|
||||||
{
|
{
|
||||||
state->forceValue(v);
|
state->forceValue(v);
|
||||||
if (v.type == tString)
|
if (v.normalType() == nString)
|
||||||
// FIXME: disallow strings with contexts?
|
// FIXME: disallow strings with contexts?
|
||||||
writeFile(path, v.string.s);
|
writeFile(path, v.string.s);
|
||||||
else if (v.type == tAttrs) {
|
else if (v.normalType() == nAttrs) {
|
||||||
if (mkdir(path.c_str(), 0777) == -1)
|
if (mkdir(path.c_str(), 0777) == -1)
|
||||||
throw SysError("creating directory '%s'", path);
|
throw SysError("creating directory '%s'", path);
|
||||||
for (auto & attr : *v.attrs)
|
for (auto & attr : *v.attrs)
|
||||||
|
|
|
@ -279,7 +279,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
if (v.type == tLambda) {
|
if (v.type == tLambda) {
|
||||||
if (!v.lambda.fun->matchAttrs || !v.lambda.fun->formals->ellipsis)
|
if (!v.lambda.fun->matchAttrs || !v.lambda.fun->formals->ellipsis)
|
||||||
throw Error("module must match an open attribute set ('{ config, ... }')");
|
throw Error("module must match an open attribute set ('{ config, ... }')");
|
||||||
} else if (v.type == tAttrs) {
|
} else if (v.normalType() == nAttrs) {
|
||||||
for (auto & attr : *v.attrs)
|
for (auto & attr : *v.attrs)
|
||||||
try {
|
try {
|
||||||
state->forceValue(*attr.value, *attr.pos);
|
state->forceValue(*attr.value, *attr.pos);
|
||||||
|
|
|
@ -446,7 +446,7 @@ bool NixRepl::processLine(string line)
|
||||||
|
|
||||||
Pos pos;
|
Pos pos;
|
||||||
|
|
||||||
if (v.type == tPath || v.type == tString) {
|
if (v.normalType() == nPath || v.normalType() == nString) {
|
||||||
PathSet context;
|
PathSet context;
|
||||||
auto filename = state->coerceToString(noPos, v, context);
|
auto filename = state->coerceToString(noPos, v, context);
|
||||||
pos.file = state->symbols.create(filename);
|
pos.file = state->symbols.create(filename);
|
||||||
|
@ -669,31 +669,31 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
|
||||||
|
|
||||||
state->forceValue(v);
|
state->forceValue(v);
|
||||||
|
|
||||||
switch (v.type) {
|
switch (v.normalType()) {
|
||||||
|
|
||||||
case tInt:
|
case nInt:
|
||||||
str << ANSI_CYAN << v.integer << ANSI_NORMAL;
|
str << ANSI_CYAN << v.integer << ANSI_NORMAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tBool:
|
case nBool:
|
||||||
str << ANSI_CYAN << (v.boolean ? "true" : "false") << ANSI_NORMAL;
|
str << ANSI_CYAN << (v.boolean ? "true" : "false") << ANSI_NORMAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tString:
|
case nString:
|
||||||
str << ANSI_YELLOW;
|
str << ANSI_YELLOW;
|
||||||
printStringValue(str, v.string.s);
|
printStringValue(str, v.string.s);
|
||||||
str << ANSI_NORMAL;
|
str << ANSI_NORMAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tPath:
|
case nPath:
|
||||||
str << ANSI_GREEN << v.path << ANSI_NORMAL; // !!! escaping?
|
str << ANSI_GREEN << v.path << ANSI_NORMAL; // !!! escaping?
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tNull:
|
case nNull:
|
||||||
str << ANSI_CYAN "null" ANSI_NORMAL;
|
str << ANSI_CYAN "null" ANSI_NORMAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tAttrs: {
|
case nAttrs: {
|
||||||
seen.insert(&v);
|
seen.insert(&v);
|
||||||
|
|
||||||
bool isDrv = state->isDerivation(v);
|
bool isDrv = state->isDerivation(v);
|
||||||
|
@ -738,9 +738,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case tList1:
|
case nList:
|
||||||
case tList2:
|
|
||||||
case tListN:
|
|
||||||
seen.insert(&v);
|
seen.insert(&v);
|
||||||
|
|
||||||
str << "[ ";
|
str << "[ ";
|
||||||
|
@ -761,22 +759,21 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
|
||||||
str << "]";
|
str << "]";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tLambda: {
|
case nFunction:
|
||||||
std::ostringstream s;
|
if (v.type == tLambda) {
|
||||||
s << v.lambda.fun->pos;
|
std::ostringstream s;
|
||||||
str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL;
|
s << v.lambda.fun->pos;
|
||||||
break;
|
str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL;
|
||||||
}
|
} else if (v.type == tPrimOp) {
|
||||||
|
str << ANSI_MAGENTA "«primop»" ANSI_NORMAL;
|
||||||
case tPrimOp:
|
} else if (v.type == tPrimOpApp) {
|
||||||
str << ANSI_MAGENTA "«primop»" ANSI_NORMAL;
|
str << ANSI_BLUE "«primop-app»" ANSI_NORMAL;
|
||||||
|
} else {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tPrimOpApp:
|
case nFloat:
|
||||||
str << ANSI_BLUE "«primop-app»" ANSI_NORMAL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tFloat:
|
|
||||||
str << v.fpoint;
|
str << v.fpoint;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue