mirror of
https://github.com/NixOS/nix
synced 2025-06-26 11:41:15 +02:00
Allow external code using libnixexpr to add types
Code that links to libnixexpr (e.g. plugins loaded with importNative, or nix-exec) may want to provide custom value types and operations on values of those types. For example, nix-exec is currently using sets where a custom IO value type would be more appropriate. This commit provides a generic hook for such types in the form of tExternal and the ExternalBase virtual class, which contains all functions necessary for libnixexpr's type-polymorphic functions (e.g. `showType`) to be implemented.
This commit is contained in:
parent
5f04da905f
commit
320659b0cd
5 changed files with 108 additions and 0 deletions
|
@ -104,6 +104,9 @@ static void printValue(std::ostream & str, std::set<const Value *> & active, con
|
|||
case tPrimOpApp:
|
||||
str << "<PRIMOP-APP>";
|
||||
break;
|
||||
case tExternal:
|
||||
str << *v.external;
|
||||
break;
|
||||
default:
|
||||
throw Error("invalid value");
|
||||
}
|
||||
|
@ -136,6 +139,7 @@ string showType(const Value & v)
|
|||
case tBlackhole: return "a black hole";
|
||||
case tPrimOp: return "a built-in function";
|
||||
case tPrimOpApp: return "a partially applied built-in function";
|
||||
case tExternal: return v.external->showType();
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
@ -1314,6 +1318,9 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
|
|||
return coerceToString(pos, *i->value, context, coerceMore, copyToStore);
|
||||
}
|
||||
|
||||
if (v.type == tExternal)
|
||||
return v.external->coerceToString(pos, context, coerceMore, copyToStore);
|
||||
|
||||
if (coerceMore) {
|
||||
|
||||
/* Note that `false' is represented as an empty string for
|
||||
|
@ -1434,6 +1441,9 @@ bool EvalState::eqValues(Value & v1, Value & v2)
|
|||
case tPrimOpApp:
|
||||
return false;
|
||||
|
||||
case tExternal:
|
||||
return *v1.external == *v2.external;
|
||||
|
||||
default:
|
||||
throwEvalError("cannot compare %1% with %2%", showType(v1), showType(v2));
|
||||
}
|
||||
|
@ -1575,6 +1585,11 @@ size_t valueSize(Value & v)
|
|||
sz += doValue(*v.primOpApp.left);
|
||||
sz += doValue(*v.primOpApp.right);
|
||||
break;
|
||||
case tExternal:
|
||||
if (seen.find(v.external) != seen.end()) break;
|
||||
seen.insert(v.external);
|
||||
sz += v.external->valueSize(seen);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
@ -1601,4 +1616,22 @@ size_t valueSize(Value & v)
|
|||
}
|
||||
|
||||
|
||||
string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore)
|
||||
{
|
||||
throw TypeError(format("cannot coerce %1% to a string, at %2%") %
|
||||
showType() % pos);
|
||||
}
|
||||
|
||||
|
||||
bool ExternalValueBase::operator==(const ExternalValueBase & b)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::ostream & operator << (std::ostream & str, ExternalValueBase & v) {
|
||||
return v.print(str);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue