diff options
Diffstat (limited to 'tvix/eval')
-rw-r--r-- | tvix/eval/src/builtins/mod.rs | 67 | ||||
-rw-r--r-- | tvix/eval/src/value/attrs.rs | 8 |
2 files changed, 60 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 } diff --git a/tvix/eval/src/value/attrs.rs b/tvix/eval/src/value/attrs.rs index 319f6bdfa9bb..4109691992ca 100644 --- a/tvix/eval/src/value/attrs.rs +++ b/tvix/eval/src/value/attrs.rs @@ -259,6 +259,14 @@ impl NixAttrs { Ok(attrs) } + + /// Construct an attribute set directly from a BTreeMap + /// representation. This is only visible inside of the crate, as + /// it is intended exclusively for use with the construction of + /// global sets for the compiler. + pub(crate) fn from_map(map: BTreeMap<NixString, Value>) -> Self { + NixAttrs(AttrsRep::Map(map)) + } } // In Nix, name/value attribute pairs are frequently constructed from |