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, |     vm::VM, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use crate::arithmetic_op; | use crate::{arithmetic_op, cmp_op}; | ||||||
| 
 | 
 | ||||||
| use self::versions::{VersionPart, VersionPartsIter}; | use self::versions::{VersionPart, VersionPartsIter}; | ||||||
| 
 | 
 | ||||||
|  | @ -160,6 +160,11 @@ fn pure_builtins() -> Vec<Builtin> { | ||||||
|                 .map(|list| Value::List(NixList::from(list))) |                 .map(|list| Value::List(NixList::from(list))) | ||||||
|                 .map_err(Into::into) |                 .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, _| { |         Builtin::new("hasAttr", &[true, true], |args, _| { | ||||||
|             let k = args[0].to_str()?; |             let k = args[0].to_str()?; | ||||||
|             let xs = args[1].to_attrs()?; |             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 { | macro_rules! cmp_op { | ||||||
|     ( $self:ident, $op:tt ) => {{ |     ( $self:ident, $op:tt ) => {{ | ||||||
|         let b = $self.pop(); |         let b = $self.pop(); | ||||||
|         let a = $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
 |         // Comparable (in terms of ordering) values are numbers and
 | ||||||
|         // strings. Numbers need to be coerced similarly to arithmetic
 |         // strings. Numbers need to be coerced similarly to arithmetic
 | ||||||
|         // ops if mixed types are encountered.
 |         // ops if mixed types are encountered.
 | ||||||
|         let result = match (a, b) { |         match ($a, $b) { | ||||||
|             (Value::Integer(i1), Value::Integer(i2)) => i1 $op i2, |             // same types
 | ||||||
|             (Value::Float(f1), Value::Float(f2)) => f1 $op f2, |             (Value::Integer(i1), Value::Integer(i2)) => Ok(Value::Bool(i1 $op i2)), | ||||||
|             (Value::Integer(i1), Value::Float(f2)) => (i1 as f64) $op f2, |             (Value::Float(f1), Value::Float(f2)) => Ok(Value::Bool(f1 $op f2)), | ||||||
|             (Value::Float(f1), Value::Integer(i2)) => f1 $op (i2 as f64), |             (Value::String(s1), Value::String(s2)) => Ok(Value::Bool(s1 $op s2)), | ||||||
|             (Value::String(s1), Value::String(s2)) => 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(), |                 lhs: lhs.type_of(), | ||||||
|                 rhs: rhs.type_of(), |                 rhs: rhs.type_of(), | ||||||
|             })), |             }), | ||||||
|         }; |         } | ||||||
| 
 |     } | ||||||
|         $self.push(Value::Bool(result)); |  | ||||||
|     }}; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'o> VM<'o> { | impl<'o> VM<'o> { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue