56 lines
1.7 KiB
Rust
56 lines
1.7 KiB
Rust
use fix_error::Error;
|
|
use fix_lang::StringId;
|
|
use fix_runtime::{
|
|
BytecodeReader, Machine, MachineExt, NixString, NixType, Path, Step, StrictValue, Value,
|
|
VmRuntimeCtx,
|
|
};
|
|
use gc_arena::Mutation;
|
|
|
|
pub fn to_string<'gc, M: Machine<'gc>>(
|
|
m: &mut M,
|
|
_ctx: &mut impl VmRuntimeCtx,
|
|
reader: &mut BytecodeReader<'_>,
|
|
mc: &Mutation<'gc>,
|
|
) -> Step {
|
|
let val = m.force_and_retry::<StrictValue>(reader, mc)?;
|
|
if val.is::<StringId>() || val.is::<NixString>() {
|
|
return m.return_from_primop(val.relax(), reader);
|
|
}
|
|
if let Some(p) = val.downcast::<Path>() {
|
|
return m.return_from_primop(Value::new(p.0), reader);
|
|
}
|
|
// TODO: derivations / `__toString` / `outPath`,
|
|
// numbers, lists.
|
|
m.finish_err(Error::eval_error(format!(
|
|
"cannot coerce {} to a string",
|
|
val.ty()
|
|
)))
|
|
}
|
|
|
|
#[expect(
|
|
clippy::unreachable,
|
|
reason = "val was forced to WHNF by force_and_retry, so its type is never Thunk here"
|
|
)]
|
|
pub fn type_of<'gc, M: Machine<'gc>>(
|
|
m: &mut M,
|
|
ctx: &mut impl VmRuntimeCtx,
|
|
reader: &mut BytecodeReader<'_>,
|
|
mc: &Mutation<'gc>,
|
|
) -> Step {
|
|
let val = m.force_and_retry::<StrictValue>(reader, mc)?;
|
|
let name: &str = match val.ty() {
|
|
NixType::Int => "int",
|
|
NixType::Float => "float",
|
|
NixType::Bool => "bool",
|
|
NixType::Null => "null",
|
|
NixType::String => "string",
|
|
NixType::Path => "path",
|
|
NixType::AttrSet => "set",
|
|
NixType::List => "list",
|
|
NixType::Closure | NixType::PrimOp | NixType::PrimOpApp => "lambda",
|
|
NixType::Thunk => unreachable!("forced"),
|
|
};
|
|
let sid = ctx.intern_string(name);
|
|
m.return_from_primop(Value::new(sid), reader)
|
|
}
|