@live-codes/ocaml 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -16
- package/assets/compiler/compile_stdout.browser.js +18185 -18181
- package/assets/compiler/libs/base64.cma +0 -0
- package/assets/compiler/libs/base64.cmi +0 -0
- package/assets/compiler/libs/big_int_Z.cmi +0 -0
- package/assets/compiler/libs/digestif.cmi +0 -0
- package/assets/compiler/libs/dllcamlruntime_eventsbyt-x86_64-pc-linux-gnu-a100.so +0 -0
- package/assets/compiler/libs/dllcamlstrbyt-x86_64-pc-linux-gnu-a100.so +0 -0
- package/assets/compiler/libs/dlldigestif_c_stubs.so +0 -0
- package/assets/compiler/libs/dllgraphics_js_stubs.so +0 -0
- package/assets/compiler/libs/dllgraphics_stubs.so +0 -0
- package/assets/compiler/libs/dlljs_of_ocaml_compiler_dynlink_stubs.so +0 -0
- package/assets/compiler/libs/dlljs_of_ocaml_stubs.so +0 -0
- package/assets/compiler/libs/dlljsoo_runtime_stubs.so +0 -0
- package/assets/compiler/libs/dlllwt_unix_stubs.so +0 -0
- package/assets/compiler/libs/dllthreads-x86_64-pc-linux-gnu-a100.so +0 -0
- package/assets/compiler/libs/dllunixbyt-x86_64-pc-linux-gnu-a100.so +0 -0
- package/assets/compiler/libs/dllzarith.so +0 -0
- package/assets/compiler/libs/fmt.cma +0 -0
- package/assets/compiler/libs/fmt.cmi +0 -0
- package/assets/compiler/libs/graphics.cma +0 -0
- package/assets/compiler/libs/graphics.cmi +0 -0
- package/assets/compiler/libs/graphicsX11.cmi +0 -0
- package/assets/compiler/libs/index.txt +105 -0
- package/assets/compiler/libs/js_of_ocaml.cma +0 -0
- package/assets/compiler/libs/js_of_ocaml.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Abort.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__CSS.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Console.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Dom.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Dom_events.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Dom_html.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Dom_svg.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Effect_js.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__EventSource.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Fetch.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__File.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Form.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Geolocation.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Import.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__IntersectionObserver.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Intl.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Js.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Json.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Jstable.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Lib_version.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__MutationObserver.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Performance.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__PerformanceObserver.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Promise.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Regexp.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__ResizeObserver.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Sys_js.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Typed_array.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Url.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__WebGL.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__WebSockets.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__Worker.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml__XmlHttpRequest.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt.cma +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt__.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt__Import.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt__Lwt_file.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt__Lwt_js.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt__Lwt_js_events.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt__Lwt_jsonp.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt__Lwt_promise.cmi +0 -0
- package/assets/compiler/libs/js_of_ocaml_lwt__Lwt_xmlHttpRequest.cmi +0 -0
- package/assets/compiler/libs/jsonm.cma +0 -0
- package/assets/compiler/libs/jsonm.cmi +0 -0
- package/assets/compiler/libs/jsoo_runtime.cma +0 -0
- package/assets/compiler/libs/jsoo_runtime.cmi +0 -0
- package/assets/compiler/libs/jsoo_runtime__.cmi +0 -0
- package/assets/compiler/libs/jsoo_runtime__Runtime_version.cmi +0 -0
- package/assets/compiler/libs/logs.cma +0 -0
- package/assets/compiler/libs/logs.cmi +0 -0
- package/assets/compiler/libs/lwt.cma +0 -0
- package/assets/compiler/libs/lwt.cmi +0 -0
- package/assets/compiler/libs/lwt_condition.cmi +0 -0
- package/assets/compiler/libs/lwt_list.cmi +0 -0
- package/assets/compiler/libs/lwt_mutex.cmi +0 -0
- package/assets/compiler/libs/lwt_mvar.cmi +0 -0
- package/assets/compiler/libs/lwt_pool.cmi +0 -0
- package/assets/compiler/libs/lwt_pqueue.cmi +0 -0
- package/assets/compiler/libs/lwt_result.cmi +0 -0
- package/assets/compiler/libs/lwt_rte.cmi +0 -0
- package/assets/compiler/libs/lwt_seq.cmi +0 -0
- package/assets/compiler/libs/lwt_sequence.cmi +0 -0
- package/assets/compiler/libs/lwt_stream.cmi +0 -0
- package/assets/compiler/libs/lwt_switch.cmi +0 -0
- package/assets/compiler/libs/manifest.txt +132 -0
- package/assets/compiler/libs/q.cmi +0 -0
- package/assets/compiler/libs/re.cma +0 -0
- package/assets/compiler/libs/re.cmi +0 -0
- package/assets/compiler/libs/re__.cmi +0 -0
- package/assets/compiler/libs/re__Ast.cmi +0 -0
- package/assets/compiler/libs/re__Automata.cmi +0 -0
- package/assets/compiler/libs/re__Bit_vector.cmi +0 -0
- package/assets/compiler/libs/re__Category.cmi +0 -0
- package/assets/compiler/libs/re__Color_map.cmi +0 -0
- package/assets/compiler/libs/re__Compile.cmi +0 -0
- package/assets/compiler/libs/re__Core.cmi +0 -0
- package/assets/compiler/libs/re__Cset.cmi +0 -0
- package/assets/compiler/libs/re__Dense_map.cmi +0 -0
- package/assets/compiler/libs/re__Dyn.cmi +0 -0
- package/assets/compiler/libs/re__Emacs.cmi +0 -0
- package/assets/compiler/libs/re__Fmt.cmi +0 -0
- package/assets/compiler/libs/re__Glob.cmi +0 -0
- package/assets/compiler/libs/re__Group.cmi +0 -0
- package/assets/compiler/libs/re__Hash_set.cmi +0 -0
- package/assets/compiler/libs/re__Import.cmi +0 -0
- package/assets/compiler/libs/re__Mark_infos.cmi +0 -0
- package/assets/compiler/libs/re__Parse_buffer.cmi +0 -0
- package/assets/compiler/libs/re__Pcre.cmi +0 -0
- package/assets/compiler/libs/re__Perl.cmi +0 -0
- package/assets/compiler/libs/re__Pmark.cmi +0 -0
- package/assets/compiler/libs/re__Posix.cmi +0 -0
- package/assets/compiler/libs/re__Posix_class.cmi +0 -0
- package/assets/compiler/libs/re__Replace.cmi +0 -0
- package/assets/compiler/libs/re__Search.cmi +0 -0
- package/assets/compiler/libs/re__Slice.cmi +0 -0
- package/assets/compiler/libs/re__Str.cmi +0 -0
- package/assets/compiler/libs/re__View.cmi +0 -0
- package/assets/compiler/libs/str.cma +0 -0
- package/assets/compiler/libs/str.cmi +0 -0
- package/assets/compiler/libs/stubs.txt +12 -0
- package/assets/compiler/libs/unix.cma +0 -0
- package/assets/compiler/libs/unix.cmi +0 -0
- package/assets/compiler/libs/unixLabels.cmi +0 -0
- package/assets/compiler/libs/uutf.cma +0 -0
- package/assets/compiler/libs/uutf.cmi +0 -0
- package/assets/compiler/libs/xmlm.cma +0 -0
- package/assets/compiler/libs/xmlm.cmi +0 -0
- package/assets/compiler/libs/z.cmi +0 -0
- package/assets/compiler/libs/zarith.cma +0 -0
- package/assets/compiler/libs/zarith_stubs_js.runtime.js +1246 -0
- package/assets/compiler/worker.js +38 -2
- package/assets/interpreter/libs/base64.cma +0 -0
- package/assets/interpreter/libs/base64.cmi +0 -0
- package/assets/interpreter/libs/big_int_Z.cmi +0 -0
- package/assets/interpreter/libs/fmt.cma +0 -0
- package/assets/interpreter/libs/fmt.cmi +0 -0
- package/assets/interpreter/libs/graphics.cma +0 -0
- package/assets/interpreter/libs/graphics.cmi +0 -0
- package/assets/interpreter/libs/graphicsX11.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml.cma +0 -0
- package/assets/interpreter/libs/js_of_ocaml.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Abort.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__CSS.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Console.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Dom.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Dom_events.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Dom_html.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Dom_svg.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Effect_js.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__EventSource.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Fetch.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__File.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Form.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Geolocation.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Import.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__IntersectionObserver.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Intl.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Js.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Json.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Jstable.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Lib_version.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__MutationObserver.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Performance.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__PerformanceObserver.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Promise.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Regexp.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__ResizeObserver.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Sys_js.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Typed_array.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Url.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__WebGL.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__WebSockets.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__Worker.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml__XmlHttpRequest.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt.cma +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt__.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt__Import.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt__Lwt_file.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt__Lwt_js.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt__Lwt_js_events.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt__Lwt_jsonp.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt__Lwt_promise.cmi +0 -0
- package/assets/interpreter/libs/js_of_ocaml_lwt__Lwt_xmlHttpRequest.cmi +0 -0
- package/assets/interpreter/libs/jsonm.cma +0 -0
- package/assets/interpreter/libs/jsonm.cmi +0 -0
- package/assets/interpreter/libs/jsoo_runtime.cma +0 -0
- package/assets/interpreter/libs/logs.cma +0 -0
- package/assets/interpreter/libs/logs.cmi +0 -0
- package/assets/interpreter/libs/lwt.cma +0 -0
- package/assets/interpreter/libs/lwt.cmi +0 -0
- package/assets/interpreter/libs/lwt_condition.cmi +0 -0
- package/assets/interpreter/libs/lwt_list.cmi +0 -0
- package/assets/interpreter/libs/lwt_mutex.cmi +0 -0
- package/assets/interpreter/libs/lwt_mvar.cmi +0 -0
- package/assets/interpreter/libs/lwt_pool.cmi +0 -0
- package/assets/interpreter/libs/lwt_pqueue.cmi +0 -0
- package/assets/interpreter/libs/lwt_result.cmi +0 -0
- package/assets/interpreter/libs/lwt_rte.cmi +0 -0
- package/assets/interpreter/libs/lwt_seq.cmi +0 -0
- package/assets/interpreter/libs/lwt_sequence.cmi +0 -0
- package/assets/interpreter/libs/lwt_stream.cmi +0 -0
- package/assets/interpreter/libs/lwt_switch.cmi +0 -0
- package/assets/interpreter/libs/manifest.txt +16 -0
- package/assets/interpreter/libs/q.cmi +0 -0
- package/assets/interpreter/libs/re.cma +0 -0
- package/assets/interpreter/libs/re.cmi +0 -0
- package/assets/interpreter/libs/re__.cmi +0 -0
- package/assets/interpreter/libs/re__Ast.cmi +0 -0
- package/assets/interpreter/libs/re__Automata.cmi +0 -0
- package/assets/interpreter/libs/re__Bit_vector.cmi +0 -0
- package/assets/interpreter/libs/re__Category.cmi +0 -0
- package/assets/interpreter/libs/re__Color_map.cmi +0 -0
- package/assets/interpreter/libs/re__Compile.cmi +0 -0
- package/assets/interpreter/libs/re__Core.cmi +0 -0
- package/assets/interpreter/libs/re__Cset.cmi +0 -0
- package/assets/interpreter/libs/re__Dense_map.cmi +0 -0
- package/assets/interpreter/libs/re__Dyn.cmi +0 -0
- package/assets/interpreter/libs/re__Emacs.cmi +0 -0
- package/assets/interpreter/libs/re__Fmt.cmi +0 -0
- package/assets/interpreter/libs/re__Glob.cmi +0 -0
- package/assets/interpreter/libs/re__Group.cmi +0 -0
- package/assets/interpreter/libs/re__Hash_set.cmi +0 -0
- package/assets/interpreter/libs/re__Import.cmi +0 -0
- package/assets/interpreter/libs/re__Mark_infos.cmi +0 -0
- package/assets/interpreter/libs/re__Parse_buffer.cmi +0 -0
- package/assets/interpreter/libs/re__Pcre.cmi +0 -0
- package/assets/interpreter/libs/re__Perl.cmi +0 -0
- package/assets/interpreter/libs/re__Pmark.cmi +0 -0
- package/assets/interpreter/libs/re__Posix.cmi +0 -0
- package/assets/interpreter/libs/re__Posix_class.cmi +0 -0
- package/assets/interpreter/libs/re__Replace.cmi +0 -0
- package/assets/interpreter/libs/re__Search.cmi +0 -0
- package/assets/interpreter/libs/re__Slice.cmi +0 -0
- package/assets/interpreter/libs/re__Str.cmi +0 -0
- package/assets/interpreter/libs/re__View.cmi +0 -0
- package/assets/interpreter/libs/str.cma +0 -0
- package/assets/interpreter/libs/str.cmi +0 -0
- package/assets/interpreter/libs/unix.cma +0 -0
- package/assets/interpreter/libs/unix.cmi +0 -0
- package/assets/interpreter/libs/unixLabels.cmi +0 -0
- package/assets/interpreter/libs/uutf.cma +0 -0
- package/assets/interpreter/libs/uutf.cmi +0 -0
- package/assets/interpreter/libs/xmlm.cma +0 -0
- package/assets/interpreter/libs/xmlm.cmi +0 -0
- package/assets/interpreter/libs/z.cmi +0 -0
- package/assets/interpreter/libs/zarith.cma +0 -0
- package/assets/interpreter/libs/zarith_stubs_js.cma +0 -0
- package/assets/interpreter/libs/zarith_stubs_js.cmi +0 -0
- package/assets/interpreter/worker.js +20246 -20050
- package/package.json +1 -1
- package/src/compiler/compile.js +156 -10
- package/src/compiler/worker.js +38 -2
|
@@ -0,0 +1,1246 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
|
|
3
|
+
// We represent a [Z.t] as a javascript 32bit integers or as a BigInt.
|
|
4
|
+
// Like in ZArith, we guarantee that:
|
|
5
|
+
// - If the number fits in a 32bit integer, it is stored in a 32bit integer,
|
|
6
|
+
// not a BigInt.
|
|
7
|
+
// - Conversely, if the number does not fit in a 32bit integer, it is stored in
|
|
8
|
+
// a BigInt. We almost could get away with using primitive integers up to 53
|
|
9
|
+
// bits, but this would require giving up marshaling (because the js_of_ocaml
|
|
10
|
+
// runtime assumes that numbers are either 32bit integers or floats, and
|
|
11
|
+
// refuses to marshal floats that are not exactly 32bit integers), and so we
|
|
12
|
+
// don't. I am not sure this would bring much performance benefits due to the
|
|
13
|
+
// additional checks required anyways (the checks for 32bit integers happen
|
|
14
|
+
// in ZArith's OCaml code, so we can't replace them with checks for 53 bit
|
|
15
|
+
// integers).
|
|
16
|
+
//
|
|
17
|
+
// Note that some functions in this module call other functions as utility in
|
|
18
|
+
// a way that doesn't respect these invariants, and so some functions can see
|
|
19
|
+
// non-normalized numbers as input.
|
|
20
|
+
|
|
21
|
+
//Provides: ml_z_normalize
|
|
22
|
+
function ml_z_normalize(x) {
|
|
23
|
+
if (typeof x === "number") {
|
|
24
|
+
if (x === (x | 0)) return x;
|
|
25
|
+
|
|
26
|
+
return BigInt(x);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (-2147483648 <= x && x <= 2147483647) return Number(x) | 0;
|
|
30
|
+
return x;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//external mul_overflows: int -> int -> bool
|
|
34
|
+
//Provides: ml_z_mul_overflows
|
|
35
|
+
function ml_z_mul_overflows(x, y) {
|
|
36
|
+
let z = x * y;
|
|
37
|
+
return +(z !== (z | 0));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//external init: unit -> unit
|
|
41
|
+
//Provides: ml_z_init
|
|
42
|
+
//Requires: caml_zarith_marshal, caml_zarith_unmarshal, caml_custom_ops
|
|
43
|
+
//Requires: ml_z_hash, ml_z_compare
|
|
44
|
+
function ml_z_init(unit) {
|
|
45
|
+
caml_custom_ops['_z'] =
|
|
46
|
+
{
|
|
47
|
+
serialize: caml_zarith_marshal,
|
|
48
|
+
deserialize: caml_zarith_unmarshal,
|
|
49
|
+
hash: ml_z_hash,
|
|
50
|
+
compare: ml_z_compare,
|
|
51
|
+
};
|
|
52
|
+
Object.defineProperty(BigInt.prototype, 'caml_custom', { value: '_z' });
|
|
53
|
+
return 0
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//external neg: t -> t
|
|
57
|
+
//Provides: ml_z_neg const
|
|
58
|
+
//Requires: ml_z_normalize
|
|
59
|
+
function ml_z_neg(z1) {
|
|
60
|
+
return ml_z_normalize(-z1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//external add: t -> t -> t
|
|
64
|
+
//Provides: ml_z_add const
|
|
65
|
+
//Requires: ml_z_normalize
|
|
66
|
+
function ml_z_add(z1, z2) {
|
|
67
|
+
return ml_z_normalize(BigInt(z1) + BigInt(z2));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//external sub: t -> t -> t
|
|
71
|
+
//Provides: ml_z_sub const
|
|
72
|
+
//Requires: ml_z_normalize
|
|
73
|
+
function ml_z_sub(z1, z2) {
|
|
74
|
+
return ml_z_normalize(BigInt(z1) - BigInt(z2));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//external mul: t -> t -> t
|
|
78
|
+
//Provides: ml_z_mul const
|
|
79
|
+
//Requires: ml_z_normalize
|
|
80
|
+
function ml_z_mul(z1, z2) {
|
|
81
|
+
return ml_z_normalize(BigInt(z1) * BigInt(z2));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//external div: t -> t -> t
|
|
85
|
+
//Provides: ml_z_div
|
|
86
|
+
//Requires: caml_raise_zero_divide, ml_z_normalize
|
|
87
|
+
function ml_z_div(z1, z2) {
|
|
88
|
+
if (z2 == 0) caml_raise_zero_divide();
|
|
89
|
+
return ml_z_normalize(BigInt(z1) / BigInt(z2));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//external cdiv: t -> t -> t
|
|
93
|
+
//Provides: ml_z_cdiv
|
|
94
|
+
//Requires: ml_z_div, ml_z_sign, ml_z_normalize
|
|
95
|
+
function ml_z_cdiv(z1, z2) {
|
|
96
|
+
let z1_pos = ml_z_sign(z1);
|
|
97
|
+
let z2_pos = ml_z_sign(z2);
|
|
98
|
+
if (z1_pos * z2_pos > 0) /* Multiplication is like a signwise xor */ {
|
|
99
|
+
if (BigInt(z1) % BigInt(z2) !== 0n) {
|
|
100
|
+
return ml_z_normalize(BigInt(z1) / BigInt(z2) + 1n);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return ml_z_div(z1, z2);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
//external fdiv: t -> t -> t
|
|
107
|
+
//Provides: ml_z_fdiv
|
|
108
|
+
//Requires: ml_z_div, ml_z_sign, ml_z_normalize
|
|
109
|
+
function ml_z_fdiv(z1, z2) {
|
|
110
|
+
let z1_pos = ml_z_sign(z1);
|
|
111
|
+
let z2_pos = ml_z_sign(z2);
|
|
112
|
+
if (z1_pos * z2_pos < 0) /* Multiplication is like a signwise xor */ {
|
|
113
|
+
if (BigInt(z1) % BigInt(z2) !== 0n) {
|
|
114
|
+
return ml_z_normalize(BigInt(z1) / BigInt(z2) - 1n);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return ml_z_div(z1, z2);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
//external rem: t -> t -> t
|
|
121
|
+
//Provides: ml_z_rem
|
|
122
|
+
//Requires: caml_raise_zero_divide, ml_z_normalize
|
|
123
|
+
function ml_z_rem(z1, z2) {
|
|
124
|
+
if (z2 == 0) caml_raise_zero_divide();
|
|
125
|
+
return ml_z_normalize(BigInt(z1) % BigInt(z2));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
//external div_rem: t -> t -> (t * t)
|
|
129
|
+
//Provides: ml_z_div_rem
|
|
130
|
+
//Requires: ml_z_div, ml_z_rem
|
|
131
|
+
function ml_z_div_rem(z1, z2) {
|
|
132
|
+
return [0, ml_z_div(z1, z2), ml_z_rem(z1, z2)]
|
|
133
|
+
}
|
|
134
|
+
//external succ: t -> t
|
|
135
|
+
//Provides: ml_z_succ const
|
|
136
|
+
//Requires: ml_z_normalize
|
|
137
|
+
function ml_z_succ(z1) {
|
|
138
|
+
return ml_z_normalize(BigInt(z1) + 1n);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
//external pred: t -> t
|
|
142
|
+
//Provides: ml_z_pred const
|
|
143
|
+
//Requires: ml_z_normalize
|
|
144
|
+
function ml_z_pred(z1) {
|
|
145
|
+
return ml_z_normalize(BigInt(z1) - 1n);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
//external abs: t -> t
|
|
149
|
+
//Provides: ml_z_abs const
|
|
150
|
+
//Requires: ml_z_normalize
|
|
151
|
+
function ml_z_abs(z1) {
|
|
152
|
+
if (z1 < 0) return ml_z_normalize(-z1);
|
|
153
|
+
return z1;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
//external logand: t -> t -> t
|
|
157
|
+
//Provides: ml_z_logand const
|
|
158
|
+
//Requires: ml_z_normalize
|
|
159
|
+
function ml_z_logand(z1, z2) {
|
|
160
|
+
return ml_z_normalize(BigInt(z1) & BigInt(z2));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
//external logor: t -> t -> t
|
|
164
|
+
//Provides: ml_z_logor const
|
|
165
|
+
//Requires: ml_z_normalize
|
|
166
|
+
function ml_z_logor(z1, z2) {
|
|
167
|
+
return ml_z_normalize(BigInt(z1) | BigInt(z2));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
//external logxor: t -> t -> t
|
|
171
|
+
//Provides: ml_z_logxor const
|
|
172
|
+
//Requires: ml_z_normalize
|
|
173
|
+
function ml_z_logxor(z1, z2) {
|
|
174
|
+
return ml_z_normalize(BigInt(z1) ^ BigInt(z2));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
//external lognot: t -> t
|
|
178
|
+
//Provides: ml_z_lognot const
|
|
179
|
+
//Requires: ml_z_normalize
|
|
180
|
+
function ml_z_lognot(z1) {
|
|
181
|
+
return ml_z_normalize(~z1);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
//external shift_left: t -> int -> t
|
|
185
|
+
//Provides: ml_z_shift_left const
|
|
186
|
+
//Requires: ml_z_normalize
|
|
187
|
+
function ml_z_shift_left(z1, amt) {
|
|
188
|
+
return ml_z_normalize(BigInt(z1) << BigInt(amt));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
//external shift_right: t -> int -> t
|
|
192
|
+
//Provides: ml_z_shift_right const
|
|
193
|
+
//Requires: ml_z_normalize
|
|
194
|
+
function ml_z_shift_right(z1, amt) {
|
|
195
|
+
return ml_z_normalize(BigInt(z1) >> BigInt(amt));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
//external shift_right_trunc: t -> int -> t
|
|
199
|
+
//Provides: ml_z_shift_right_trunc const
|
|
200
|
+
//Requires: ml_z_normalize
|
|
201
|
+
function ml_z_shift_right_trunc(z1, z2) {
|
|
202
|
+
return ml_z_normalize(BigInt(z1) / (1n << BigInt(z2)));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
//external of_int32: int32 -> t
|
|
206
|
+
//Provides: ml_z_of_int32 const
|
|
207
|
+
function ml_z_of_int32(i) {
|
|
208
|
+
return i | 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
//external of_nativeint: nativeint -> t
|
|
212
|
+
//Provides: ml_z_of_nativeint const
|
|
213
|
+
function ml_z_of_nativeint(i) {
|
|
214
|
+
return i | 0;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
//external of_int64: int64 -> t
|
|
218
|
+
//Provides: ml_z_of_int64 const
|
|
219
|
+
//Requires: caml_int64_compare, caml_int64_neg, ml_z_normalize
|
|
220
|
+
//Requires: caml_int64_create_lo_hi,caml_int64_hi32,caml_int64_lo32
|
|
221
|
+
function ml_z_of_int64(i64) {
|
|
222
|
+
let neg = false;
|
|
223
|
+
if (caml_int64_compare(i64, caml_int64_create_lo_hi(0, 0)) < 0) {
|
|
224
|
+
neg = true;
|
|
225
|
+
i64 = caml_int64_neg(i64)
|
|
226
|
+
}
|
|
227
|
+
let lo = caml_int64_lo32(i64) >>> 0;
|
|
228
|
+
let hi = caml_int64_hi32(i64) >>> 0;
|
|
229
|
+
let x = BigInt(lo) + (BigInt(hi) << 32n);
|
|
230
|
+
if (neg) { x = -x }
|
|
231
|
+
return ml_z_normalize(x)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
//external of_float: float -> t
|
|
235
|
+
//Provides: ml_z_of_float
|
|
236
|
+
//Requires: caml_raise_constant, caml_named_value, ml_z_normalize
|
|
237
|
+
function ml_z_of_float(f1) {
|
|
238
|
+
if (f1 == Infinity || f1 == -Infinity || f1 != f1)
|
|
239
|
+
caml_raise_constant(caml_named_value("ml_z_overflow"));
|
|
240
|
+
return ml_z_normalize(f1 < 0 ? Math.ceil(f1) : Math.floor(f1));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
//external to_int: t -> int
|
|
244
|
+
//Provides: ml_z_to_int
|
|
245
|
+
//Requires: caml_raise_constant, caml_named_value
|
|
246
|
+
function ml_z_to_int(z1) {
|
|
247
|
+
if (typeof z1 === "number" && z1 === (z1 | 0)) return z1;
|
|
248
|
+
caml_raise_constant(caml_named_value("ml_z_overflow"));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
//external to_int32: t -> int32
|
|
252
|
+
//Provides: ml_z_to_int32
|
|
253
|
+
//Requires: ml_z_to_int
|
|
254
|
+
function ml_z_to_int32(z1) { return ml_z_to_int(z1) }
|
|
255
|
+
|
|
256
|
+
//external to_int32_unsigned: t -> int32
|
|
257
|
+
//Provides: ml_z_to_int32_unsigned
|
|
258
|
+
//Requires: ml_z_fits_int32_unsigned, ml_z_normalize, caml_raise_constant
|
|
259
|
+
//Requires: caml_named_value
|
|
260
|
+
function ml_z_to_int32_unsigned(z1) {
|
|
261
|
+
if (ml_z_fits_int32_unsigned(z1)) {
|
|
262
|
+
return Number(BigInt.asIntN(32, BigInt(z1))) | 0;
|
|
263
|
+
}
|
|
264
|
+
caml_raise_constant(caml_named_value("ml_z_overflow"));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
//external to_nativeint_unsigned: t -> nativeint
|
|
268
|
+
//Provides: ml_z_to_nativeint_unsigned
|
|
269
|
+
//Requires: ml_z_to_int32_unsigned
|
|
270
|
+
function ml_z_to_nativeint_unsigned(z1) {
|
|
271
|
+
return ml_z_to_int32_unsigned(z1);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
//external to_int64: t -> int64
|
|
275
|
+
//Provides: ml_z_to_int64
|
|
276
|
+
//Requires: ml_z_fits_int64, caml_raise_constant, caml_named_value
|
|
277
|
+
//Requires: caml_int64_create_lo_hi
|
|
278
|
+
function ml_z_to_int64(z1) {
|
|
279
|
+
if (!ml_z_fits_int64(z1)) {
|
|
280
|
+
caml_raise_constant(caml_named_value("ml_z_overflow"));
|
|
281
|
+
}
|
|
282
|
+
let z1n = BigInt(z1)
|
|
283
|
+
let mask = 0xffffffffn
|
|
284
|
+
let lo = Number(z1n & mask);
|
|
285
|
+
let hi = Number((z1n >> 32n) & mask);
|
|
286
|
+
let x = caml_int64_create_lo_hi(lo, hi);
|
|
287
|
+
return x;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
//external to_int64_unsigned: t -> int64
|
|
291
|
+
//Provides: ml_z_to_int64_unsigned
|
|
292
|
+
//Requires: ml_z_fits_int64_unsigned, caml_raise_constant, caml_named_value
|
|
293
|
+
//Requires: caml_int64_create_lo_hi
|
|
294
|
+
function ml_z_to_int64_unsigned(z1) {
|
|
295
|
+
if (!ml_z_fits_int64_unsigned(z1)) {
|
|
296
|
+
caml_raise_constant(caml_named_value("ml_z_overflow"));
|
|
297
|
+
}
|
|
298
|
+
let z1n = BigInt.asIntN(64, BigInt(z1))
|
|
299
|
+
let mask = 0xffffffffn
|
|
300
|
+
let lo = Number(z1n & mask);
|
|
301
|
+
let hi = Number((z1n >> 32n) & mask);
|
|
302
|
+
let x = caml_int64_create_lo_hi(lo, hi);
|
|
303
|
+
return x;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
//external testbit: t -> int -> bool
|
|
307
|
+
//Provides: ml_z_testbit const
|
|
308
|
+
function ml_z_testbit(z, pos) {
|
|
309
|
+
return Number((BigInt(z) >> BigInt(pos)) & 1n);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
//external to_nativeint: t -> nativeint
|
|
313
|
+
//Provides: ml_z_to_nativeint
|
|
314
|
+
//Requires: ml_z_to_int
|
|
315
|
+
function ml_z_to_nativeint(z1) { return ml_z_to_int(z1) }
|
|
316
|
+
|
|
317
|
+
//external format: string -> t -> string
|
|
318
|
+
//Provides: ml_z_format
|
|
319
|
+
//Requires: caml_jsbytes_of_string, caml_failwith, caml_string_of_jsbytes
|
|
320
|
+
//Requires: ml_z_normalize
|
|
321
|
+
function ml_z_format(fmt, z1) {
|
|
322
|
+
let z1n = BigInt(z1);
|
|
323
|
+
fmt = caml_jsbytes_of_string(fmt);
|
|
324
|
+
// https://github.com/ocaml/Zarith/blob/d0555d451ce295c4497f24a8d9993f8dd23097df/z.mlip#L297
|
|
325
|
+
let base = 10;
|
|
326
|
+
let cas = 0;
|
|
327
|
+
let width = 0;
|
|
328
|
+
let alt = 0;
|
|
329
|
+
let dir = 0;
|
|
330
|
+
let sign = '';
|
|
331
|
+
let pad = ' ';
|
|
332
|
+
let idx = 0;
|
|
333
|
+
let prefix = "";
|
|
334
|
+
while (fmt[idx] == '%') idx++;
|
|
335
|
+
for (; ; idx++) {
|
|
336
|
+
if (fmt[idx] == '#') alt = 1;
|
|
337
|
+
else if (fmt[idx] == '0') pad = '0';
|
|
338
|
+
else if (fmt[idx] == '-') dir = 1;
|
|
339
|
+
else if (fmt[idx] == ' ' || fmt[idx] == '+') sign = fmt[idx];
|
|
340
|
+
else break;
|
|
341
|
+
}
|
|
342
|
+
if (z1n < 0) { sign = '-'; z1n = -z1n }
|
|
343
|
+
for (; fmt[idx] >= '0' && fmt[idx] <= '9'; idx++)
|
|
344
|
+
width = 10 * width + (+fmt[idx]);
|
|
345
|
+
switch (fmt[idx]) {
|
|
346
|
+
case 'i': case 'd': case 'u': break;
|
|
347
|
+
case 'b': base = 2; if (alt) prefix = "0b"; break;
|
|
348
|
+
case 'o': base = 8; if (alt) prefix = "0o"; break;
|
|
349
|
+
case 'x': base = 16; if (alt) prefix = "0x"; break;
|
|
350
|
+
case 'X': base = 16; if (alt) prefix = "0X"; cas = 1; break;
|
|
351
|
+
default:
|
|
352
|
+
caml_failwith("Unsupported format '" + fmt + "'");
|
|
353
|
+
}
|
|
354
|
+
if (dir) pad = ' ';
|
|
355
|
+
let res = z1n.toString(base);
|
|
356
|
+
if (cas === 1) {
|
|
357
|
+
res = res.toUpperCase();
|
|
358
|
+
}
|
|
359
|
+
let size = res.length;
|
|
360
|
+
if (pad == ' ') {
|
|
361
|
+
if (dir) {
|
|
362
|
+
res = sign + prefix + res;
|
|
363
|
+
for (; res.length < width;) res = res + pad;
|
|
364
|
+
} else {
|
|
365
|
+
res = sign + prefix + res;
|
|
366
|
+
for (; res.length < width;) res = pad + res;
|
|
367
|
+
}
|
|
368
|
+
} else {
|
|
369
|
+
let pre = sign + prefix;
|
|
370
|
+
for (; res.length + pre.length < width;) res = pad + res;
|
|
371
|
+
res = pre + res;
|
|
372
|
+
}
|
|
373
|
+
return caml_string_of_jsbytes(res);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
//Provides: jsoo_z_of_js_string_base
|
|
377
|
+
//Requires: caml_invalid_argument, ml_z_normalize
|
|
378
|
+
function jsoo_z_of_js_string_base(base, s) {
|
|
379
|
+
if (base == 0) { // https://github.com/ocaml/Zarith/blob/b8dbaf48a7927061df699ad7ce642bb4f1fe5308/caml_z.c#L598
|
|
380
|
+
base = 10;
|
|
381
|
+
let p = 0;
|
|
382
|
+
let sign = 1;
|
|
383
|
+
if (s[p] == '-') { sign = -1; p++ }
|
|
384
|
+
else if (s[p] == '+') { p++ }
|
|
385
|
+
if (s[p] == '0') {
|
|
386
|
+
p++;
|
|
387
|
+
if (s.length == p) {
|
|
388
|
+
return 0;
|
|
389
|
+
} else {
|
|
390
|
+
let bc = s[p];
|
|
391
|
+
if (bc == 'o' || bc == 'O') {
|
|
392
|
+
base = 8;
|
|
393
|
+
} else if (bc == 'x' || bc == 'X') {
|
|
394
|
+
base = 16;
|
|
395
|
+
} else if (bc == 'b' || bc == 'B') {
|
|
396
|
+
base = 2;
|
|
397
|
+
}
|
|
398
|
+
if (base != 10) {
|
|
399
|
+
s = s.substring(p + 1);
|
|
400
|
+
if (sign == -1) s = "-" + s;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function digit(code) {
|
|
407
|
+
if (code >= 48 && code <= 57) return code - 48;
|
|
408
|
+
if (code >= 97 && code <= 102) return code - 97 + 10;
|
|
409
|
+
if (code >= 65 && code <= 70) return code - 65 + 10;
|
|
410
|
+
}
|
|
411
|
+
let i = 0;
|
|
412
|
+
if (s[i] == '+') {
|
|
413
|
+
//remove leading '+'
|
|
414
|
+
s = s.substring(1);
|
|
415
|
+
}
|
|
416
|
+
else if (s[i] == '-') i++;
|
|
417
|
+
if (s[i] == '_') caml_invalid_argument("Z.of_substring_base: invalid digit");
|
|
418
|
+
s = s.replace(/_/g, '');
|
|
419
|
+
//normalize "empty" numbers
|
|
420
|
+
if (s == '-' || s == '') s = '0';
|
|
421
|
+
for (; i < s.length; i++) {
|
|
422
|
+
let c = digit(s.charCodeAt(i));
|
|
423
|
+
if (c == undefined || c >= base)
|
|
424
|
+
caml_invalid_argument("Z.of_substring_base: invalid digit");
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (base === 10) return ml_z_normalize(BigInt(s));
|
|
428
|
+
|
|
429
|
+
let neg = false;
|
|
430
|
+
i = 0;
|
|
431
|
+
if (s[i] == '-') { neg = true; i++; }
|
|
432
|
+
let n = 0n;
|
|
433
|
+
for (; i < s.length; i++) {
|
|
434
|
+
n *= BigInt(base);
|
|
435
|
+
n += BigInt(digit(s.charCodeAt(i)));
|
|
436
|
+
}
|
|
437
|
+
if (neg) n = -n;
|
|
438
|
+
return ml_z_normalize(n);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
//external of_substring_base: int -> string -> pos:int -> len:int -> t
|
|
442
|
+
//Provides: ml_z_of_substring_base
|
|
443
|
+
//Requires: jsoo_z_of_js_string_base, caml_jsbytes_of_string
|
|
444
|
+
//Requires: caml_invalid_argument, caml_ml_string_length
|
|
445
|
+
function ml_z_of_substring_base(base, s, pos, len) {
|
|
446
|
+
s = caml_jsbytes_of_string(s);
|
|
447
|
+
if (pos != 0 || len != s.length) {
|
|
448
|
+
if (s.length - pos < len) {
|
|
449
|
+
caml_invalid_argument("Z.of_substring_base: invalid offset or length");
|
|
450
|
+
}
|
|
451
|
+
s = s.slice(pos, pos + len);
|
|
452
|
+
}
|
|
453
|
+
return jsoo_z_of_js_string_base(base, s);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
//external compare: t -> t -> int
|
|
457
|
+
//Provides: ml_z_compare const
|
|
458
|
+
function ml_z_compare(z1, z2) {
|
|
459
|
+
return z1 == z2 ? 0 : z1 > z2 ? 1 : -1;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
//external equal: t -> t -> bool
|
|
463
|
+
//Provides: ml_z_equal const
|
|
464
|
+
function ml_z_equal(z1, z2) {
|
|
465
|
+
return z1 == z2 ? 1 : 0;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
//external sign: t -> int
|
|
469
|
+
//Provides: ml_z_sign const
|
|
470
|
+
function ml_z_sign(z1) {
|
|
471
|
+
return z1 == 0 ? 0 : z1 > 0 ? 1 : -1;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
//external gcd: t -> t -> t
|
|
475
|
+
//Provides: ml_z_gcd
|
|
476
|
+
//Requires: ml_z_normalize
|
|
477
|
+
function ml_z_gcd(z1, z2) {
|
|
478
|
+
let a = BigInt(z1);
|
|
479
|
+
if (a < 0) a = -a;
|
|
480
|
+
let b = BigInt(z2);
|
|
481
|
+
if (b < 0) b = -b;
|
|
482
|
+
if (a === b) return ml_z_normalize(a);
|
|
483
|
+
if (a === 0n) return ml_z_normalize(b);
|
|
484
|
+
if (b === 0n) return ml_z_normalize(a);
|
|
485
|
+
let c = 1n, d, t;
|
|
486
|
+
function min(a, b) { return a < b ? a : b }
|
|
487
|
+
while ((a & 1n) === 0n && (b & 1n) === 0n) {
|
|
488
|
+
d = min(a & -a, b & -b);
|
|
489
|
+
a /= d;
|
|
490
|
+
b /= d;
|
|
491
|
+
c *= d;
|
|
492
|
+
}
|
|
493
|
+
while ((a & 1n) === 0n) {
|
|
494
|
+
a /= a & -a;
|
|
495
|
+
}
|
|
496
|
+
do {
|
|
497
|
+
while ((b & 1n) === 0n) {
|
|
498
|
+
b /= b & -b;
|
|
499
|
+
}
|
|
500
|
+
if (a > b) {
|
|
501
|
+
t = b; b = a; a = t;
|
|
502
|
+
}
|
|
503
|
+
b -= a;
|
|
504
|
+
} while (b !== 0n);
|
|
505
|
+
return ml_z_normalize(c === 1n ? a : a * c);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
//external numbits: t -> int
|
|
509
|
+
//Provides: ml_z_numbits const
|
|
510
|
+
function ml_z_numbits(z1) {
|
|
511
|
+
if (z1 < 0) z1 = -z1;
|
|
512
|
+
let n = 0;
|
|
513
|
+
let upperBound = 1n;
|
|
514
|
+
while (upperBound <= z1) {
|
|
515
|
+
n += 1;
|
|
516
|
+
upperBound = upperBound << 1n;
|
|
517
|
+
}
|
|
518
|
+
return n; // 2^{n-1} <= |x| < 2^n
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
//external fits_int: t -> bool
|
|
522
|
+
//Provides: ml_z_fits_int const
|
|
523
|
+
function ml_z_fits_int(z1) {
|
|
524
|
+
return typeof z1 === "number" ? +(z1 === (z1 | 0)) : 0;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
//external fits_int32: t -> bool
|
|
528
|
+
//Provides: ml_z_fits_int32
|
|
529
|
+
//Requires: ml_z_fits_int
|
|
530
|
+
function ml_z_fits_int32(z1) {
|
|
531
|
+
return ml_z_fits_int(z1);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
//external fits_int32_unsigned: t -> bool
|
|
535
|
+
//Provides: ml_z_fits_int32_unsigned
|
|
536
|
+
function ml_z_fits_int32_unsigned(z1) {
|
|
537
|
+
return 0 <= z1 && z1 <= 4294967295;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
//external fits_int64_unsigned: t -> bool
|
|
541
|
+
//Provides: ml_z_fits_int64_unsigned
|
|
542
|
+
function ml_z_fits_int64_unsigned(z1) {
|
|
543
|
+
return 0 <= z1 && z1 <= 18446744073709551615n;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
//external fits_nativeint_unsigned: t -> bool
|
|
547
|
+
//Provides: ml_z_fits_nativeint_unsigned
|
|
548
|
+
//Requires: ml_z_fits_int32_unsigned
|
|
549
|
+
function ml_z_fits_nativeint_unsigned(z1) {
|
|
550
|
+
return ml_z_fits_int32_unsigned(z1);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
//external fits_int64: t -> bool
|
|
555
|
+
//Provides: ml_z_fits_int64
|
|
556
|
+
function ml_z_fits_int64(z1) {
|
|
557
|
+
if (z1 <= 9223372036854775807n && z1 >= -9223372036854775808n)
|
|
558
|
+
return 1
|
|
559
|
+
else
|
|
560
|
+
return 0
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
//external fits_nativeint: t -> bool
|
|
564
|
+
//Provides: ml_z_fits_nativeint
|
|
565
|
+
//Requires: ml_z_fits_int
|
|
566
|
+
function ml_z_fits_nativeint(z1) {
|
|
567
|
+
return ml_z_fits_int(z1);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
//external powm: t -> t -> t -> t
|
|
571
|
+
//Provides: ml_z_powm
|
|
572
|
+
//Requires: ml_z_normalize, ml_z_invert, caml_raise_zero_divide
|
|
573
|
+
//Requires: jsoo_bigint_mod_pow
|
|
574
|
+
function ml_z_powm(z1, z2, z3) {
|
|
575
|
+
if (z3 == 0) caml_raise_zero_divide();
|
|
576
|
+
if (z3 == 1 || z3 == -1) return 0;
|
|
577
|
+
if (z2 == 0) return 1;
|
|
578
|
+
let z3n = BigInt(z3);
|
|
579
|
+
if (z2 < 0) {
|
|
580
|
+
let inv = BigInt(ml_z_invert(z1, z3));
|
|
581
|
+
let r = jsoo_bigint_mod_pow(inv, BigInt(-z2), z3n);
|
|
582
|
+
if (r < 0) r = r + (z3n < 0 ? -z3n : z3n);
|
|
583
|
+
return ml_z_normalize(r);
|
|
584
|
+
} else {
|
|
585
|
+
let r = jsoo_bigint_mod_pow(BigInt(z1), BigInt(z2), z3n);
|
|
586
|
+
if (r < 0) r = r + (z3n < 0 ? -z3n : z3n);
|
|
587
|
+
return ml_z_normalize(r);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
//external pown: t -> t -> t
|
|
592
|
+
//Provides: ml_z_pow
|
|
593
|
+
//Requires: caml_failwith, ml_z_normalize, caml_invalid_argument
|
|
594
|
+
function ml_z_pow(z1, i1) {
|
|
595
|
+
if (i1 < 0) {
|
|
596
|
+
caml_invalid_argument("Z.pow: exponent must be nonnegative");
|
|
597
|
+
}
|
|
598
|
+
return ml_z_normalize(BigInt(z1) ** BigInt(i1));
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
//external hash: t -> int
|
|
602
|
+
//Provides: ml_z_hash const
|
|
603
|
+
//Requires: caml_hash_mix_int
|
|
604
|
+
function ml_z_hash(z1) {
|
|
605
|
+
let z1n = BigInt(z1);
|
|
606
|
+
let neg = z1n < 0;
|
|
607
|
+
if (neg) z1n = -z1n;
|
|
608
|
+
|
|
609
|
+
let acc = 0, len = 1;
|
|
610
|
+
let left = z1n;
|
|
611
|
+
while (left >= 2 ** 32) {
|
|
612
|
+
acc = caml_hash_mix_int(acc, Number(left & 0xffffffffn));
|
|
613
|
+
left >>= 32n;
|
|
614
|
+
len += 1;
|
|
615
|
+
}
|
|
616
|
+
acc = caml_hash_mix_int(acc, Number(left) | 0);
|
|
617
|
+
if (len % 2 !== 0) {
|
|
618
|
+
acc = caml_hash_mix_int(acc, 0);
|
|
619
|
+
}
|
|
620
|
+
if (neg) {
|
|
621
|
+
acc = acc + 1
|
|
622
|
+
}
|
|
623
|
+
return acc | 0
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
//external to_bits: t -> string
|
|
627
|
+
//Provides: ml_z_to_bits const
|
|
628
|
+
//Requires: caml_string_of_jsbytes, caml_str_repeat
|
|
629
|
+
function ml_z_to_bits(z1) {
|
|
630
|
+
let z1n = BigInt(z1);
|
|
631
|
+
if (z1n < 0) z1n = -z1n;
|
|
632
|
+
let res = "";
|
|
633
|
+
while (z1n !== 0n) {
|
|
634
|
+
res += String.fromCharCode(Number(z1n % 256n) | 0);
|
|
635
|
+
z1n /= 256n;
|
|
636
|
+
}
|
|
637
|
+
while (res.length % 4 != 0) {
|
|
638
|
+
res += String.fromCharCode(0);
|
|
639
|
+
}
|
|
640
|
+
return caml_string_of_jsbytes(res);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
//external of_bits: string -> t
|
|
644
|
+
//Provides: ml_z_of_bits const
|
|
645
|
+
//Requires: caml_string_unsafe_get, caml_ml_string_length, ml_z_normalize
|
|
646
|
+
function ml_z_of_bits(z1) {
|
|
647
|
+
let r = 0n;
|
|
648
|
+
let base = 1n;
|
|
649
|
+
for (let i = 0; i < caml_ml_string_length(z1); i++) {
|
|
650
|
+
let d = caml_string_unsafe_get(z1, i);
|
|
651
|
+
r += base * BigInt(d);
|
|
652
|
+
base *= 256n;
|
|
653
|
+
}
|
|
654
|
+
return ml_z_normalize(r);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
//external powm_sec: t -> t -> t -> t
|
|
658
|
+
//Provides: ml_z_powm_sec
|
|
659
|
+
//Requires: caml_failwith, ml_z_powm, caml_invalid_argument
|
|
660
|
+
function ml_z_powm_sec(z1, z2, z3) {
|
|
661
|
+
if (z1 < 0) z3 = -z3;
|
|
662
|
+
// powm_sec requires that the exponent be positive
|
|
663
|
+
if (z2 < 1) {
|
|
664
|
+
caml_invalid_argument("Z.powm_sec: exponent must be positive");
|
|
665
|
+
}
|
|
666
|
+
if ((BigInt(z3) & 1n) !== 1n) {
|
|
667
|
+
caml_invalid_argument("Z.powm_sec: modulus must be odd");
|
|
668
|
+
}
|
|
669
|
+
return ml_z_powm(z1, z2, z3)
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
//external root: t -> int -> t
|
|
673
|
+
//Provides: ml_z_root
|
|
674
|
+
//Requires: ml_z_pow, ml_z_normalize, caml_invalid_argument
|
|
675
|
+
function ml_z_root(z, i) {
|
|
676
|
+
if (i % 2 === 0 && z < 0) {
|
|
677
|
+
caml_invalid_argument("Z.root: even root of a negative number");
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
if (z == 0 || z == 1) {
|
|
681
|
+
return Number(z) | 0;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
let start = 0n;
|
|
685
|
+
let end = BigInt(z);
|
|
686
|
+
let ans = 0n;
|
|
687
|
+
|
|
688
|
+
let bigi = BigInt(i);
|
|
689
|
+
while (start <= end) {
|
|
690
|
+
let mid = (start + end) / 2n;
|
|
691
|
+
let po = mid ** bigi;
|
|
692
|
+
if (po == z) {
|
|
693
|
+
return ml_z_normalize(mid);
|
|
694
|
+
} else if (po < z) {
|
|
695
|
+
start = mid + 1n;
|
|
696
|
+
ans = mid;
|
|
697
|
+
} else {
|
|
698
|
+
end = mid - 1n;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
return ml_z_normalize(ans);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
//external rootrem: t -> int -> t * t
|
|
705
|
+
//Provides: ml_z_rootrem
|
|
706
|
+
//Requires: ml_z_pow, ml_z_normalize, caml_invalid_argument
|
|
707
|
+
function ml_z_rootrem(z, i) {
|
|
708
|
+
if (i % 2 === 0 && z < 0) {
|
|
709
|
+
caml_invalid_argument("Z.rootrem: even root of a negative number");
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
if (z == 0 || z === 1) {
|
|
713
|
+
return [0, Number(z) | 0, 0];
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
let start = 0n;
|
|
717
|
+
let end = BigInt(z);
|
|
718
|
+
let ans = 0n;
|
|
719
|
+
|
|
720
|
+
let bigi = BigInt(i);
|
|
721
|
+
while (start <= end) {
|
|
722
|
+
let mid = (start + end) / 2n;
|
|
723
|
+
let po = mid ** bigi;
|
|
724
|
+
if (po == z) {
|
|
725
|
+
return [0, ml_z_normalize(mid), 0];
|
|
726
|
+
} else if (po < z) {
|
|
727
|
+
start = mid + 1n;
|
|
728
|
+
ans = mid;
|
|
729
|
+
} else {
|
|
730
|
+
end = mid - 1n;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
return [0, ml_z_normalize(ans), ml_z_normalize(BigInt(z) - (ans ** bigi))];
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
//external invert: t -> t -> t
|
|
737
|
+
//Provides: ml_z_invert
|
|
738
|
+
//Requires: caml_raise_zero_divide, ml_z_gcdext_intern, ml_z_normalize
|
|
739
|
+
function ml_z_invert(a, n) {
|
|
740
|
+
// Because [a.modInv(n)] produces different results for edge cases,
|
|
741
|
+
// we wrote our own implementation based on gcdext_intern.
|
|
742
|
+
if (n == 1 || n == -1)
|
|
743
|
+
return 0;
|
|
744
|
+
if (n == 0 && (a == 1 || a == -1)) {
|
|
745
|
+
return a;
|
|
746
|
+
}
|
|
747
|
+
if (n == 0 || a == 0) {
|
|
748
|
+
caml_raise_zero_divide();
|
|
749
|
+
}
|
|
750
|
+
let x = ml_z_gcdext_intern(a, n);
|
|
751
|
+
let r = BigInt(x[2]);
|
|
752
|
+
a = BigInt(a);
|
|
753
|
+
n = BigInt(n);
|
|
754
|
+
if (n < 0) n = -n;
|
|
755
|
+
let tmp = (a * r) % n;
|
|
756
|
+
if (tmp < 0) tmp += n;
|
|
757
|
+
if (r < 0) r += n;
|
|
758
|
+
if (tmp == 1) {
|
|
759
|
+
return ml_z_normalize(r);
|
|
760
|
+
}
|
|
761
|
+
caml_raise_zero_divide();
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
//external perfect_power: t -> bool
|
|
765
|
+
//Provides: ml_z_perfect_power
|
|
766
|
+
//Requires: caml_failwith, ml_z_numbits, ml_z_root, ml_z_pow
|
|
767
|
+
function ml_z_perfect_power(z) {
|
|
768
|
+
// Return true if op is a perfect power, i.e., if there exist integers a and
|
|
769
|
+
// b, with b > 1, such that op = a^b.
|
|
770
|
+
// Otherwise false.
|
|
771
|
+
if (z == 0 || z == 1 || z == -1) return 1;
|
|
772
|
+
|
|
773
|
+
let zp = z < 0 ? -z : z;
|
|
774
|
+
let log2z = ml_z_numbits(zp);
|
|
775
|
+
for (let b = 2; b <= log2z; b++) {
|
|
776
|
+
if (z < 0 && b % 2 == 0) continue;
|
|
777
|
+
let p = ml_z_root(zp, b);
|
|
778
|
+
if (z < 0) p = -p;
|
|
779
|
+
let r = ml_z_pow(p, b);
|
|
780
|
+
if (z == r) {
|
|
781
|
+
return 1;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return 0;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
//external perfect_square: t -> bool
|
|
788
|
+
//Provides: ml_z_perfect_square
|
|
789
|
+
//Requires: ml_z_root
|
|
790
|
+
function ml_z_perfect_square(z) {
|
|
791
|
+
if (z < 0) return 0;
|
|
792
|
+
let root = BigInt(ml_z_root(z, 2));
|
|
793
|
+
if (root * root == z) {
|
|
794
|
+
return 1;
|
|
795
|
+
} else {
|
|
796
|
+
return 0
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
//Must have 0 <= low <= high
|
|
801
|
+
//Provides: jsoo_bigint_rand_between
|
|
802
|
+
function jsoo_bigint_rand_between(low, high) {
|
|
803
|
+
let range = high - low + 1n;
|
|
804
|
+
let base = 1e7, bigbase = BigInt(base);
|
|
805
|
+
let result = 0n, restricted = true;
|
|
806
|
+
|
|
807
|
+
let digits = [];
|
|
808
|
+
while (range >= bigbase) {
|
|
809
|
+
digits.push(Number(range % bigbase));
|
|
810
|
+
range /= bigbase;
|
|
811
|
+
}
|
|
812
|
+
digits.push(Number(range));
|
|
813
|
+
digits.reverse();
|
|
814
|
+
|
|
815
|
+
for (let i = 0; i < digits.length; i++) {
|
|
816
|
+
let top = restricted ? digits[i] | 0 : base;
|
|
817
|
+
range /= bigbase;
|
|
818
|
+
let digit = Math.floor(Math.random() * top);
|
|
819
|
+
result *= bigbase;
|
|
820
|
+
result += BigInt(digit);
|
|
821
|
+
if (digit < top) restricted = false;
|
|
822
|
+
}
|
|
823
|
+
return low + result;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
//Provides: jsoo_bigint_mod_pow
|
|
827
|
+
function jsoo_bigint_mod_pow(self, exp, mod) {
|
|
828
|
+
if (mod === 0n) throw new Error("Cannot take modPow with modulo 0");
|
|
829
|
+
if (exp < 0) throw new Error("Cannot take modPow with negative exponent");
|
|
830
|
+
let r = 1n, base = self % mod;
|
|
831
|
+
while (exp > 0) {
|
|
832
|
+
if (base === 0n) return 0n;
|
|
833
|
+
if ((exp & 1n) === 1n) r = (r * base) % mod;
|
|
834
|
+
exp >>= 1n;
|
|
835
|
+
base = (base * base) % mod;
|
|
836
|
+
}
|
|
837
|
+
return r;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
//external probab_prime: t -> int -> int
|
|
841
|
+
//Provides: ml_z_probab_prime const
|
|
842
|
+
//Requires: jsoo_bigint_mod_pow, jsoo_bigint_rand_between
|
|
843
|
+
//Note: called with [1n] from [ml_z_primorial]
|
|
844
|
+
function ml_z_probab_prime(z, i) {
|
|
845
|
+
if (z < 0) z = -z;
|
|
846
|
+
|
|
847
|
+
// Test for basic primes (multiples of 2, 3, 5)
|
|
848
|
+
if (z == 1) return 0;
|
|
849
|
+
if (z == 2 || z == 3 || z == 5) return 1;
|
|
850
|
+
let n = BigInt(z);
|
|
851
|
+
if (n % 2n === 0n || n % 3n === 0n || n % 5n === 0n) return 0;
|
|
852
|
+
if (z < 49) return 1;
|
|
853
|
+
|
|
854
|
+
// Miller-Rabin test
|
|
855
|
+
let nPrev = n - 1n,
|
|
856
|
+
b = nPrev,
|
|
857
|
+
r = 0,
|
|
858
|
+
a, d, j, x;
|
|
859
|
+
while (b % 2n === 0n) b /= 2n, r++;
|
|
860
|
+
next: for (j = 0; j < i; j++) {
|
|
861
|
+
a = jsoo_bigint_rand_between(2n, n - 2n);
|
|
862
|
+
x = jsoo_bigint_mod_pow(a, b, n);
|
|
863
|
+
if (x === 1n || x === nPrev) continue;
|
|
864
|
+
for (d = r - 1; d != 0; d--) {
|
|
865
|
+
x = (x * x) % n;
|
|
866
|
+
if (x === 1n) return 0;
|
|
867
|
+
if (x === nPrev) continue next;
|
|
868
|
+
}
|
|
869
|
+
return 0;
|
|
870
|
+
}
|
|
871
|
+
return 1;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
//external nextprime: t -> t
|
|
875
|
+
//Provides: ml_z_nextprime const
|
|
876
|
+
//Requires: ml_z_normalize, ml_z_probab_prime
|
|
877
|
+
function ml_z_nextprime(z1) {
|
|
878
|
+
// Interestingly, the zarith next_prime only returns
|
|
879
|
+
// probabalistic primes. We do the same, with the
|
|
880
|
+
// same probablistic parameter of 25.
|
|
881
|
+
// https://fossies.org/dox/gmp-6.1.2/mpz_2nextprime_8c_source.html
|
|
882
|
+
|
|
883
|
+
if (z1 < 1 || z1 == 1) {
|
|
884
|
+
return 2;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
let z1n = BigInt(z1)
|
|
888
|
+
if ((z1n & 1n) === 1n) {
|
|
889
|
+
z1n += 2n;
|
|
890
|
+
} else {
|
|
891
|
+
z1n += 1n;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
for (; ;) {
|
|
895
|
+
if (ml_z_probab_prime(z1n, 25)) {
|
|
896
|
+
return ml_z_normalize(z1n);
|
|
897
|
+
} else {
|
|
898
|
+
z1n += 2n;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
//external c_extract: t -> int -> int -> t
|
|
904
|
+
//Provides: ml_z_extract
|
|
905
|
+
//Requires: caml_failwith, ml_z_normalize
|
|
906
|
+
function ml_z_extract(z1, pos, len) {
|
|
907
|
+
return ml_z_normalize((BigInt(z1) >> BigInt(pos)) & ((1n << BigInt(len)) - 1n));
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
//external c_extract_small: t -> int -> int -> t
|
|
911
|
+
//Provides: ml_z_extract_small
|
|
912
|
+
function ml_z_extract_small(z1, pos, len) {
|
|
913
|
+
return Number(BigInt.asIntN(32, z1 >> BigInt(pos))) & ((1 << len) - 1);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
//external gcdext_intern: t -> t -> (t * t * bool)
|
|
917
|
+
//Provides: ml_z_gcdext_intern
|
|
918
|
+
//Requires: caml_raise_zero_divide, ml_z_normalize
|
|
919
|
+
function ml_z_gcdext_intern(z1, z2) {
|
|
920
|
+
if (z1 == 0) caml_raise_zero_divide();
|
|
921
|
+
let a = BigInt(z1);
|
|
922
|
+
let b = BigInt(z2);
|
|
923
|
+
let x = 0n;
|
|
924
|
+
let lastx = 1n;
|
|
925
|
+
let y = 1n;
|
|
926
|
+
let lasty = 1n;
|
|
927
|
+
let q, t, r;
|
|
928
|
+
while (b !== 0n) {
|
|
929
|
+
q = a / b;
|
|
930
|
+
r = a - q * b;
|
|
931
|
+
t = x;
|
|
932
|
+
x = lastx - q * x;
|
|
933
|
+
lastx = t;
|
|
934
|
+
t = y;
|
|
935
|
+
y = lasty - q * y;
|
|
936
|
+
lasty = t;
|
|
937
|
+
a = b;
|
|
938
|
+
b = r;
|
|
939
|
+
}
|
|
940
|
+
if (a < 0)
|
|
941
|
+
return [0, ml_z_normalize(-a), ml_z_normalize(-lastx), 1]
|
|
942
|
+
else
|
|
943
|
+
return [0, ml_z_normalize(a), ml_z_normalize(lastx), 1]
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
//external sqrt: t -> t
|
|
947
|
+
//Provides: ml_z_sqrt
|
|
948
|
+
//Requires: ml_z_root, caml_invalid_argument
|
|
949
|
+
function ml_z_sqrt(z1) {
|
|
950
|
+
if (z1 < 0) {
|
|
951
|
+
caml_invalid_argument("Z.sqrt: square root of a negative number");
|
|
952
|
+
}
|
|
953
|
+
return ml_z_root(z1, 2);
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
//external sqrt_rem: t -> (t * t)
|
|
957
|
+
//Provides: ml_z_sqrt_rem
|
|
958
|
+
//Requires: ml_z_root, caml_invalid_argument, ml_z_normalize
|
|
959
|
+
function ml_z_sqrt_rem(z) {
|
|
960
|
+
if (z < 0) {
|
|
961
|
+
caml_invalid_argument("Z.sqrt_rem: square root of a negative number");
|
|
962
|
+
}
|
|
963
|
+
let root = ml_z_root(z, 2);
|
|
964
|
+
let rootn = BigInt(root);
|
|
965
|
+
let diff = BigInt(z) - rootn * rootn;
|
|
966
|
+
return [0, root, ml_z_normalize(diff)]
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
//external trailing_zeros: t -> int
|
|
970
|
+
//Provides: ml_z_trailing_zeros const
|
|
971
|
+
function ml_z_trailing_zeros(z) {
|
|
972
|
+
if (z == 0) {
|
|
973
|
+
// max_int in 32bit
|
|
974
|
+
return 0x7fffffff;
|
|
975
|
+
}
|
|
976
|
+
if (z < 0) z = -z;
|
|
977
|
+
let zn = BigInt(z);
|
|
978
|
+
let i = 0;
|
|
979
|
+
zn = (zn ^ (zn - 1n)) >> 1n;
|
|
980
|
+
for (i = 0; zn !== 0n; i++) zn >>= 1n;
|
|
981
|
+
return i;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
//external popcount: t -> int
|
|
985
|
+
//Provides: ml_z_popcount
|
|
986
|
+
//Requires: caml_raise_constant, caml_named_value
|
|
987
|
+
function ml_z_popcount(z) {
|
|
988
|
+
if (z < 0) {
|
|
989
|
+
caml_raise_constant(caml_named_value("ml_z_overflow"));
|
|
990
|
+
}
|
|
991
|
+
z = BigInt(z);
|
|
992
|
+
let i;
|
|
993
|
+
for (i = 0; z !== 0n; i++) {
|
|
994
|
+
z &= z - 1n;
|
|
995
|
+
}
|
|
996
|
+
if (i !== (i | 0)) caml_raise_constant(caml_named_value("ml_z_overflow"));
|
|
997
|
+
return i | 0;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
//external hamdist: t -> t -> int
|
|
1001
|
+
//Provides: ml_z_hamdist
|
|
1002
|
+
//Requires: ml_z_popcount, caml_invalid_argument, caml_raise_constant
|
|
1003
|
+
//Requires: caml_named_value, ml_z_normalize
|
|
1004
|
+
function ml_z_hamdist(z1, z2) {
|
|
1005
|
+
if ((z1 < 0) !== (z2 < 0)) {
|
|
1006
|
+
caml_raise_constant(caml_named_value("ml_z_overflow"));
|
|
1007
|
+
}
|
|
1008
|
+
if ((typeof z1 == 'bignum' || typeof z2 == 'bignum') && (z1 < 0 || z2 < 0)) {
|
|
1009
|
+
caml_invalid_argument("Z.hamdist: negative arguments");
|
|
1010
|
+
}
|
|
1011
|
+
return ml_z_popcount(BigInt(z1) ^ BigInt(z2));
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
//external size: t -> int
|
|
1015
|
+
//Provides: ml_z_size const
|
|
1016
|
+
function ml_z_size(z1) {
|
|
1017
|
+
// Claim to be a 32-bit architecture.
|
|
1018
|
+
if (z1 < 0) z1 = -z1;
|
|
1019
|
+
let z1n = BigInt(z1);
|
|
1020
|
+
let len = 1;
|
|
1021
|
+
while (z1n >= 2 ** 32) { len += 1; z1n >>= 32n; }
|
|
1022
|
+
return len | 0;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
//external divexact: t -> t -> t
|
|
1026
|
+
//Provides: ml_z_divexact
|
|
1027
|
+
//Requires: ml_z_div
|
|
1028
|
+
function ml_z_divexact(z1, z2) {
|
|
1029
|
+
return ml_z_div(z1, z2);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
//Provides: caml_zarith_marshal
|
|
1034
|
+
function caml_zarith_marshal(writer, v, sz) {
|
|
1035
|
+
let vn = BigInt(v);
|
|
1036
|
+
let neg = vn < 0;
|
|
1037
|
+
if (neg) vn = -vn;
|
|
1038
|
+
let bits = [];
|
|
1039
|
+
while (vn >= 2 ** 32) {
|
|
1040
|
+
bits.push(Number(vn & 0xffffffffn));
|
|
1041
|
+
vn >>= 32n;
|
|
1042
|
+
}
|
|
1043
|
+
bits.push(Number(vn) | 0);
|
|
1044
|
+
writer.write(8, neg ? 1 : 0);
|
|
1045
|
+
let block = bits.length;
|
|
1046
|
+
let len = block * 4;
|
|
1047
|
+
writer.write(32, len);
|
|
1048
|
+
for (let i = 0; i < block; i++) {
|
|
1049
|
+
writer.write(8, (bits[i] >>> 0) & 0xff);
|
|
1050
|
+
writer.write(8, (bits[i] >>> 8) & 0xff);
|
|
1051
|
+
writer.write(8, (bits[i] >>> 16) & 0xff);
|
|
1052
|
+
writer.write(8, (bits[i] >>> 24) & 0xff);
|
|
1053
|
+
}
|
|
1054
|
+
sz[0] = 4 * (1 + (((len + 3) / 4) | 0));
|
|
1055
|
+
sz[1] = 8 * (1 + (((len + 7) / 8) | 0));
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
//Provides: caml_zarith_unmarshal
|
|
1059
|
+
//Requires: caml_failwith, ml_z_normalize
|
|
1060
|
+
function caml_zarith_unmarshal(reader, sz) {
|
|
1061
|
+
let negate;
|
|
1062
|
+
switch (reader.read8u()) {
|
|
1063
|
+
case 1: negate = true; break;
|
|
1064
|
+
case 0: negate = false; break;
|
|
1065
|
+
default: caml_failwith("input_value: z (malformed input)");
|
|
1066
|
+
}
|
|
1067
|
+
let len = reader.read32u();
|
|
1068
|
+
let x = 0n;
|
|
1069
|
+
for (let i = 0; i < len / 4; i++) {
|
|
1070
|
+
let y = reader.read8u();
|
|
1071
|
+
y |= reader.read8u() << 8
|
|
1072
|
+
y |= reader.read8u() << 16
|
|
1073
|
+
y |= reader.read8u() << 24
|
|
1074
|
+
x |= BigInt.asUintN(32, BigInt(y)) << (BigInt(i) * 32n);
|
|
1075
|
+
}
|
|
1076
|
+
if (negate) x = -x;
|
|
1077
|
+
sz[0] = len + 4;
|
|
1078
|
+
return ml_z_normalize(x)
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
//Provides: ml_z_divisible
|
|
1082
|
+
function ml_z_divisible(a, b) {
|
|
1083
|
+
if (a == 0 && b == 0) return 1;
|
|
1084
|
+
if (b == 0) return 0;
|
|
1085
|
+
if (b == 1) return 1;
|
|
1086
|
+
if (b == 2 || b == -2) return +((BigInt(a) & 1n) === 0n);
|
|
1087
|
+
return +((BigInt(a) % BigInt(b)) === 0n);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
//Provides: ml_z_congruent
|
|
1091
|
+
//Requires: ml_z_divisible
|
|
1092
|
+
function ml_z_congruent(a, b, c) {
|
|
1093
|
+
return ml_z_divisible(BigInt(a) - BigInt(b), c);
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
//external remove : t -> t -> t * int
|
|
1097
|
+
//Provides: ml_z_remove
|
|
1098
|
+
//Requires: ml_z_normalize, caml_raise_zero_divide
|
|
1099
|
+
function ml_z_remove(a, b) {
|
|
1100
|
+
if (b == 0) caml_raise_zero_divide();
|
|
1101
|
+
if (a == 0 || b == 1 || b == -1) return [0, a, 0];
|
|
1102
|
+
let i = 0;
|
|
1103
|
+
a = BigInt(a);
|
|
1104
|
+
b = BigInt(b);
|
|
1105
|
+
while ((a % b) === 0n) {
|
|
1106
|
+
a /= b;
|
|
1107
|
+
i++;
|
|
1108
|
+
}
|
|
1109
|
+
return [0, ml_z_normalize(a), i];
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
//external fac : int -> t
|
|
1113
|
+
//Provides: ml_z_fac
|
|
1114
|
+
//Requires: ml_z_facM, caml_invalid_argument
|
|
1115
|
+
function ml_z_fac(i) {
|
|
1116
|
+
if (i < 0) caml_invalid_argument("Z.fac: non-positive argument");
|
|
1117
|
+
return ml_z_facM(i, 1);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
//external fac2 : int -> t
|
|
1121
|
+
//Provides: ml_z_fac2
|
|
1122
|
+
//Requires: ml_z_facM, caml_invalid_argument
|
|
1123
|
+
function ml_z_fac2(i) {
|
|
1124
|
+
if (i < 0) caml_invalid_argument("Z.fac2: non-positive argument");
|
|
1125
|
+
return ml_z_facM(i, 2);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
//external facM : int -> int -> t
|
|
1129
|
+
//Provides: ml_z_facM
|
|
1130
|
+
//Requires: caml_invalid_argument, ml_z_normalize
|
|
1131
|
+
function ml_z_facM(i, m) {
|
|
1132
|
+
if (i < 0 || m < 0) caml_invalid_argument("Z.facM: non-positive argument");
|
|
1133
|
+
if (m == 0) return i;
|
|
1134
|
+
let mn = BigInt(m);
|
|
1135
|
+
let current = BigInt(i);
|
|
1136
|
+
let res = 1n;
|
|
1137
|
+
while (current > 0) {
|
|
1138
|
+
res *= current;
|
|
1139
|
+
current -= mn;
|
|
1140
|
+
}
|
|
1141
|
+
return ml_z_normalize(res);
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
//external fib : int -> t
|
|
1145
|
+
//Provides: ml_z_fib
|
|
1146
|
+
//Requires: caml_invalid_argument, ml_z_normalize
|
|
1147
|
+
function ml_z_fib(i) {
|
|
1148
|
+
if (i < 0) caml_invalid_argument("Z.fib: negative arguments");
|
|
1149
|
+
if (i == 0 || i == 1) return i;
|
|
1150
|
+
let a = 0n, b = 1n;
|
|
1151
|
+
for (let k = 1; k < i; k++) {
|
|
1152
|
+
let b2 = b;
|
|
1153
|
+
b += a;
|
|
1154
|
+
a = b2;
|
|
1155
|
+
}
|
|
1156
|
+
return ml_z_normalize(b);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
//external lucnum : int -> t
|
|
1160
|
+
//Provides: ml_z_lucnum
|
|
1161
|
+
//Requires: caml_invalid_argument, ml_z_normalize
|
|
1162
|
+
function ml_z_lucnum(i) {
|
|
1163
|
+
if (i < 0) caml_invalid_argument("Z.lucnum: negative arguments");
|
|
1164
|
+
if (i == 0) return 2;
|
|
1165
|
+
if (i == 1) return 1;
|
|
1166
|
+
let a = 2n, b = 1n;
|
|
1167
|
+
for (let k = 1; k < i; k++) {
|
|
1168
|
+
let b2 = b;
|
|
1169
|
+
b += a;
|
|
1170
|
+
a = b2;
|
|
1171
|
+
}
|
|
1172
|
+
return ml_z_normalize(b);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
//Provides: ml_z_jacobi
|
|
1176
|
+
//Requires: caml_invalid_argument
|
|
1177
|
+
function ml_z_jacobi(n, k) {
|
|
1178
|
+
let nn = BigInt(n);
|
|
1179
|
+
let kn = BigInt(k);
|
|
1180
|
+
//assert(k > 0 and k % 2 == 1)
|
|
1181
|
+
if (kn <= 0 || kn % 2n !== 1n)
|
|
1182
|
+
caml_invalid_argument("Z.jacobi: second argument is negative or even");
|
|
1183
|
+
nn = nn % kn;
|
|
1184
|
+
if (nn < 0) nn += kn;
|
|
1185
|
+
let t = 1;
|
|
1186
|
+
while (nn !== 0n) {
|
|
1187
|
+
while (nn % 2n === 0n) {
|
|
1188
|
+
nn /= 2n;
|
|
1189
|
+
let r = kn % 8n
|
|
1190
|
+
if (r === 3n || r === 5n) {
|
|
1191
|
+
t = -t
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
let n1 = nn, k1 = kn;
|
|
1195
|
+
nn = k1;
|
|
1196
|
+
kn = n1;
|
|
1197
|
+
if (nn % 4n === 3n && kn % 4n === 3n) {
|
|
1198
|
+
t = -t
|
|
1199
|
+
}
|
|
1200
|
+
nn = nn % kn
|
|
1201
|
+
}
|
|
1202
|
+
if (kn === 1n)
|
|
1203
|
+
return t
|
|
1204
|
+
else
|
|
1205
|
+
return 0
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
//Provides: ml_z_legendre
|
|
1209
|
+
//Requires: ml_z_jacobi
|
|
1210
|
+
function ml_z_legendre(a, b) {
|
|
1211
|
+
return ml_z_jacobi(a, b);
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
//Provides: ml_z_kronecker
|
|
1215
|
+
//Requires: caml_failwith
|
|
1216
|
+
function ml_z_kronecker(n, k) {
|
|
1217
|
+
caml_failwith("ml_z_kronecker is not implemented");
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
//Provides: ml_z_primorial
|
|
1221
|
+
//Requires: ml_z_probab_prime, ml_z_normalize, caml_invalid_argument
|
|
1222
|
+
function ml_z_primorial(a) {
|
|
1223
|
+
if (a < 0) caml_invalid_argument("Z.primorial: non-positive argument");
|
|
1224
|
+
let z1 = 1n;
|
|
1225
|
+
let res = 1n;
|
|
1226
|
+
while (z1 <= a) {
|
|
1227
|
+
if (ml_z_probab_prime(z1, 25)) {
|
|
1228
|
+
res *= z1;
|
|
1229
|
+
}
|
|
1230
|
+
if (z1 === 1n || z1 === 2n) z1 += 1n;
|
|
1231
|
+
else z1 += 2n;
|
|
1232
|
+
}
|
|
1233
|
+
return ml_z_normalize(res);
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
//Provides: ml_z_bin
|
|
1237
|
+
//Requires: ml_z_normalize, caml_invalid_argument
|
|
1238
|
+
function ml_z_bin(n, k) {
|
|
1239
|
+
if (k < 0) caml_invalid_argument("Z.bin: non-positive argument");
|
|
1240
|
+
n = BigInt(n);
|
|
1241
|
+
k = BigInt(k);
|
|
1242
|
+
let coeff = 1n;
|
|
1243
|
+
for (let x = n - k + 1n; x <= n; x++) coeff *= x;
|
|
1244
|
+
for (let x = 1n; x <= k; x++) coeff /= x;
|
|
1245
|
+
return ml_z_normalize(coeff);
|
|
1246
|
+
}
|