refactor(tvix/eval): Define a single builtin at the top level

Mostly as a proof-of-concept of the new proc-macros for defining
builtins, define a single builtin (the first in the list, `abort`) at
the top-level of a child module within builtins/mod.rs, and add it to
the list of builtins returned from `pure_builtins`.

If this works nicely, we can start breaking out the rest of the builtins
into the top-level too, in addition to introducing additional sets of
builtins (to differentiate between pure and impure builtins).

Change-Id: I5bdd57c57fecf8d63c9fed4fc6b1460f533b20f2
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7199
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
This commit is contained in:
Griffin Smith 2022-11-05 20:59:13 -04:00 committed by grfn
parent 645d0c06e5
commit 43eb4900e0

View file

@ -10,6 +10,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
use std::path::PathBuf;
use std::rc::Rc;
use builtin_macros::builtins;
use regex::Regex;
use crate::warnings::WarningKind;
@ -50,14 +51,21 @@ pub fn coerce_value_to_path(v: &Value, vm: &mut VM) -> Result<PathBuf, ErrorKind
}
}
#[builtins]
mod pure_builtins {
use super::*;
#[builtin("abort")]
fn builtin_abort(_vm: &mut VM, message: Value) -> Result<Value, ErrorKind> {
Err(ErrorKind::Abort(message.to_str()?.to_string()))
}
}
/// Return all pure builtins, that is all builtins that do not rely on
/// I/O outside of the VM and which can be used in any contexts (e.g.
/// WASM).
fn pure_builtins() -> Vec<Builtin> {
vec![
Builtin::new("abort", &[true], |args: Vec<Value>, _: &mut VM| {
Err(ErrorKind::Abort(args[0].to_str()?.to_string()))
}),
let mut bs = vec![
Builtin::new(
"add",
&[false, false],
@ -820,7 +828,10 @@ fn pure_builtins() -> Vec<Builtin> {
let value = args[0].force(vm)?;
Ok(Value::String(value.type_of().into()))
}),
]
];
bs.extend(pure_builtins::builtins());
bs
}
/// Placeholder builtins that technically have a function which we do