diff options
Diffstat (limited to 'tvix/eval/src/builtins/mod.rs')
-rw-r--r-- | tvix/eval/src/builtins/mod.rs | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index b5e8bb289b0e..39e29580b4c3 100644 --- a/tvix/eval/src/builtins/mod.rs +++ b/tvix/eval/src/builtins/mod.rs @@ -3,29 +3,66 @@ //! See //tvix/eval/docs/builtins.md for a some context on the //! available builtins in Nix. -use std::collections::HashMap; +use std::{ + collections::{BTreeMap, HashMap}, + rc::Rc, +}; -use crate::value::{Builtin, Value}; +use crate::value::{Builtin, NixAttrs, NixString, Value}; -macro_rules! builtin { - ( $map:ident, $name:literal, $arity:literal, $body:expr ) => { - $map.insert($name, Value::Builtin(Builtin::new($name, $arity, $body))); - }; +fn pure_builtins() -> Vec<Builtin> { + vec![ + Builtin::new("isNull", 1, |args| { + Ok(Value::Bool(matches!(args[0], Value::Null))) + }), + Builtin::new("toString", 1, |args| { + // TODO: toString is actually not the same as Display + Ok(Value::String(format!("{}", args[0]).into())) + }), + ] +} + +fn builtins_set() -> NixAttrs { + let mut map: BTreeMap<NixString, Value> = BTreeMap::new(); + + for builtin in pure_builtins() { + map.insert(builtin.name().into(), Value::Builtin(builtin)); + } + + NixAttrs::from_map(map) } /// Set of Nix builtins that are globally available. pub fn global_builtins() -> HashMap<&'static str, Value> { - let mut globals = HashMap::new(); + let builtins = builtins_set(); + let mut globals: HashMap<&'static str, Value> = HashMap::new(); - builtin!(globals, "isNull", 1, |args| Ok(Value::Bool(matches!( - args[0], - Value::Null - )))); + // known global builtins from the builtins set. + for global in &[ + "abort", + "baseNameOf", + "derivation", + "derivationStrict", + "dirOf", + "fetchGit", + "fetchMercurial", + "fetchTarball", + "fromTOML", + "import", + "isNull", + "map", + "placeholder", + "removeAttrs", + "scopedImport", + "throw", + "toString", + ] { + if let Some(builtin) = builtins.select(global) { + globals.insert(global, builtin.clone()); + } + } - builtin!(globals, "toString", 1, |args| { - // TODO: toString is actually not the same as Display - Ok(Value::String(format!("{}", args[0]).into())) - }); + globals.insert("builtins", Value::Attrs(Rc::new(builtins))); globals } |