@@ -35,7 +35,7 @@ type primitive =
35
35
[ Value .t
36
36
| `PFun of RequestData .request_data -> Value .t list -> Value .t Lwt .t ]
37
37
38
- type pure = PURE | IMPURE
38
+ type pure = PURE | IMPURE | F2 of ( Value .t -> Value .t -> pure )
39
39
40
40
type located_primitive = [ `Client | `Server of primitive | primitive ]
41
41
@@ -47,19 +47,34 @@ let mk_binop_fn impl unbox_fn constr = function
47
47
48
48
let int_op impl pure : located_primitive * Types.datatype * pure =
49
49
(`PFun (fun _ -> mk_binop_fn impl Value. unbox_int (fun x -> `Int x))),
50
- datatype " (Int, Int ) -> Int" ,
50
+ datatype " (a::Numeric, a ) -> Int" ,
51
51
pure
52
52
53
53
let float_op impl pure : located_primitive * Types.datatype * pure =
54
54
(`PFun (fun _ -> mk_binop_fn impl Value. unbox_float (fun x -> `Float x))),
55
- datatype " (Float, Float ) -> Float" ,
55
+ datatype " (a::Numeric, a ) -> Float" ,
56
56
pure
57
57
58
58
let string_op impl pure : located_primitive * Types.datatype * pure =
59
59
(`PFun (fun _ -> mk_binop_fn impl Value. unbox_string (fun x -> `String x))),
60
60
datatype " (String, String) -> String" ,
61
61
pure
62
62
63
+ let numeric_op impli implf purei puref : located_primitive * Types.datatype * pure =
64
+ (`PFun (fun _ args -> match args with
65
+ | [x; y] ->
66
+ (match (x,y) with
67
+ | (`Int _ , `Int _ ) -> Lwt. return (`Int (impli (Value. unbox_int x) (Value. unbox_int y)))
68
+ | (`Float _ , `Float _ ) -> Lwt. return (`Float (implf (Value. unbox_float x) (Value. unbox_float y)))
69
+ | _ -> raise (runtime_type_error " type error in numeric operation" ))
70
+ | _ -> raise (internal_error " arity error in numeric operation" ))),
71
+ datatype " (a::Numeric, a) -> a" ,
72
+ F2 (fun l r -> match (l, r) with
73
+ | (`Int _ , `Int _ ) -> purei
74
+ | (`Float _ , `Float _ ) -> puref
75
+ | _ -> raise (internal_error (" cannot establish purity in numeric operations" ))
76
+ )
77
+
63
78
let conversion_op' ~unbox ~conv ~(box :'a->Value.t ): Value.t list -> Value.t = function
64
79
| [x] -> box (conv (unbox x))
65
80
| _ -> assert false
@@ -228,18 +243,22 @@ let project_datetime (f: CalendarShow.t -> int) : located_primitive * Types.data
228
243
229
244
230
245
let env : (string * (located_primitive * Types.datatype * pure)) list = [
231
- " +" , int_op (+ ) PURE ;
232
- " -" , int_op (- ) PURE ;
233
- " *" , int_op ( * ) PURE ;
234
- " /" , int_op (/ ) IMPURE ;
235
- " ^" , int_op pow PURE ;
236
- " mod" , int_op (mod ) IMPURE ;
237
- " +." , float_op (+. ) PURE ;
238
- " -." , float_op (-. ) PURE ;
239
- " *." , float_op ( *. ) PURE ;
240
- " /." , float_op (/. ) PURE ;
241
- " ^." , float_op ( ** ) PURE ;
242
- " ^^" , string_op ( ^ ) PURE ;
246
+ " +" , numeric_op ( + ) ( +. ) PURE PURE ;
247
+ " -" , numeric_op ( - ) ( -. ) PURE PURE ;
248
+ " *" , numeric_op ( * ) ( *. ) PURE PURE ;
249
+ " /" , numeric_op ( / ) ( /. ) IMPURE PURE ;
250
+ " ^" , numeric_op (pow) ( ** ) PURE PURE ;
251
+
252
+ " mod" , int_op ( mod ) IMPURE ;
253
+
254
+ (* for backwards compatability *)
255
+ " +." , float_op ( +. ) PURE ;
256
+ " -." , float_op ( -. ) PURE ;
257
+ " *." , float_op ( *. ) PURE ;
258
+ " /." , float_op ( /. ) PURE ;
259
+ " ^." , float_op ( ** ) PURE ;
260
+
261
+ " ^^" , string_op ( ^ ) PURE ;
243
262
244
263
" max_int" ,
245
264
(Value. box_int max_int,
@@ -718,7 +737,6 @@ let env : (string * (located_primitive * Types.datatype * pure)) list = [
718
737
719
738
" print" ,
720
739
(p1 (fun msg -> print_string (Value. unbox_string msg); flush stdout; `Record [] ),
721
- (* datatype "(String) ~> ()", *)
722
740
datatype " (String) ~> ()" ,
723
741
IMPURE );
724
742
@@ -732,7 +750,15 @@ let env : (string * (located_primitive * Types.datatype * pure)) list = [
732
750
PURE );
733
751
734
752
" negate" ,
735
- (p1 (Value. unbox_int ->- (~- ) ->- Value. box_int), datatype " (Int) -> Int" ,
753
+ (p1 (fun i -> match i with
754
+ | `Int _ -> Value. box_int (- (Value. unbox_int i))
755
+ | `Float _ -> Value. box_float (-. (Value. unbox_float i))
756
+ | _ -> raise (runtime_type_error (" Cannot negate: " ^ Value. string_of_value i))),
757
+ datatype " (a::Numeric) -> a" ,
758
+ PURE );
759
+
760
+ " negatei" ,
761
+ (p1 (fun i -> Value. box_int (- (Value. unbox_int i))), datatype " (Int) -> Int" ,
736
762
PURE );
737
763
738
764
" negatef" ,
0 commit comments