feat(tvix/eval): implement builtins.splitVersion

This was fairly easy, thanks to the work already done by Thomas Frank.
However, the implementation is suboptimal because we parse number parts
only to convert them back to strings afterwards. I've chosen to tackle
this problem in the future, since having an (inefficient) implementation
of splitVersion will be helpful for debugging the slight discrepancies
between C++ Nix and Tvix in the case of compareVersions.

Change-Id: Id6ed8eeb77663ff650c8c53ea952875b1fb7ea84
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6688
Autosubmit: sterni <sternenseemann@systemli.org>
Reviewed-by: grfn <grfn@gws.fyi>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
sterni 2022-09-19 10:14:05 +02:00
parent 489395448f
commit 0096939bf6

View file

@ -18,7 +18,7 @@ use crate::{
use crate::arithmetic_op;
use self::versions::VersionPartsIter;
use self::versions::{VersionPart, VersionPartsIter};
pub mod versions;
@ -213,6 +213,21 @@ fn pure_builtins() -> Vec<Builtin> {
let a = args.pop().unwrap();
arithmetic_op!(a, b, *)
}),
Builtin::new("splitVersion", &[true], |args, _| {
let s = args[0].to_str()?;
let s = VersionPartsIter::new(s.as_str());
let parts = s
.map(|s| {
Value::String(match s {
// TODO(sterni): we should avoid converting back and forth here
VersionPart::Number(n) => format!("{n}").into(),
VersionPart::Word(w) => w.into(),
})
})
.collect::<Vec<Value>>();
Ok(Value::List(NixList::construct(parts.len(), parts)))
}),
Builtin::new("sub", &[true, true], |mut args, _| {
let b = args.pop().unwrap();
let a = args.pop().unwrap();