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::(reader, mc)?; if val.is::() || val.is::() { return m.return_from_primop(val.relax(), reader); } if let Some(p) = val.downcast::() { 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() ))) } 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::(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) }