@@ -97,22 +97,21 @@ let try_with_idents : Longident.t Asttypes.loc list = [
9797]
9898let is_try_with_ident x = List. exists (fun tw -> x = tw) try_with_idents
9999
100- (* For integer constants (not 0/1) in this range we will use Prims.of_int
101- * Outside this range we will use string parsing to allow arbitrary sized
102- * integers.
103- * Using int_zero/int_one removes int processing to create the int
104- * Using of_int removes string processing to create the int
105- *)
106- let max_of_int_const = Z. of_int 65535
107- let min_of_int_const = Z. of_int (- 65536 )
100+ (* For integer constants outside of this range we will use Prims.parse_int,
101+ * to allow for arbitrary sized integers.
102+ * For small integers, we prefer using of_int to avoid string parsing.
103+ * OCaml guarantees a minimum width of 31 ( *not* 32), so we can generate
104+ * literals safely for anything in [-2^30, 2^30 - 1]. *)
105+ let min_of_int_const = Z. neg (Z. pow (Z. of_int 2 ) 30 )
106+ let max_of_int_const = Z. sub (Z. pow (Z. of_int 2 ) 30 ) Z. one
108107
109108let maybe_guts (s :string ) : string =
110109 if FStarC_Options. codegen () = Some FStarC_Options. Plugin
111110 then " Fstarcompiler." ^ s
112111 else s
113112
114113(* mapping functions from F* ML AST to Parsetree *)
115- let build_constant (c : mlconstant ): constant =
114+ let build_constant_expr (c : mlconstant ) : expression =
116115 let stdint_module (s :FStarC_Const.signedness ) (w :FStarC_Const.width ) : string =
117116 let sign = match s with
118117 | FStarC_Const. Signed -> " Int"
@@ -123,53 +122,60 @@ let build_constant (c: mlconstant): constant =
123122 | FStarC_Const. Int16 -> with_w " 16"
124123 | FStarC_Const. Int32 -> with_w " 32"
125124 | FStarC_Const. Int64 -> with_w " 64"
126- | FStarC_Const. Sizet -> with_w " 64" in
127- match c with
128- | MLC_Int (v , None) ->
129- let s = match Z. of_string v with
130- | x when x = Z. zero ->
131- maybe_guts " Prims.int_zero"
132- | x when x = Z. one ->
133- maybe_guts " Prims.int_one"
134- | x when (min_of_int_const < x) && (x < max_of_int_const) ->
135- BatString. concat v [" (Prims.of_int (" ; " ))" ]
136- | x ->
137- BatString. concat v [" (Prims.parse_int \" " ; " \" )" ] in
138- Pconst_integer (s, None )
139- (* Special case for UInt8, as it's realized as OCaml built-in int type *)
140- | MLC_Int (v , Some (FStarC_Const. Unsigned, FStarC_Const. Int8)) ->
141- Pconst_integer (v, None )
142- | MLC_Int (v , Some (s , w )) ->
143- let s = match Z. of_string v with
144- | x when x = Z. zero ->
145- BatString. concat " " [stdint_module s w; " .zero" ]
146- | x when x = Z. one ->
147- BatString. concat " " [stdint_module s w; " .one" ]
148- | x when (min_of_int_const < x) && (x < max_of_int_const) ->
149- BatString. concat " " [" (" ; stdint_module s w; " .of_int (" ; v; " ))" ]
150- | x ->
151- BatString. concat " " [" (" ; stdint_module s w; " .of_string \" " ; v; " \" )" ] in
152- Pconst_integer (s, None )
153- | MLC_Float v -> Pconst_float (string_of_float v, None )
154- | MLC_Char v -> Pconst_integer (string_of_int v, None )
155- | MLC_String v -> Pconst_string (v, no_location, None )
156- | _ -> failwith " Case not handled"
157-
158- let build_constant_expr (c : mlconstant ): expression =
125+ | FStarC_Const. Sizet -> with_w " 64"
126+ in
159127 match c with
160128 | MLC_Unit -> pexp_construct ~loc (mk_lident " ()" ) None
161129 | MLC_Bool b ->
162130 let id = if b then " true" else " false" in
163131 pexp_construct ~loc (mk_lident id) None
164- | _ -> pexp_constant ~loc (build_constant c)
132+ (* Special case for UInt8, as it's realized as OCaml built-in int type *)
133+ | MLC_Int (v , Some (FStarC_Const. Unsigned, FStarC_Const. Int8)) ->
134+ pexp_constant ~loc @@ Pconst_integer (v, None )
135+ | MLC_Int (v , None) -> (
136+ (* Prims integers *)
137+ match Z. of_string v with
138+ | x when x = Z. zero -> pexp_ident ~loc (mk_lident " Prims.int_zero" )
139+ | x when x = Z. one -> pexp_ident ~loc (mk_lident " Prims.int_one" )
140+ | x when min_of_int_const < = x && x < = max_of_int_const ->
141+ let r = pexp_ident ~loc (mk_lident " Prims.of_int" ) in
142+ let n = pexp_constant ~loc (Pconst_integer (v, None )) in
143+ pexp_apply ~loc r [(Nolabel , n)]
144+ | x ->
145+ let r = pexp_ident ~loc (mk_lident " Prims.parse_int" ) in
146+ let n = pexp_constant ~loc (Pconst_string (v, no_location, None )) in
147+ pexp_apply ~loc r [(Nolabel , n)]
148+ )
149+ | MLC_Int (v , Some (s , w )) -> (
150+ (* Machine integers. *)
151+ match Z. of_string v with
152+ | x when x = Z. zero -> pexp_ident ~loc @@ mk_lident (stdint_module s w ^ " .zero" )
153+ | x when x = Z. one -> pexp_ident ~loc @@ mk_lident (stdint_module s w ^ " .one" )
154+ | x when min_of_int_const < = x && x < = max_of_int_const ->
155+ let r = pexp_ident ~loc @@ mk_lident (stdint_module s w ^ " .of_int" ) in
156+ let n = pexp_constant ~loc (Pconst_integer (v, None )) in
157+ pexp_apply ~loc r [(Nolabel , n)]
158+ | x ->
159+ let r = pexp_ident ~loc @@ mk_lident (stdint_module s w ^ " .of_string" ) in
160+ let n = pexp_constant ~loc (Pconst_string (v, no_location, None )) in
161+ pexp_apply ~loc r [(Nolabel , n)]
162+ )
163+ | MLC_Float v -> pexp_constant ~loc @@ Pconst_float (string_of_float v, None )
164+ | MLC_Char v -> pexp_constant ~loc @@ Pconst_integer (string_of_int v, None )
165+ | MLC_String v -> pexp_constant ~loc @@ Pconst_string (v, no_location, None )
166+ | _ -> failwith " Case not handled"
165167
166168let build_constant_pat (c : mlconstant ): pattern =
167169 match c with
168170 | MLC_Unit -> ppat_construct ~loc (mk_lident " ()" ) None
169171 | MLC_Bool b ->
170172 let id = if b then " true" else " false" in
171173 ppat_construct ~loc (mk_lident id) None
172- | _ -> ppat_constant ~loc (build_constant c)
174+ | MLC_Float v -> ppat_constant ~loc @@ Pconst_float (string_of_float v, None )
175+ | MLC_Char v -> ppat_constant ~loc @@ Pconst_integer (string_of_int v, None )
176+ | MLC_String v -> ppat_constant ~loc @@ Pconst_string (v, no_location, None )
177+ | MLC_Int _ ->
178+ failwith " PrintML: unexpected integer pattern, should have become a pattern guard"
173179
174180let rec build_pattern (p : mlpattern ): pattern =
175181 match p with
0 commit comments