+(* + operator is addition or string concatenation. *)
+and add_values value1 value2 =
+ match value1, value2 with
+ | T_int i1, T_int i2 -> T_int (add_big_int i1 i2)
+ | T_float i1, T_float i2 -> T_float (i1 +. i2)
+ | T_int i1, T_float i2 -> T_float (float_of_big_int i1 +. i2)
+ | T_float i1, T_int i2 -> T_float (i1 +. float_of_big_int i2)
+ | T_string i1, T_string i2 -> T_string (i1 ^ i2)
+ | _ ->
+ invalid_arg
+ (sprintf "incompatible types in addition: %s + %s"
+ (printable_string_of_variable value1)
+ (printable_string_of_variable value2))
+
+and sub_values value1 value2 =
+ match value1, value2 with
+ | T_int i1, T_int i2 -> T_int (sub_big_int i1 i2)
+ | T_float i1, T_float i2 -> T_float (i1 -. i2)
+ | T_int i1, T_float i2 -> T_float (float_of_big_int i1 -. i2)
+ | T_float i1, T_int i2 -> T_float (i1 -. float_of_big_int i2)
+ | _ ->
+ invalid_arg
+ (sprintf "incompatible types in subtraction: %s - %s"
+ (printable_string_of_variable value1)
+ (printable_string_of_variable value2))
+
+and mul_values value1 value2 =
+ match value1, value2 with
+ | T_int i1, T_int i2 -> T_int (mult_big_int i1 i2)
+ | T_float i1, T_float i2 -> T_float (i1 *. i2)
+ | T_int i1, T_float i2 -> T_float (float_of_big_int i1 *. i2)
+ | T_float i1, T_int i2 -> T_float (i1 *. float_of_big_int i2)
+ | _ ->
+ invalid_arg
+ (sprintf "incompatible types in multiplication: %s * %s"
+ (printable_string_of_variable value1)
+ (printable_string_of_variable value2))
+
+and div_values value1 value2 =
+ match value1, value2 with
+ | T_int i1, T_int i2 -> T_int (div_big_int i1 i2)
+ | T_float i1, T_float i2 -> T_float (i1 /. i2)
+ | T_int i1, T_float i2 -> T_float (float_of_big_int i1 /. i2)
+ | T_float i1, T_int i2 -> T_float (i1 /. float_of_big_int i2)
+ | _ ->
+ invalid_arg
+ (sprintf "incompatible types in division: %s / %s"
+ (printable_string_of_variable value1)
+ (printable_string_of_variable value2))
+
+and mod_values value1 value2 =
+ match value1, value2 with
+ | T_int i1, T_int i2 -> T_int (mod_big_int i1 i2)
+ | T_float i1, T_float i2 -> T_float (mod_float i1 i2)
+ | T_int i1, T_float i2 -> T_float (mod_float (float_of_big_int i1) i2)
+ | T_float i1, T_int i2 -> T_float (mod_float i1 (float_of_big_int i2))
+ | _ ->
+ invalid_arg
+ (sprintf "incompatible types in modulo: %s mod %s"
+ (printable_string_of_variable value1)
+ (printable_string_of_variable value2))
+