about summary refs log tree commit diff
path: root/tvix/eval/src/value/builtin.rs
diff options
context:
space:
mode:
authorGriffin Smith <root@gws.fyi>2022-11-06T15·28-0500
committergrfn <grfn@gws.fyi>2022-11-08T13·42+0000
commita1015ba1d7c2228224847f1931118da473815de3 (patch)
tree2cf2d28f841c3a40ac8f95a5c5e4a3a6797d648f /tvix/eval/src/value/builtin.rs
parentdad07a8bc0369932a7b65efc2dd4181a8863eb5b (diff)
feat(tvix/eval): Give names to builtin arguments r/5268
Refactor the arguments of a Builtin to be a vec of a new BuiltinArgument
struct, which contains the old strictness boolean and also a static
`name` str - this is automatically determined via the ident for the
corresponding function argument in the proc-macro case, and passed in in
the cases where we're still manually calling Builtin::new.

Currently this name is unused, but in the future this can be used as
part of a documentation system for builtins.

Change-Id: Ib9dadb15b69bf8c9ea1983a4f4f197294a2394a6
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7204
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/value/builtin.rs')
-rw-r--r--tvix/eval/src/value/builtin.rs24
1 files changed, 15 insertions, 9 deletions
diff --git a/tvix/eval/src/value/builtin.rs b/tvix/eval/src/value/builtin.rs
index fc8043176211..944efd85eb99 100644
--- a/tvix/eval/src/value/builtin.rs
+++ b/tvix/eval/src/value/builtin.rs
@@ -25,6 +25,14 @@ use std::{
 pub trait BuiltinFn: Fn(Vec<Value>, &mut VM) -> Result<Value, ErrorKind> {}
 impl<F: Fn(Vec<Value>, &mut VM) -> Result<Value, ErrorKind>> BuiltinFn for F {}
 
+/// Description of a single argument passed to a builtin
+pub struct BuiltinArgument {
+    /// Whether the argument should be forced before the underlying builtin function is called
+    pub strict: bool,
+    /// The name of the argument, to be used in docstrings and error messages
+    pub name: &'static str,
+}
+
 /// Represents a single built-in function which directly executes Rust
 /// code that operates on a Nix value.
 ///
@@ -40,10 +48,8 @@ impl<F: Fn(Vec<Value>, &mut VM) -> Result<Value, ErrorKind>> BuiltinFn for F {}
 #[derive(Clone)]
 pub struct Builtin {
     name: &'static str,
-    /// Array reference that describes how many arguments there are (usually 1
-    /// or 2) and whether they need to be forced. `true` causes the
-    /// corresponding argument to be forced before `func` is called.
-    strict_args: &'static [bool],
+    /// Array of arguments to the builtin.
+    arguments: &'static [BuiltinArgument],
     func: Rc<dyn BuiltinFn>,
 
     /// Partially applied function arguments.
@@ -53,12 +59,12 @@ pub struct Builtin {
 impl Builtin {
     pub fn new<F: BuiltinFn + 'static>(
         name: &'static str,
-        strict_args: &'static [bool],
+        arguments: &'static [BuiltinArgument],
         func: F,
     ) -> Self {
         Builtin {
             name,
-            strict_args,
+            arguments,
             func: Rc::new(func),
             partials: vec![],
         }
@@ -74,9 +80,9 @@ impl Builtin {
     pub fn apply(mut self, vm: &mut VM, arg: Value) -> Result<Value, ErrorKind> {
         self.partials.push(arg);
 
-        if self.partials.len() == self.strict_args.len() {
-            for (idx, force) in self.strict_args.iter().enumerate() {
-                if *force {
+        if self.partials.len() == self.arguments.len() {
+            for (idx, BuiltinArgument { strict, .. }) in self.arguments.iter().enumerate() {
+                if *strict {
                     self.partials[idx].force(vm)?;
                 }
             }