refactor(tvix/eval): Implement value comparison with a method

Rather than implementing all of the interesting semantics of value
comparison with a macro bound to the VM, implement the bulk of the logic
with a method on Value itself that returns an Ordering, and then use the
macro to implement the comparison against that Ordering. This has no
functional change, but paves the way to implementing lexicographic
comparison of list values, which is supported in the latest version of
upstream nix.

Change-Id: I8af1a020b41577021af5939f5edc160c407d4a9e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7069
Autosubmit: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
This commit is contained in:
Griffin Smith 2022-10-23 13:24:05 -04:00 committed by grfn
parent 7b3bda9e08
commit 5bd0e723c1
3 changed files with 45 additions and 24 deletions

View file

@ -3,7 +3,7 @@
//! See //tvix/eval/docs/builtins.md for a some context on the
//! available builtins in Nix.
use std::cmp;
use std::cmp::{self, Ordering};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::path::PathBuf;
@ -16,7 +16,7 @@ use crate::{
vm::VM,
};
use crate::{arithmetic_op, cmp_op};
use crate::arithmetic_op;
use self::versions::{VersionPart, VersionPartsIter};
@ -407,7 +407,12 @@ fn pure_builtins() -> Vec<Builtin> {
Builtin::new(
"lessThan",
&[false, false],
|args: Vec<Value>, vm: &mut VM| cmp_op!(&*args[0].force(vm)?, &*args[1].force(vm)?, <),
|args: Vec<Value>, vm: &mut VM| {
Ok(Value::Bool(matches!(
args[0].force(vm)?.nix_cmp(&*args[1].force(vm)?)?,
Some(Ordering::Less)
)))
},
),
Builtin::new("listToAttrs", &[true], |args: Vec<Value>, vm: &mut VM| {
let list = args[0].to_list()?;