feat(tvix/eval): Support builtins.lessThan
Extend and export the `cmp_op`, and this becomes trivial. Change-Id: I9c93fa4db0f5a1fc8b56928ea144676f79247de1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6557 Autosubmit: wpcarro <wpcarro@gmail.com> Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
		
							parent
							
								
									9e16d70809
								
							
						
					
					
						commit
						890bbf9b1f
					
				
					 4 changed files with 41 additions and 13 deletions
				
			
		|  | @ -16,7 +16,7 @@ use crate::{ | |||
|     vm::VM, | ||||
| }; | ||||
| 
 | ||||
| use crate::arithmetic_op; | ||||
| use crate::{arithmetic_op, cmp_op}; | ||||
| 
 | ||||
| use self::versions::{VersionPart, VersionPartsIter}; | ||||
| 
 | ||||
|  | @ -160,6 +160,11 @@ fn pure_builtins() -> Vec<Builtin> { | |||
|                 .map(|list| Value::List(NixList::from(list))) | ||||
|                 .map_err(Into::into) | ||||
|         }), | ||||
|         Builtin::new( | ||||
|             "lessThan", | ||||
|             &[false, false], | ||||
|             |args, vm| cmp_op!(&*args[0].force(vm)?, &*args[1].force(vm)?, <), | ||||
|         ), | ||||
|         Builtin::new("hasAttr", &[true, true], |args, _| { | ||||
|             let k = args[0].to_str()?; | ||||
|             let xs = args[1].to_attrs()?; | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| [ true true true true false false false false true true true true false ] | ||||
|  | @ -0,0 +1,15 @@ | |||
| [ | ||||
|   (builtins.lessThan 2 3) | ||||
|   (builtins.lessThan 2.0 3) | ||||
|   (builtins.lessThan 2 3.0) | ||||
|   (builtins.lessThan 2.0 3.0) | ||||
|   (builtins.lessThan 3 2) | ||||
|   (builtins.lessThan 3.0 2) | ||||
|   (builtins.lessThan 3 2.0) | ||||
|   (builtins.lessThan 3.0 2.0) | ||||
|   (builtins.lessThan 10 (builtins.add 9 2)) | ||||
|   (builtins.lessThan (builtins.add 9 1) 11) | ||||
|   (builtins.lessThan (builtins.add 9 1) (builtins.add 9 2)) | ||||
|   (builtins.lessThan "a" "b") | ||||
|   (builtins.lessThan "b" "a") | ||||
| ] | ||||
|  | @ -94,29 +94,36 @@ macro_rules! arithmetic_op { | |||
|     }}; | ||||
| } | ||||
| 
 | ||||
| #[macro_export] | ||||
| macro_rules! cmp_op { | ||||
|     ( $self:ident, $op:tt ) => {{ | ||||
|         let b = $self.pop(); | ||||
|         let a = $self.pop(); | ||||
|         let result = fallible!($self, cmp_op!(&a, &b, $op)); | ||||
|         $self.push(result); | ||||
|     }}; | ||||
| 
 | ||||
|     ( $a:expr, $b:expr, $op:tt ) => { | ||||
|         // Comparable (in terms of ordering) values are numbers and
 | ||||
|         // strings. Numbers need to be coerced similarly to arithmetic
 | ||||
|         // ops if mixed types are encountered.
 | ||||
|         let result = match (a, b) { | ||||
|             (Value::Integer(i1), Value::Integer(i2)) => i1 $op i2, | ||||
|             (Value::Float(f1), Value::Float(f2)) => f1 $op f2, | ||||
|             (Value::Integer(i1), Value::Float(f2)) => (i1 as f64) $op f2, | ||||
|             (Value::Float(f1), Value::Integer(i2)) => f1 $op (i2 as f64), | ||||
|             (Value::String(s1), Value::String(s2)) => s1 $op s2, | ||||
|         match ($a, $b) { | ||||
|             // same types
 | ||||
|             (Value::Integer(i1), Value::Integer(i2)) => Ok(Value::Bool(i1 $op i2)), | ||||
|             (Value::Float(f1), Value::Float(f2)) => Ok(Value::Bool(f1 $op f2)), | ||||
|             (Value::String(s1), Value::String(s2)) => Ok(Value::Bool(s1 $op s2)), | ||||
| 
 | ||||
|             (lhs, rhs) => return Err($self.error(ErrorKind::Incomparable { | ||||
|             // different types
 | ||||
|             (Value::Integer(i1), Value::Float(f2)) => Ok(Value::Bool((*i1 as f64) $op *f2)), | ||||
|             (Value::Float(f1), Value::Integer(i2)) => Ok(Value::Bool(*f1 $op (*i2 as f64))), | ||||
| 
 | ||||
|             // unsupported types
 | ||||
|             (lhs, rhs) => Err(ErrorKind::Incomparable { | ||||
|                 lhs: lhs.type_of(), | ||||
|                 rhs: rhs.type_of(), | ||||
|             })), | ||||
|         }; | ||||
| 
 | ||||
|         $self.push(Value::Bool(result)); | ||||
|     }}; | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'o> VM<'o> { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue