diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6e03654..adfa7d3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -16,3 +16,17 @@ jobs: run: make - name: Run the testsuite run: make -C tests test + + MacOS: + runs-on: macos-latest + steps: + - name: Install packages + run: brew install ocaml ocaml-findlib gmp + - name: Checkout + uses: actions/checkout@v2 + - name: configure tree + run: ./configure + - name: Build + run: make + - name: Run the testsuite + run: make -C tests test diff --git a/.gitignore b/.gitignore index 56ffacd..6ee9be0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,4 @@ *.so Makefile depend -z.ml -z.mli -z_features.h +zarith_version.ml diff --git a/README.md b/README.md index 1d5434a..7c2a5c9 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ However, small integers are represented as unboxed Caml integers, to save space and improve performance. Big integers are allocated in the Caml heap, bypassing GMP's memory management and achieving better GC behavior than e.g. the MLGMP library. -Computations on small integers use a special, faster path (coded in assembly -for some platforms and functions) eschewing calls to GMP, while computations -on large intergers use the low-level MPN functions from GMP. +Computations on small integers use a special, faster path (in C or OCaml) +eschewing calls to GMP, while computations on large intergers use the +low-level MPN functions from GMP. Arbitrary-precision integers can be compared correctly using OCaml's polymorphic comparison operators (`=`, `<`, `>`, etc.). @@ -32,7 +32,6 @@ Additional features include: * OCaml, version 4.04.0 or later. * Either the GMP library or the MPIR library, including development files. * GCC or Clang or a gcc-compatible C compiler and assembler (other compilers may work). -* The Perl programming language. * The Findlib package manager (optional, recommended). @@ -95,8 +94,8 @@ See LICENSE file for details. ## AUTHORS -* Antoine Miné, Université Pierre et Marie Curie, formerly ENS Paris. -* Xavier Leroy, INRIA Paris-Rocquencourt. +* Antoine Miné, Sorbonne Université, formerly at ENS Paris. +* Xavier Leroy, Collège de France, formerly at Inria Paris. * Pascal Cuoq, TrustInSoft. * Christophe Troestler (toplevel module) @@ -116,17 +115,12 @@ INRIA Rocquencourt (Institut national de recherche en informatique, France). Source files | Description --------------------|----------------------------------------- configure | configuration script - caml_z.c | C implementation of all functions - caml_z_*.S | asm implementation for a few functions - z_pp.pl | script to generate z.ml[i] from z.ml[i]p - z.ml[i]p | templates used to generate z.ml[i]p + z.ml[i] | Z module and implementation for small integers + caml_z.c | C implementation big_int_z.ml[i] | wrapper to provide a Big_int compatible API to Z q.ml[i] | rational library, pure OCaml on top of Z zarith_top.ml | toplevel module to provide pretty-printing projet.mak | builds Z, Q and the tests + zarith.opam | package description for opam + z_mlgmpidl.ml[i] | conversion between Zarith and MLGMPIDL tests/ | simple regression tests and benchmarks - -Note: `z_pp.pl` simply scans the asm file (if any) to see which functions have -an asm implementation. It then fixes the external statements in .mlp and -.mlip accordingly. -The argument to `z_pp.pl` is the suffix `*` of the `caml_z_*.S` to use (guessed by configure). diff --git a/caml_z.c b/caml_z.c index da0957d..f8c3179 100644 --- a/caml_z.c +++ b/caml_z.c @@ -35,7 +35,6 @@ #include #endif -#include "z_features.h" #include "zarith.h" #ifdef __cplusplus @@ -50,9 +49,7 @@ extern "C" { #include #include #include -#ifdef Z_OCAML_HASH #include -#endif #define inline __inline @@ -103,16 +100,6 @@ extern "C" { */ #define Z_CUSTOM_BLOCK 1 -/* whether the "compare_ext" operation over custom blocks is supported. - This operation is required for OCaml's generic comparisons to - operate properly over values of type Z.t. - The compare_ext operation is supported in OCaml since version 3.12.1. -*/ -/* - #define Z_OCAML_COMPARE_EXT 0 - now set by configure -*/ - /*--------------------------------------------------- DATA STRUCTURES ---------------------------------------------------*/ @@ -3244,10 +3231,6 @@ int ml_z_custom_compare(value arg1, value arg2) return r; } -#ifndef Z_OCAML_HASH -#define caml_hash_mix_uint32(h,n) ((h) * 65599 + (n)) -#endif - static intnat ml_z_custom_hash(value v) { Z_DECL(v); @@ -3380,11 +3363,7 @@ struct custom_operations ml_z_custom_ops = { ml_z_custom_hash, ml_z_custom_serialize, ml_z_custom_deserialize, -#if Z_OCAML_COMPARE_EXT ml_z_custom_compare, -#else - custom_compare_ext_default, -#endif #ifndef Z_OCAML_LEGACY_CUSTOM_OPERATIONS custom_fixed_length_default #endif diff --git a/configure b/configure index b8803f5..585a002 100755 --- a/configure +++ b/configure @@ -22,8 +22,6 @@ host='auto' gmp='auto' perf='no' -ar="${AR}" -[ -z "$ar" ] && ar='ar' ocaml='ocaml' ocamlc='ocamlc' ocamlopt='ocamlopt' @@ -32,7 +30,6 @@ ocamldep='ocamldep' ocamldoc='ocamldoc' ccinc="$CPPFLAGS" cclib="$LDFLAGS" -asopt="$ASFLAGS" ccdef='' mlflags="$OCAMLFLAGS" mloptflags="$OCAMLOPTFLAGS" @@ -55,18 +52,14 @@ usage: configure [options] where options include: -installdir dir installation directory -ocamllibdir dir ocaml library directory - -host arch host type, for platform-specific asm code - -noasm disable platform-specific asm code -gmp use GMP library (default if found) -mpir use MPIR library instead of GMP -perf enable performance statistics -prefixnonocaml add for non ocaml tool, e.g. -prefixnonocaml x86_64-w64-mingw32- Environment variables that affect configuration: - AR archiver tool CC C compiler to use (default: try gcc, then cc) CFLAGS extra flags to pass to the C compiler - ASFLAGS extra flags to pass to the assembler CPPFLAGS extra includes, e.g. -I/path/to/gmp/include LDFLAGS extra link flags, e.g. -L/path/to/gmp/lib OCAMLFLAGS extra flags to pass to the ocamlc Caml compiler @@ -90,11 +83,6 @@ while : ; do -no-ocamlfind|--no-ocamlfind) ocamlfind="no" shift;; - -host|--host) - host="$2" - shift;; - -noasm|--no-asm) - host='none';; -help|--help) help;; -gmp|--gmp) @@ -211,9 +199,6 @@ searchbinreq $ocamlc searchbinreq $ocamldep searchbinreq $ocamlmklib searchbinreq $ocamldoc -searchbin $ar -if test $? -eq 0; then ar=$prefixnonocaml$ar; searchbinreq $ar; fi -searchbinreq perl if test -n "$CC"; then searchbinreq "$CC" @@ -309,62 +294,6 @@ if test "x$host" = 'xauto'; then fi fi - -# set arch from host - -arch='none' -case $host in - x86_64-*linux-gnu|x86_64-kfreebsd-gnu) - ccdef="-DZ_ELF -DZ_DOT_LABEL_PREFIX $ccdef" - if test $wordsize = 32; then - # 32-bit OCaml on a 64-bit host - arch='i686' - ccopt="-m32 $ccopt" - asopt="-m32 $asopt" - else - arch='x86_64' - fi - ;; - i486-*linux-gnu|i686-*linux-gnu|i486-kfreebsd-gnu) - ccdef="-DZ_ELF -DZ_DOT_LABEL_PREFIX $ccdef" - arch='i686';; - i686-*cygwin) - if test "x$wordsize" = "x64"; then - ccdef="-DZ_COFF $ccdef" - arch='x86_64_mingw64' - else - ccdef="-DZ_UNDERSCORE_PREFIX -DZ_COFF $ccdef" - arch='i686' - fi - ;; - i386-*darwin* | x86_64-*darwin*) - ccdef="-DZ_UNDERSCORE_PREFIX -DZ_MACOS $ccdef" - if test "x$wordsize" = "x64"; then - ccopt="-arch x86_64 $ccopt" - asopt="-arch x86_64 $asopt" - arch='x86_64' - checkcc - else - ccopt="-arch i386 $ccopt" - asopt="-arch i386 $asopt" - arch='i686' - checkcc - fi - ;; - armv7*-gnueabi) - arch='arm' - ;; - none) - ;; - *) - echo "unknown host $host";; -esac - -if test "$arch" != 'none'; then - if test ! -f "caml_z_${arch}.S"; then arch='none'; fi -fi - - # check GMP, MPIR if test "$gmp" = 'gmp' -o "$gmp" = 'auto'; then @@ -406,14 +335,6 @@ case "$ocamlver" in ;; esac -# Extended comparisons available since 3.12.1 -echo "OCaml extended comparison supported" -ccdef="-DZ_OCAML_COMPARE_EXT $ccdef" - -# New hash functions available since 4.00.0 -echo "OCaml new hash functions available" -ccdef="-DZ_OCAML_HASH $ccdef" - # -bin-annot available since 4.00.0 echo "OCaml supports -bin-annot to produce documentation" hasbinannot='yes' @@ -443,11 +364,8 @@ OCAMLFLAGS=$mlflags OCAMLOPTFLAGS=$mloptflags OCAMLINC=$mlinc CFLAGS=$ccinc $ccdef $ccopt -ASFLAGS=$ccdef $asopt LIBS=$cclib -ARCH=$arch INSTALLDIR=$installdir -AR=$ar INSTALL=install OCAMLFIND=ocamlfind INSTMETH=$instmeth @@ -468,11 +386,9 @@ detected configuration: native-code: $hasocamlopt dynamic linking: $hasdynlink - asm path: $arch defines: $ccdef libraries: $cclib C options: $ccopt - asm options $asopt installation path: $installdir installation method $instmeth diff --git a/project.mak b/project.mak index deb1db3..fd1c158 100644 --- a/project.mak +++ b/project.mak @@ -32,11 +32,10 @@ endif ############### CSRC = caml_z.c -SSRC = $(wildcard caml_z_$(ARCH).S) -MLSRC = z.ml q.ml big_int_Z.ml +MLSRC = zarith_version.ml z.ml q.ml big_int_Z.ml MLISRC = z.mli q.mli big_int_Z.mli -AUTOGEN = z.ml z.mli z_features.h +AUTOGEN = zarith_version.ml CMIOBJ = $(MLISRC:%.mli=%.cmi) CMXOBJ = $(MLISRC:%.mli=%.cmx) @@ -80,7 +79,7 @@ zarith.cmxa: $(MLSRC:%.ml=%.cmx) zarith.cmxs: zarith.cmxa libzarith.$(LIBSUFFIX) $(OCAMLOPT) -shared -o $@ -I . zarith.cmxa -linkall -libzarith.$(LIBSUFFIX): $(SSRC:%.S=%.$(OBJSUFFIX)) $(CSRC:%.c=%.$(OBJSUFFIX)) +libzarith.$(LIBSUFFIX): $(CSRC:%.c=%.$(OBJSUFFIX)) $(OCAMLMKLIB) -failsafe -o zarith $+ $(LIBS) zarith_top.cma: zarith_top.cmo @@ -90,7 +89,8 @@ doc: $(MLISRC) mkdir -p html $(OCAMLDOC) -html -d html -charset utf8 $+ - +zarith_version.ml: META + (echo "let"; grep "version" META | head -1) > zarith_version.ml # install targets ################# @@ -122,9 +122,6 @@ endif # rules ####### -$(AUTOGEN): z.mlp z.mlip $(SSRC) z_pp.pl - ./z_pp.pl $(ARCH) - %.cmi: %.mli $(OCAMLC) $(OCAMLFLAGS) $(OCAMLINC) -c $< @@ -152,7 +149,7 @@ depend: $(AUTOGEN) include depend -$(CSRC:%.c=%.$(OBJSUFFIX)): z_features.h zarith.h +$(CSRC:%.c=%.$(OBJSUFFIX)): zarith.h .PHONY: clean .PHONY: tests diff --git a/z.mlp b/z.ml similarity index 93% rename from z.mlp rename to z.ml index 753299d..4de0d56 100644 --- a/z.mlp +++ b/z.ml @@ -61,7 +61,7 @@ let sub x y = end else c_sub x y -external mul_overflows: int -> int -> bool = "ml_z_mul_overflows" @NOALLOC +external mul_overflows: int -> int -> bool = "ml_z_mul_overflows" [@@noalloc] external c_mul: t -> t -> t = "ml_z_mul" let mul x y = @@ -216,22 +216,22 @@ external to_int64: t -> int64 = "ml_z_to_int64" external to_nativeint: t -> nativeint = "ml_z_to_nativeint" external format: string -> t -> string = "ml_z_format" external of_substring_base: int -> string -> pos:int -> len:int -> t = "ml_z_of_substring_base" -external compare: t -> t -> int = "ml_z_compare" @NOALLOC -external equal: t -> t -> bool = "ml_z_equal" @NOALLOC -external sign: t -> int = "ml_z_sign" @NOALLOC +external compare: t -> t -> int = "ml_z_compare" [@@noalloc] +external equal: t -> t -> bool = "ml_z_equal" [@@noalloc] +external sign: t -> int = "ml_z_sign" [@@noalloc] external gcd: t -> t -> t = "ml_z_gcd" external gcdext_intern: t -> t -> (t * t * bool) = "ml_z_gcdext_intern" external sqrt: t -> t = "ml_z_sqrt" external sqrt_rem: t -> (t * t) = "ml_z_sqrt_rem" -external numbits: t -> int = "ml_z_numbits" @NOALLOC -external trailing_zeros: t -> int = "ml_z_trailing_zeros" @NOALLOC +external numbits: t -> int = "ml_z_numbits" [@@noalloc] +external trailing_zeros: t -> int = "ml_z_trailing_zeros" [@@noalloc] external popcount: t -> int = "ml_z_popcount" external hamdist: t -> t -> int = "ml_z_hamdist" -external size: t -> int = "ml_z_size" @NOALLOC -external fits_int: t -> bool = "ml_z_fits_int" @NOALLOC -external fits_int32: t -> bool = "ml_z_fits_int32" @NOALLOC -external fits_int64: t -> bool = "ml_z_fits_int64" @NOALLOC -external fits_nativeint: t -> bool = "ml_z_fits_nativeint" @NOALLOC +external size: t -> int = "ml_z_size" [@@noalloc] +external fits_int: t -> bool = "ml_z_fits_int" [@@noalloc] +external fits_int32: t -> bool = "ml_z_fits_int32" [@@noalloc] +external fits_int64: t -> bool = "ml_z_fits_int64" [@@noalloc] +external fits_nativeint: t -> bool = "ml_z_fits_nativeint" [@@noalloc] external extract: t -> int -> int -> t = "ml_z_extract" external powm: t -> t -> t -> t = "ml_z_powm" external pow: t -> int -> t = "ml_z_pow" @@ -243,7 +243,7 @@ external perfect_power: t -> bool = "ml_z_perfect_power" external perfect_square: t -> bool = "ml_z_perfect_square" external probab_prime: t -> int -> int = "ml_z_probab_prime" external nextprime: t -> t = "ml_z_nextprime" -external hash: t -> int = "ml_z_hash" @NOALLOC +external hash: t -> int = "ml_z_hash" [@@noalloc] external to_bits: t -> string = "ml_z_to_bits" external of_bits: string -> t = "ml_z_of_bits" external divisible: t -> t -> bool = "ml_z_divisible" @@ -314,11 +314,11 @@ let lcm u v = let g = gcd u v in abs (mul (divexact u g) v) -external testbit_internal: t -> int -> bool = "ml_z_testbit" @NOALLOC +external testbit_internal: t -> int -> bool = "ml_z_testbit" [@@noalloc] let testbit x n = if n >= 0 then testbit_internal x n else invalid_arg "Z.testbit" (* The test [n >= 0] is done in Caml rather than in the C stub code - so that the latter raises no exceptions and can be declared @NOALLOC. *) + so that the latter raises no exceptions and can be declared [@@noalloc]. *) let is_odd x = testbit_internal x 0 let is_even x = not (testbit_internal x 0) @@ -407,4 +407,4 @@ module Compare = struct let (<>) a b = not (equal a b) end -let version = @VERSION +let version = Zarith_version.version diff --git a/z.mlip b/z.mli similarity index 97% rename from z.mlip rename to z.mli index fe6dbca..0e4a046 100644 --- a/z.mlip +++ b/z.mli @@ -247,14 +247,14 @@ val shift_right_trunc: t -> int -> t The second argument must be nonnegative. *) -external numbits: t -> int = "ml_z_numbits" @NOALLOC +external numbits: t -> int = "ml_z_numbits" [@@noalloc] (** Returns the number of significant bits in the given number. If [x] is zero, [numbits x] returns 0. Otherwise, [numbits x] returns a positive integer [n] such that [2^{n-1} <= |x| < 2^n]. Note that [numbits] is defined for negative arguments, and that [numbits (-x) = numbits x]. *) -external trailing_zeros: t -> int = "ml_z_trailing_zeros" @NOALLOC +external trailing_zeros: t -> int = "ml_z_trailing_zeros" [@@noalloc] (** Returns the number of trailing 0 bits in the given number. If [x] is zero, [trailing_zeros x] returns [max_int]. Otherwise, [trailing_zeros x] returns a nonnegative integer [n] @@ -336,16 +336,16 @@ external format: string -> t -> string = "ml_z_format" are simply ignored (and not copied in the output). *) -external fits_int: t -> bool = "ml_z_fits_int" @NOALLOC +external fits_int: t -> bool = "ml_z_fits_int" [@@noalloc] (** Whether the argument fits in a regular [int]. *) -external fits_int32: t -> bool = "ml_z_fits_int32" @NOALLOC +external fits_int32: t -> bool = "ml_z_fits_int32" [@@noalloc] (** Whether the argument fits in an [int32]. *) -external fits_int64: t -> bool = "ml_z_fits_int64" @NOALLOC +external fits_int64: t -> bool = "ml_z_fits_int64" [@@noalloc] (** Whether the argument fits in an [int64]. *) -external fits_nativeint: t -> bool = "ml_z_fits_nativeint" @NOALLOC +external fits_nativeint: t -> bool = "ml_z_fits_nativeint" [@@noalloc] (** Whether the argument fits in a [nativeint]. *) @@ -374,7 +374,7 @@ val pp_print: Format.formatter -> t -> unit (** {1 Ordering} *) -external compare: t -> t -> int = "ml_z_compare" @NOALLOC +external compare: t -> t -> int = "ml_z_compare" [@@noalloc] (** Comparison. [compare x y] returns 0 if [x] equals [y], -1 if [x] is smaller than [y], and 1 if [x] is greater than [y]. @@ -382,7 +382,7 @@ external compare: t -> t -> int = "ml_z_compare" @NOALLOC only on OCaml 3.12.1 and later versions. *) -external equal: t -> t -> bool = "ml_z_equal" @NOALLOC +external equal: t -> t -> bool = "ml_z_equal" [@@noalloc] (** Equality test. *) val leq: t -> t -> bool @@ -397,7 +397,7 @@ val lt: t -> t -> bool val gt: t -> t -> bool (** Greater than (and not equal). *) -external sign: t -> int = "ml_z_sign" @NOALLOC +external sign: t -> int = "ml_z_sign" [@@noalloc] (** Returns -1, 0, or 1 when the argument is respectively negative, null, or positive. *) @@ -414,7 +414,7 @@ val is_even: t -> bool val is_odd: t -> bool (** Returns true if the argument is odd, false if even. *) -external hash: t -> int = "ml_z_hash" @NOALLOC +external hash: t -> int = "ml_z_hash" [@@noalloc] (** Hashes a number, producing a small integer. The result is consistent with equality: if [a] = [b], then [hash a] = [hash b]. @@ -585,7 +585,7 @@ val log2up: t -> int (** {1 Representation} *) -external size: t -> int = "ml_z_size" @NOALLOC +external size: t -> int = "ml_z_size" [@@noalloc] (** Returns the number of machine words used to represent the number. *) external extract: t -> int -> int -> t = "ml_z_extract" diff --git a/z_pp.ml b/z_pp.ml deleted file mode 100644 index d86d3d6..0000000 --- a/z_pp.ml +++ /dev/null @@ -1,92 +0,0 @@ -let archname = ref "" -let noalloc = ref true -let version = ref "VERSION" -let usage = "Usage: './z_pp architecture" - -let () = - Arg.parse - ["-noalloc", Arg.Set noalloc, "noalloc attribute available"; - "-ov", Arg.Set_string version, "ocaml compiler version"] - (fun name -> archname := name) - usage; - if !archname = "" - then begin - print_endline usage; - exit 1 - end - -let noalloc_str = if !noalloc then "[@@noalloc]" else "\"noalloc\"" - -let asmfilename = "caml_z_" ^ !archname ^ ".S" - -module StringSet = Set.Make(String) - -let funcnames = ref StringSet.empty - -let () = - let rPROLOG = Str.regexp "[ ]*PROLOG(\\([^)]*\\))" in - let input = open_in asmfilename in - Printf.printf "found assembly file %s\n" asmfilename; - try - while true do - let s = input_line input in - if Str.string_match rPROLOG s 0 - then - let funcname = Str.matched_group 1 s in - Printf.printf " found %s\n" funcname; - funcnames := StringSet.add funcname !funcnames - done - with - End_of_file -> - close_in input - - -let treat_file = - let rASM = Str.regexp "\\(.*\\) \\([A-Za-z0-9_]+\\)@ASM\\(.*\\)" in - let funcnames = !funcnames in - function extension -> - let outputname = "z." ^ extension in - let inputname = outputname ^ "p" in - - let input = open_in inputname in - let output = open_out outputname in - Printf.fprintf output - "(* This file was automatically generated by z_pp.ml from %s *)\n" - inputname; - try - while true do - let line_in = input_line input in - let line_in = Str.(global_replace (regexp "@VERSION") (Printf.sprintf "%S" !version) line_in) in - let line_in = Str.(global_replace (regexp "@NOALLOC") noalloc_str line_in) in - let line_out = - if Str.string_match rASM line_in 0 - then - let funcname = Str.matched_group 2 line_in in - if StringSet.mem funcname funcnames - then Str.replace_matched - "\\1 \"ml_z_\\2\" \"ml_as_z_\\2\"\\3" - line_in - else - Str.replace_matched - "\\1 \"ml_z_\\2\"\\3" - line_in - else line_in - in - Printf.fprintf output "%s\n" line_out - done - with - End_of_file -> - close_in input -;; - -let generate_config filename = - let oc = open_out filename in - StringSet.iter - (fun f -> Printf.fprintf oc "#define Z_ASM_%s\n" f) - !funcnames; - close_out oc -;; - -let _ = treat_file "ml" -let _ = treat_file "mli" -let _ = generate_config "z_features.h" diff --git a/z_pp.pl b/z_pp.pl deleted file mode 100755 index aa92959..0000000 --- a/z_pp.pl +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env perl - -use warnings "all"; - -# Simple preprocessor to fix @ASM directives in z.mlp and z.mlip, and -# generate z.ml and z.mli - -# This file is part of the Zarith library -# http://forge.ocamlcore.org/projects/zarith . -# It is distributed under LGPL 2 licensing, with static linking exception. -# See the LICENSE file included in the distribution. -# -# Copyright (c) 2010-2011 Antoine Miné, Abstraction project. -# Abstraction is part of the LIENS (Laboratoire d'Informatique de l'ENS), -# a joint laboratory by: -# CNRS (Centre national de la recherche scientifique, France), -# ENS (École normale supérieure, Paris, France), -# INRIA Rocquencourt (Institut national de recherche en informatique, France). - - -die "Usage: './z_pp.pl architecture'" unless $#ARGV==0; - -# version, from META file - -$v = `grep version META`; -($ver) = $v =~ /version\s*=\s*(\S+)/; - -$ov = `ocamlc -version`; -($major,$minor,$extra) = split(/\./, $ov, 3); -if ($major > 4 || ($major == 4 && $minor >= 3)) { - $noalloc = "[\@\@noalloc]"; -} else { - $noalloc = "\"noalloc\""; -} - -# scan assembly - -$ASM = "caml_z_${ARGV[0]}.S"; -if (-e $ASM) { - print "found assembly file $ASM\n"; - open F, "<$ASM"; - while (defined($l = )) { - if ($l =~ /^\s*PROLOG\s*\(\s*([A-Za-z0-9_]+)/) { - $ASM_FUNS{$1} = 1; - } - } - close F; -} - -for $i (sort (keys %ASM_FUNS)) { - print " found $i\n"; -} - - -# specialize .ml & .mli files - -sub doml { - $SUF = shift @_; - open I, "z.${SUF}"; - print O "(* This file was automatically generated by z_pp.pl from z.${SUF}p *) "; - while (defined($l = )) { - while ($l =~ /([A-Za-z0-9_]+)\@ASM/) { - $f = $1; - if (defined($ASM_FUNS{$f})) { - $r = "\"ml_z_$f\" \"ml_as_z_$f\""; - } - else { - $r = "\"ml_z_$f\""; - } - $l =~ s/$f\@ASM/$r/g; - } - $l =~ s/\@VERSION/$ver/; - $l =~ s/\@NOALLOC/$noalloc/; - print O "$l"; - } - close F; -} - -doml "ml"; -doml "mli"; - -# generate a features.h file recording the functions defined in asm - -open F, "> z_features.h"; -for $i (sort (keys %ASM_FUNS)) { - print F "#define Z_ASM_$i\n"; -} -close F; diff --git a/zarith.opam b/zarith.opam index 8a4e3d2..b299715 100644 --- a/zarith.opam +++ b/zarith.opam @@ -30,7 +30,6 @@ depends: [ "ocaml" {>= "4.04.0"} "ocamlfind" "conf-gmp" - "conf-perl" {build} ] synopsis: "Implements arithmetic and logical operations over arbitrary-precision integers"