Skip to content

Commit cd5f765

Browse files
committed
Js_json adding support of bigint
1 parent 11adb1d commit cd5f765

9 files changed

+50
-7
lines changed

jscomp/core/js_exp_make.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,11 +807,13 @@ let tag_type = function
807807
| Ast_untagged_variants.String s -> str s ~delim:DStarJ
808808
| Int i -> small_int i
809809
| Float f -> float f
810+
| Bigint i -> bigint i
810811
| Bool b -> bool b
811812
| Null -> nil
812813
| Undefined -> undefined
813814
| Untagged IntType -> str "number"
814815
| Untagged FloatType -> str "number"
816+
| Untagged BigintType -> str "bigint"
815817
| Untagged BooleanType -> str "boolean"
816818
| Untagged FunctionType -> str "function"
817819
| Untagged StringType -> str "string"

jscomp/core/js_stmt_make.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ let string_switch ?(comment : string option)
138138
match switch_case with
139139
| String s ->
140140
if s = txt then Some x.switch_body else None
141-
| Int _ | Float _| Bool _ | Null | Undefined | Untagged _ ->
141+
| Int _ | Float _ | Bigint _ | Bool _ | Null | Undefined | Untagged _ ->
142142
None)
143143
with
144144
| Some case -> case

jscomp/ml/ast_payload.ml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ let is_single_int (x : t) : int option =
6161
{
6262
pstr_desc =
6363
Pstr_eval
64-
({pexp_desc = Pexp_constant (Pconst_integer (name, _)); _}, _);
64+
({pexp_desc = Pexp_constant (Pconst_integer (name, char)); _}, _);
6565
_;
6666
};
67-
] ->
67+
] when (match char with Some n when n = 'n' -> false | _ -> true) ->
6868
Some (int_of_string name)
6969
| _ -> None
7070

@@ -82,6 +82,20 @@ let is_single_float (x : t) : string option =
8282
Some name
8383
| _ -> None
8484

85+
let is_single_bigint (x : t) : string option =
86+
match x with
87+
| PStr
88+
[
89+
{
90+
pstr_desc =
91+
Pstr_eval
92+
({pexp_desc = Pexp_constant (Pconst_integer (name, Some n)); _}, _);
93+
_;
94+
};
95+
] when n = 'n' ->
96+
Some name
97+
| _ -> None
98+
8599
let is_single_bool (x : t) : bool option =
86100
match x with
87101
| PStr

jscomp/ml/ast_payload.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ val is_single_int : t -> int option
4141

4242
val is_single_float : t -> string option
4343

44+
val is_single_bigint : t -> string option
45+
4446
val is_single_bool : t -> bool option
4547

4648
val is_single_ident : t -> Longident.t option

jscomp/ml/ast_untagged_variants.ml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type untaggedError =
2222
| AtMostOneFunction
2323
| AtMostOneString
2424
| AtMostOneNumber
25+
| AtMostOneBigint
2526
| AtMostOneBoolean
2627
| DuplicateLiteral of string
2728
| ConstructorMoreThanOneArg of string
@@ -54,6 +55,8 @@ let report_error ppf =
5455
| AtMostOneBoolean -> "At most one case can be a boolean type."
5556
| AtMostOneNumber ->
5657
"At most one case can be a number type (int or float)."
58+
| AtMostOneBigint ->
59+
"At most one case can be a bigint type."
5760
| DuplicateLiteral s -> "Duplicate literal " ^ s ^ "."
5861
| ConstructorMoreThanOneArg (name) -> "Constructor " ^ name ^ " has more than one argument.")
5962

@@ -62,6 +65,7 @@ type block_type =
6265
| IntType
6366
| StringType
6467
| FloatType
68+
| BigintType
6569
| BooleanType
6670
| InstanceType of Instance.t
6771
| FunctionType
@@ -77,6 +81,7 @@ type tag_type =
7781
| String of string
7882
| Int of int
7983
| Float of string
84+
| Bigint of string
8085
| Bool of bool
8186
| Null
8287
| Undefined (* literal or tagged block *)
@@ -119,6 +124,9 @@ let process_tag_type (attrs : Parsetree.attributes) =
119124
(match Ast_payload.is_single_float payload with
120125
| None -> ()
121126
| Some f -> st := Some (Float f));
127+
(match Ast_payload.is_single_bigint payload with
128+
| None -> ()
129+
| Some i -> st := Some (Bigint i));
122130
(match Ast_payload.is_single_bool payload with
123131
| None -> ()
124132
| Some b -> st := Some (Bool b));
@@ -172,6 +180,8 @@ let get_block_type_from_typ ~env (t: Types.type_expr) : block_type option =
172180
Some IntType
173181
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_float ->
174182
Some FloatType
183+
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_bigint ->
184+
Some BigintType
175185
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_bool ->
176186
Some BooleanType
177187
| ({desc = Tconstr _} as t) when Ast_uncurried_utils.typeIsUncurriedFun t ->
@@ -240,6 +250,7 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
240250
let objectTypes = ref 0 in
241251
let stringTypes = ref 0 in
242252
let numberTypes = ref 0 in
253+
let bigintTypes = ref 0 in
243254
let booleanTypes = ref 0 in
244255
let unknownTypes = ref 0 in
245256
let addStringLiteral ~loc s =
@@ -267,6 +278,9 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
267278
raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneString));
268279
if !numberTypes > 1 then
269280
raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneNumber));
281+
if !bigintTypes > 1 then
282+
(* FIXME need to define another error for duplicated bigint *)
283+
raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBigint));
270284
if !booleanTypes > 1 then
271285
raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBoolean));
272286
if !booleanTypes > 0 && (StringSet.mem "true" !nonstring_literals || StringSet.mem "false" !nonstring_literals) then
@@ -278,6 +292,7 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
278292
| Some (String s) -> addStringLiteral ~loc s
279293
| Some (Int i) -> addNonstringLiteral ~loc (string_of_int i)
280294
| Some (Float f) -> addNonstringLiteral ~loc f
295+
| Some (Bigint i) -> addNonstringLiteral ~loc i
281296
| Some Null -> addNonstringLiteral ~loc "null"
282297
| Some Undefined -> addNonstringLiteral ~loc "undefined"
283298
| Some (Bool b) -> addNonstringLiteral ~loc (if b then "true" else "false")
@@ -295,6 +310,7 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
295310
Hashtbl.replace instanceTypes i (count + 1);
296311
| FunctionType -> incr functionTypes;
297312
| (IntType | FloatType) -> incr numberTypes;
313+
| BigintType -> incr bigintTypes;
298314
| BooleanType -> incr booleanTypes;
299315
| StringType -> incr stringTypes;
300316
);
@@ -359,6 +375,9 @@ module DynamicChecks = struct
359375
let function_ = Untagged FunctionType |> tag_type
360376
let string = Untagged StringType |> tag_type
361377
let number = Untagged IntType |> tag_type
378+
379+
let bigint = Untagged BigintType |> tag_type
380+
362381
let boolean = Untagged BooleanType |> tag_type
363382

364383
let ( == ) x y = bin EqEqEq x y
@@ -375,7 +394,7 @@ module DynamicChecks = struct
375394
in
376395
let literals_overlaps_with_number () =
377396
Ext_list.exists literal_cases (function
378-
| Int _ | Float _ -> true
397+
| Int _ | Float _ | Bigint _ -> true
379398
| _ -> false)
380399
in
381400
let literals_overlaps_with_boolean () =
@@ -398,6 +417,8 @@ module DynamicChecks = struct
398417
typeof e != number
399418
| FloatType when literals_overlaps_with_number () = false ->
400419
typeof e != number
420+
| BigintType when literals_overlaps_with_number () = false ->
421+
typeof e != bigint
401422
| BooleanType when literals_overlaps_with_boolean () = false ->
402423
typeof e != boolean
403424
| InstanceType i -> not (is_instance i e)
@@ -408,6 +429,7 @@ module DynamicChecks = struct
408429
| StringType (* overlap *)
409430
| IntType (* overlap *)
410431
| FloatType (* overlap *)
432+
| BigintType (* overlap *)
411433
| BooleanType (* overlap *)
412434
| UnknownType -> (
413435
(* We don't know the type of unknown, so we need to express:
@@ -449,7 +471,7 @@ module DynamicChecks = struct
449471
let add_runtime_type_check ~tag_type ~(block_cases : block_type list) x y =
450472
let instances = Ext_list.filter_map block_cases (function InstanceType i -> Some i | _ -> None) in
451473
match tag_type with
452-
| Untagged (IntType | StringType | FloatType | BooleanType | FunctionType) ->
474+
| Untagged (IntType | StringType | FloatType | BigintType | BooleanType | FunctionType) ->
453475
typeof y == x
454476
| Untagged ObjectType ->
455477
if instances <> [] then
@@ -462,5 +484,5 @@ module DynamicChecks = struct
462484
| Untagged UnknownType ->
463485
(* This should not happen because unknown must be the only non-literal case *)
464486
assert false
465-
| Bool _ | Float _ | Int _ | String _ | Null | Undefined -> x
487+
| Bool _ | Float _ | Int _ | Bigint _ | String _ | Null | Undefined -> x
466488
end

jscomp/ml/parsetree.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type constant =
2222
(* 3 3l 3L 3n
2323
2424
Suffixes [g-z][G-Z] are accepted by the parser.
25-
Suffixes except 'l', 'L' and 'n' are rejected by the typechecker
25+
Suffixes except 'l', 'L' are rejected by the typechecker
2626
*)
2727
| Pconst_char of int
2828
(* 'c' *)

jscomp/ml/variant_coercion.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ let variant_has_same_runtime_representation_as_target ~(targetPath : Path.t)
4545
| None | Some (String _) -> Path.same targetPath Predef.path_string
4646
| Some (Int _) -> Path.same targetPath Predef.path_int
4747
| Some (Float _) -> Path.same targetPath Predef.path_float
48+
| Some (Bigint _) -> Path.same targetPath Predef.path_bigint
4849
| Some (Null | Undefined | Bool _ | Untagged _) -> false)
4950
| _ -> false
5051
in

jscomp/others/js_json.res

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type rec t =
3030
| @as(null) Null
3131
| String(string)
3232
| Number(float)
33+
| Bigint(bigint)
3334
| Object(Js.Dict.t<t>)
3435
| Array(array<t>)
3536

jscomp/others/js_json.resi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type rec t =
3636
| @as(null) Null
3737
| String(string)
3838
| Number(float)
39+
| Bigint(bigint)
3940
| Object(Js.Dict.t<t>)
4041
| Array(array<t>)
4142

0 commit comments

Comments
 (0)