40 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
		
		
			
		
	
	
			40 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
|   | /* Helper function to implement a fallback for the bit operators
 | ||
|  |    `bitAnd`, `bitOr` and `bitXOr` on older nix version. | ||
|  |    See ./trivial.nix | ||
|  | */ | ||
|  | f: x: y: | ||
|  |   let | ||
|  |     # (intToBits 6) -> [ 0 1 1 ] | ||
|  |     intToBits = x: | ||
|  |       if x == 0 || x == -1 then | ||
|  |         [] | ||
|  |       else | ||
|  |         let | ||
|  |           headbit  = if (x / 2) * 2 != x then 1 else 0;          # x & 1 | ||
|  |           tailbits = if x < 0 then ((x + 1) / 2) - 1 else x / 2; # x >> 1 | ||
|  |         in | ||
|  |           [headbit] ++ (intToBits tailbits); | ||
|  | 
 | ||
|  |     # (bitsToInt [ 0 1 1 ] 0) -> 6 | ||
|  |     # (bitsToInt [ 0 1 0 ] 1) -> -6 | ||
|  |     bitsToInt = l: signum: | ||
|  |       if l == [] then | ||
|  |         (if signum == 0 then 0 else -1) | ||
|  |       else | ||
|  |         (builtins.head l) + (2 * (bitsToInt (builtins.tail l) signum)); | ||
|  | 
 | ||
|  |     xsignum = if x < 0 then 1 else 0; | ||
|  |     ysignum = if y < 0 then 1 else 0; | ||
|  |     zipListsWith' = fst: snd: | ||
|  |       if fst==[] && snd==[] then | ||
|  |         [] | ||
|  |       else if fst==[] then | ||
|  |         [(f xsignum             (builtins.head snd))] ++ (zipListsWith' []                  (builtins.tail snd)) | ||
|  |       else if snd==[] then | ||
|  |         [(f (builtins.head fst) ysignum            )] ++ (zipListsWith' (builtins.tail fst) []                 ) | ||
|  |       else | ||
|  |         [(f (builtins.head fst) (builtins.head snd))] ++ (zipListsWith' (builtins.tail fst) (builtins.tail snd)); | ||
|  |   in | ||
|  |     assert (builtins.isInt x) && (builtins.isInt y); | ||
|  |     bitsToInt (zipListsWith' (intToBits x) (intToBits y)) (f xsignum ysignum) |