mirror of
https://github.com/c-cube/iter.git
synced 2025-12-08 12:15:37 -05:00
Merge branch 'master' into stable for 1.0
This commit is contained in:
commit
7d93f1fd19
36 changed files with 229 additions and 9749 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -4,6 +4,5 @@ _build
|
||||||
*.docdir
|
*.docdir
|
||||||
*.html
|
*.html
|
||||||
man/
|
man/
|
||||||
sequence.install
|
*.install
|
||||||
setup.log
|
.merlin
|
||||||
setup.data
|
|
||||||
|
|
|
||||||
6
.merlin
6
.merlin
|
|
@ -4,7 +4,5 @@ S tests/
|
||||||
B _build/src
|
B _build/src
|
||||||
B _build/tests/
|
B _build/tests/
|
||||||
B _build/bench/
|
B _build/bench/
|
||||||
PKG oUnit qcheck
|
PKG oUnit qcheck result benchmark
|
||||||
PKG benchmark
|
FLG -safe-string -w+a-4-44-48-60@8
|
||||||
FLG -safe-string
|
|
||||||
FLG -w+a-4-44-48-60@8
|
|
||||||
|
|
|
||||||
35
.travis.yml
Normal file
35
.travis.yml
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
language: c
|
||||||
|
env:
|
||||||
|
- OCAML_VERSION=4.01.0
|
||||||
|
- OCAML_VERSION=4.02.3
|
||||||
|
- OCAML_VERSION=4.04.2
|
||||||
|
- OCAML_VERSION=4.05.0
|
||||||
|
- OCAML_VERSION=4.05.0+flambda
|
||||||
|
- OCAML_VERSION=4.06.0
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- avsm
|
||||||
|
packages:
|
||||||
|
- opam
|
||||||
|
# Caching may take a lot of space with so many ocaml versions
|
||||||
|
#cache:
|
||||||
|
# directories:
|
||||||
|
# - $HOME/.opam
|
||||||
|
before_install:
|
||||||
|
# Some opam boilerplate
|
||||||
|
- export OPAMYES=1
|
||||||
|
- export OPAMVERBOSE=1
|
||||||
|
- opam init
|
||||||
|
- opam switch ${OCAML_VERSION}
|
||||||
|
- eval `opam config env`
|
||||||
|
install:
|
||||||
|
# Install dependencies
|
||||||
|
- opam pin add --no-action sequence .
|
||||||
|
- opam install oasis
|
||||||
|
- opam install --deps-only sequence
|
||||||
|
script:
|
||||||
|
- make build
|
||||||
|
- opam install qcheck qtest
|
||||||
|
- ./configure --enable-tests
|
||||||
|
- make test
|
||||||
33
META
33
META
|
|
@ -1,33 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: 8041ba3970fcecd2b690dc7b78ccae41)
|
|
||||||
version = "0.7"
|
|
||||||
description = "Simple sequence (iterator) datatype and combinators"
|
|
||||||
requires = "bytes"
|
|
||||||
archive(byte) = "sequence.cma"
|
|
||||||
archive(byte, plugin) = "sequence.cma"
|
|
||||||
archive(native) = "sequence.cmxa"
|
|
||||||
archive(native, plugin) = "sequence.cmxs"
|
|
||||||
exists_if = "sequence.cma"
|
|
||||||
package "invert" (
|
|
||||||
version = "0.7"
|
|
||||||
description = "Simple sequence (iterator) datatype and combinators"
|
|
||||||
requires = "sequence delimcc"
|
|
||||||
archive(byte) = "invert.cma"
|
|
||||||
archive(byte, plugin) = "invert.cma"
|
|
||||||
archive(native) = "invert.cmxa"
|
|
||||||
archive(native, plugin) = "invert.cmxs"
|
|
||||||
exists_if = "invert.cma"
|
|
||||||
)
|
|
||||||
|
|
||||||
package "bigarray" (
|
|
||||||
version = "0.7"
|
|
||||||
description = "Simple sequence (iterator) datatype and combinators"
|
|
||||||
requires = "sequence bigarray"
|
|
||||||
archive(byte) = "bigarray.cma"
|
|
||||||
archive(byte, plugin) = "bigarray.cma"
|
|
||||||
archive(native) = "bigarray.cmxa"
|
|
||||||
archive(native, plugin) = "bigarray.cmxs"
|
|
||||||
exists_if = "bigarray.cma"
|
|
||||||
)
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
||||||
87
Makefile
87
Makefile
|
|
@ -1,79 +1,30 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: a3c674b4239234cbbe53afe090018954)
|
|
||||||
|
|
||||||
SETUP = ocaml setup.ml
|
all: build test
|
||||||
|
|
||||||
build: setup.data
|
build:
|
||||||
$(SETUP) -build $(BUILDFLAGS)
|
jbuilder build @install
|
||||||
|
|
||||||
doc: setup.data build
|
test:
|
||||||
$(SETUP) -doc $(DOCFLAGS)
|
jbuilder runtest
|
||||||
|
|
||||||
test: setup.data build
|
|
||||||
$(SETUP) -test $(TESTFLAGS)
|
|
||||||
|
|
||||||
all:
|
|
||||||
$(SETUP) -all $(ALLFLAGS)
|
|
||||||
|
|
||||||
install: setup.data
|
|
||||||
$(SETUP) -install $(INSTALLFLAGS)
|
|
||||||
|
|
||||||
uninstall: setup.data
|
|
||||||
$(SETUP) -uninstall $(UNINSTALLFLAGS)
|
|
||||||
|
|
||||||
reinstall: setup.data
|
|
||||||
$(SETUP) -reinstall $(REINSTALLFLAGS)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(SETUP) -clean $(CLEANFLAGS)
|
jbuilder clean
|
||||||
|
|
||||||
distclean:
|
doc:
|
||||||
$(SETUP) -distclean $(DISTCLEANFLAGS)
|
jbuilder build @doc
|
||||||
|
|
||||||
setup.data:
|
BENCH_TARGETS=bench_persistent_read.exe bench_persistent.exe
|
||||||
$(SETUP) -configure $(CONFIGUREFLAGS)
|
|
||||||
|
|
||||||
configure:
|
benchs:
|
||||||
$(SETUP) -configure $(CONFIGUREFLAGS)
|
jbuilder build $(addprefix bench/, $(BENCH_TARGETS))
|
||||||
|
|
||||||
.PHONY: build doc test all install uninstall reinstall clean distclean configure
|
|
||||||
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
||||||
QTEST_PREAMBLE=''
|
|
||||||
DONTTEST=src/sequenceLabels.ml
|
|
||||||
QTESTABLE=$(filter-out $(DONTTEST), \
|
|
||||||
$(wildcard src/*.ml) \
|
|
||||||
$(wildcard src/*.mli) \
|
|
||||||
)
|
|
||||||
|
|
||||||
qtest-clean:
|
|
||||||
@rm -rf qtest/
|
|
||||||
|
|
||||||
qtest-gen:
|
|
||||||
@mkdir -p qtest
|
|
||||||
@if which qtest > /dev/null ; then \
|
|
||||||
qtest extract --preamble $(QTEST_PREAMBLE) \
|
|
||||||
-o qtest/run_qtest.ml \
|
|
||||||
$(QTESTABLE) 2> /dev/null ; \
|
|
||||||
else touch qtest/run_qtest.ml ; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
ocamlbuild examples/test_sexpr.native
|
jbuilder build examples/test_sexpr.exe
|
||||||
|
|
||||||
push_doc: all doc
|
push_doc: all doc
|
||||||
scp -r sequence.docdir/* cedeela.fr:~/simon/root/software/sequence/
|
scp -r sequence.docdir/* cedeela.fr:~/simon/root/software/sequence/
|
||||||
|
|
||||||
push_stable: all
|
VERSION=$(shell awk '/^version:/ {print $$2}' sequence.opam)
|
||||||
git checkout stable
|
|
||||||
git merge master -m 'merge from master'
|
|
||||||
oasis setup
|
|
||||||
git commit -a -m 'oasis files'
|
|
||||||
git push origin
|
|
||||||
git checkout master
|
|
||||||
|
|
||||||
VERSION=$(shell awk '/^Version:/ {print $$2}' _oasis)
|
|
||||||
|
|
||||||
SOURCE=$(addprefix src/, *.ml *.mli invert/*.ml invert/*.mli bigarray/*.ml bigarray/*.mli)
|
SOURCE=$(addprefix src/, *.ml *.mli invert/*.ml invert/*.mli bigarray/*.ml bigarray/*.mli)
|
||||||
|
|
||||||
|
|
@ -82,18 +33,6 @@ update_next_tag:
|
||||||
sed -i "s/NEXT_VERSION/$(VERSION)/g" $(SOURCE)
|
sed -i "s/NEXT_VERSION/$(VERSION)/g" $(SOURCE)
|
||||||
sed -i "s/NEXT_RELEASE/$(VERSION)/g" $(SOURCE)
|
sed -i "s/NEXT_RELEASE/$(VERSION)/g" $(SOURCE)
|
||||||
|
|
||||||
NAME_VERSION := sequence.$(VERSION)
|
|
||||||
URL := https://github.com/c-cube/sequence/archive/$(VERSION).tar.gz
|
|
||||||
|
|
||||||
release:
|
|
||||||
git tag -a $(VERSION) -m "Version $(VERSION)."
|
|
||||||
git push origin $(VERSION)
|
|
||||||
opam publish prepare $(NAME_VERSION) $(URL)
|
|
||||||
cp descr $(NAME_VERSION)
|
|
||||||
echo "submit?"
|
|
||||||
@read
|
|
||||||
opam publish submit $(NAME_VERSION)
|
|
||||||
|
|
||||||
watch:
|
watch:
|
||||||
while find src/ -print0 | xargs -0 inotifywait -e delete_self -e modify ; do \
|
while find src/ -print0 | xargs -0 inotifywait -e delete_self -e modify ; do \
|
||||||
echo "============ at `date` ==========" ; \
|
echo "============ at `date` ==========" ; \
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ way of iterating on a finite number of values, only allocating (most of the time
|
||||||
one intermediate closure to do so. For instance, iterating on keys, or values,
|
one intermediate closure to do so. For instance, iterating on keys, or values,
|
||||||
of a `Hashtbl.t`, without creating a list.
|
of a `Hashtbl.t`, without creating a list.
|
||||||
|
|
||||||
|
image::https://travis-ci.org/c-cube/sequence.svg?branch=master[alt="Build Status", link="https://travis-ci.org/c-cube/sequence"]
|
||||||
|
|
||||||
toc::[]
|
toc::[]
|
||||||
|
|
||||||
== Documentation
|
== Documentation
|
||||||
|
|
@ -23,13 +25,13 @@ To get an overview of sequence, its origins and why it was created,
|
||||||
you can start with http://cedeela.fr/~simon/talks/sequence.pdf[the slides of a talk]
|
you can start with http://cedeela.fr/~simon/talks/sequence.pdf[the slides of a talk]
|
||||||
I (@c-cube) made at some OCaml meeting.
|
I (@c-cube) made at some OCaml meeting.
|
||||||
|
|
||||||
See https://c-cube.github.io/sequence/api/[the online API]
|
See https://c-cube.github.io/sequence/[the online API]
|
||||||
for more details on the set of available functions.
|
for more details on the set of available functions.
|
||||||
|
|
||||||
== Build
|
== Build
|
||||||
|
|
||||||
1. via opam `opam install sequence`
|
1. via opam `opam install sequence`
|
||||||
2. manually (need OCaml >= 3.12): `make all install`
|
2. manually (need OCaml >= 4.02.0): `make all install`
|
||||||
|
|
||||||
If you have https://github.com/vincent-hugot/iTeML[qtest] installed,
|
If you have https://github.com/vincent-hugot/iTeML[qtest] installed,
|
||||||
you can build and run tests with
|
you can build and run tests with
|
||||||
|
|
|
||||||
103
_oasis
103
_oasis
|
|
@ -1,103 +0,0 @@
|
||||||
OASISFormat: 0.4
|
|
||||||
Name: sequence
|
|
||||||
Version: 0.11
|
|
||||||
Homepage: https://github.com/c-cube/sequence
|
|
||||||
Authors: Simon Cruanes
|
|
||||||
License: BSD-2-clause
|
|
||||||
LicenseFile: LICENSE
|
|
||||||
Plugins: META (0.3), DevFiles (0.3)
|
|
||||||
BuildTools: ocamlbuild
|
|
||||||
|
|
||||||
Synopsis: Simple sequence (iterator) datatype and combinators
|
|
||||||
Description:
|
|
||||||
Simple sequence datatype, intended to transfer a finite number of
|
|
||||||
elements from one data structure to another. Some transformations on sequences,
|
|
||||||
like `filter`, `map`, `take`, `drop` and `append` can be performed before the
|
|
||||||
sequence is iterated/folded on.
|
|
||||||
|
|
||||||
Flag bench
|
|
||||||
Description: enable benchmarks (require library Benchmark)
|
|
||||||
Default: false
|
|
||||||
|
|
||||||
Flag invert
|
|
||||||
Description: build sequence.invert (requires Delimcc)
|
|
||||||
Default: false
|
|
||||||
|
|
||||||
Flag bigarray
|
|
||||||
Description: build sequence.bigarray (requires bigarray)
|
|
||||||
Default: true
|
|
||||||
|
|
||||||
Library "sequence"
|
|
||||||
Path: src/
|
|
||||||
Modules: Sequence, SequenceLabels
|
|
||||||
BuildDepends: bytes
|
|
||||||
|
|
||||||
Library "invert"
|
|
||||||
Path: src/invert
|
|
||||||
Build$: flag(invert)
|
|
||||||
Install$: flag(invert)
|
|
||||||
Modules: SequenceInvert
|
|
||||||
FindlibName: invert
|
|
||||||
FindlibParent: sequence
|
|
||||||
BuildDepends: sequence,delimcc
|
|
||||||
|
|
||||||
Library "bigarray"
|
|
||||||
Path: src/bigarray
|
|
||||||
Build$: flag(bigarray)
|
|
||||||
Install$: flag(bigarray)
|
|
||||||
Modules: SequenceBigarray
|
|
||||||
FindlibName: bigarray
|
|
||||||
FindlibParent: sequence
|
|
||||||
BuildDepends: sequence,bigarray
|
|
||||||
|
|
||||||
Document sequence
|
|
||||||
Title: Sequence docs
|
|
||||||
Type: ocamlbuild (0.3)
|
|
||||||
BuildTools+: ocamldoc
|
|
||||||
Install: true
|
|
||||||
XOCamlbuildPath: .
|
|
||||||
XOCamlbuildLibraries: sequence
|
|
||||||
|
|
||||||
PreBuildCommand: make qtest-gen
|
|
||||||
|
|
||||||
Executable run_qtest
|
|
||||||
Path: qtest/
|
|
||||||
Install: false
|
|
||||||
CompiledObject: native
|
|
||||||
MainIs: run_qtest.ml
|
|
||||||
Build$: flag(tests)
|
|
||||||
BuildDepends: sequence, qcheck
|
|
||||||
|
|
||||||
Test all
|
|
||||||
Command: ./run_qtest.native
|
|
||||||
TestTools: run_qtest
|
|
||||||
Run$: flag(tests)
|
|
||||||
|
|
||||||
Executable benchs
|
|
||||||
Path: bench
|
|
||||||
Install: false
|
|
||||||
CompiledObject: native
|
|
||||||
Build$: flag(bench)
|
|
||||||
BuildDepends: sequence,benchmark
|
|
||||||
MainIs: benchs.ml
|
|
||||||
|
|
||||||
Executable bench_persistent
|
|
||||||
Path: bench
|
|
||||||
Install: false
|
|
||||||
CompiledObject: native
|
|
||||||
Build$: flag(bench)
|
|
||||||
BuildDepends: sequence,benchmark
|
|
||||||
MainIs: bench_persistent.ml
|
|
||||||
|
|
||||||
Executable bench_persistent_read
|
|
||||||
Path: bench
|
|
||||||
Install: false
|
|
||||||
CompiledObject: native
|
|
||||||
Build$: flag(bench)
|
|
||||||
BuildDepends: sequence,benchmark
|
|
||||||
MainIs: bench_persistent_read.ml
|
|
||||||
|
|
||||||
SourceRepository head
|
|
||||||
Type: git
|
|
||||||
Location: https://github.com/c-cube/sequence
|
|
||||||
Browser: https://github.com/c-cube/sequence/tree/master/src
|
|
||||||
58
_tags
58
_tags
|
|
@ -1,58 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: 5495b2a66019398a5b6c2172a2c3ba42)
|
|
||||||
# Ignore VCS directories, you can use the same kind of rule outside
|
|
||||||
# OASIS_START/STOP if you want to exclude directories that contains
|
|
||||||
# useless stuff for the build process
|
|
||||||
true: annot, bin_annot
|
|
||||||
<**/.svn>: -traverse
|
|
||||||
<**/.svn>: not_hygienic
|
|
||||||
".bzr": -traverse
|
|
||||||
".bzr": not_hygienic
|
|
||||||
".hg": -traverse
|
|
||||||
".hg": not_hygienic
|
|
||||||
".git": -traverse
|
|
||||||
".git": not_hygienic
|
|
||||||
"_darcs": -traverse
|
|
||||||
"_darcs": not_hygienic
|
|
||||||
# Library sequence
|
|
||||||
"src/sequence.cmxs": use_sequence
|
|
||||||
<src/*.ml{,i,y}>: pkg_bytes
|
|
||||||
# Library invert
|
|
||||||
"src/invert/invert.cmxs": use_invert
|
|
||||||
<src/invert/*.ml{,i,y}>: pkg_bytes
|
|
||||||
<src/invert/*.ml{,i,y}>: pkg_delimcc
|
|
||||||
<src/invert/*.ml{,i,y}>: use_sequence
|
|
||||||
# Library bigarray
|
|
||||||
"src/bigarray/bigarray.cmxs": use_bigarray
|
|
||||||
<src/bigarray/*.ml{,i,y}>: pkg_bigarray
|
|
||||||
<src/bigarray/*.ml{,i,y}>: pkg_bytes
|
|
||||||
<src/bigarray/*.ml{,i,y}>: use_sequence
|
|
||||||
# Executable run_qtest
|
|
||||||
"qtest/run_qtest.native": pkg_bytes
|
|
||||||
"qtest/run_qtest.native": pkg_qcheck
|
|
||||||
"qtest/run_qtest.native": use_sequence
|
|
||||||
<qtest/*.ml{,i,y}>: pkg_bytes
|
|
||||||
<qtest/*.ml{,i,y}>: pkg_qcheck
|
|
||||||
<qtest/*.ml{,i,y}>: use_sequence
|
|
||||||
# Executable benchs
|
|
||||||
"bench/benchs.native": pkg_benchmark
|
|
||||||
"bench/benchs.native": pkg_bytes
|
|
||||||
"bench/benchs.native": use_sequence
|
|
||||||
# Executable bench_persistent
|
|
||||||
"bench/bench_persistent.native": pkg_benchmark
|
|
||||||
"bench/bench_persistent.native": pkg_bytes
|
|
||||||
"bench/bench_persistent.native": use_sequence
|
|
||||||
# Executable bench_persistent_read
|
|
||||||
"bench/bench_persistent_read.native": pkg_benchmark
|
|
||||||
"bench/bench_persistent_read.native": pkg_bytes
|
|
||||||
"bench/bench_persistent_read.native": use_sequence
|
|
||||||
<bench/*.ml{,i,y}>: pkg_benchmark
|
|
||||||
<bench/*.ml{,i,y}>: pkg_bytes
|
|
||||||
<bench/*.ml{,i,y}>: use_sequence
|
|
||||||
# OASIS_STOP
|
|
||||||
true: safe_string, bin_annot, color(always)
|
|
||||||
<**/*.ml>: warn(+a-4-44-48@8)
|
|
||||||
<src/bigarray/*.ml>: warn(-33)
|
|
||||||
true: mark_tag_used
|
|
||||||
<**/*.cmx>: optimize(3)
|
|
||||||
<src/*Labels.cm*>: nolabels
|
|
||||||
8
bench/jbuild
Normal file
8
bench/jbuild
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
(executables
|
||||||
|
((names (bench_persistent_read bench_persistent))
|
||||||
|
(libraries (sequence benchmark))
|
||||||
|
(flags (:standard -w +a-4-42-44-48-50-58-32-60@8 -safe-string -color always))
|
||||||
|
(ocamlopt_flags (:standard -O3 -color always
|
||||||
|
-unbox-closures -unbox-closures-factor 20))
|
||||||
|
))
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: dca476c3b57e859aa3b1c75ec0959ed9)
|
|
||||||
SequenceBigarray
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: dca476c3b57e859aa3b1c75ec0959ed9)
|
|
||||||
SequenceBigarray
|
|
||||||
# OASIS_STOP
|
|
||||||
27
configure
vendored
27
configure
vendored
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: dc86c2ad450f91ca10c931b6045d0499)
|
|
||||||
set -e
|
|
||||||
|
|
||||||
FST=true
|
|
||||||
for i in "$@"; do
|
|
||||||
if $FST; then
|
|
||||||
set --
|
|
||||||
FST=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $i in
|
|
||||||
--*=*)
|
|
||||||
ARG=${i%%=*}
|
|
||||||
VAL=${i##*=}
|
|
||||||
set -- "$@" "$ARG" "$VAL"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set -- "$@" "$i"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
ocaml setup.ml -configure "$@"
|
|
||||||
# OASIS_STOP
|
|
||||||
8
examples/jbuild
Normal file
8
examples/jbuild
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
(executable
|
||||||
|
((name test_sexpr)
|
||||||
|
(libraries (sequence))
|
||||||
|
(flags (:standard -w +a-4-42-44-48-50-58-32-60@8 -safe-string -color always))
|
||||||
|
(ocamlopt_flags (:standard -O3 -color always
|
||||||
|
-unbox-closures -unbox-closures-factor 20))
|
||||||
|
))
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: d74492d261fcc87665b60e0331c04236)
|
|
||||||
SequenceInvert
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: d74492d261fcc87665b60e0331c04236)
|
|
||||||
SequenceInvert
|
|
||||||
# OASIS_STOP
|
|
||||||
906
myocamlbuild.ml
906
myocamlbuild.ml
|
|
@ -1,906 +0,0 @@
|
||||||
(* OASIS_START *)
|
|
||||||
(* DO NOT EDIT (digest: df4781680e858ab0acccf45efeb50c19) *)
|
|
||||||
module OASISGettext = struct
|
|
||||||
(* # 22 "src/oasis/OASISGettext.ml" *)
|
|
||||||
|
|
||||||
|
|
||||||
let ns_ str = str
|
|
||||||
let s_ str = str
|
|
||||||
let f_ (str: ('a, 'b, 'c, 'd) format4) = str
|
|
||||||
|
|
||||||
|
|
||||||
let fn_ fmt1 fmt2 n =
|
|
||||||
if n = 1 then
|
|
||||||
fmt1^^""
|
|
||||||
else
|
|
||||||
fmt2^^""
|
|
||||||
|
|
||||||
|
|
||||||
let init = []
|
|
||||||
end
|
|
||||||
|
|
||||||
module OASISString = struct
|
|
||||||
(* # 22 "src/oasis/OASISString.ml" *)
|
|
||||||
|
|
||||||
|
|
||||||
(** Various string utilities.
|
|
||||||
|
|
||||||
Mostly inspired by extlib and batteries ExtString and BatString libraries.
|
|
||||||
|
|
||||||
@author Sylvain Le Gall
|
|
||||||
*)
|
|
||||||
|
|
||||||
|
|
||||||
let nsplitf str f =
|
|
||||||
if str = "" then
|
|
||||||
[]
|
|
||||||
else
|
|
||||||
let buf = Buffer.create 13 in
|
|
||||||
let lst = ref [] in
|
|
||||||
let push () =
|
|
||||||
lst := Buffer.contents buf :: !lst;
|
|
||||||
Buffer.clear buf
|
|
||||||
in
|
|
||||||
let str_len = String.length str in
|
|
||||||
for i = 0 to str_len - 1 do
|
|
||||||
if f str.[i] then
|
|
||||||
push ()
|
|
||||||
else
|
|
||||||
Buffer.add_char buf str.[i]
|
|
||||||
done;
|
|
||||||
push ();
|
|
||||||
List.rev !lst
|
|
||||||
|
|
||||||
|
|
||||||
(** [nsplit c s] Split the string [s] at char [c]. It doesn't include the
|
|
||||||
separator.
|
|
||||||
*)
|
|
||||||
let nsplit str c =
|
|
||||||
nsplitf str ((=) c)
|
|
||||||
|
|
||||||
|
|
||||||
let find ~what ?(offset=0) str =
|
|
||||||
let what_idx = ref 0 in
|
|
||||||
let str_idx = ref offset in
|
|
||||||
while !str_idx < String.length str &&
|
|
||||||
!what_idx < String.length what do
|
|
||||||
if str.[!str_idx] = what.[!what_idx] then
|
|
||||||
incr what_idx
|
|
||||||
else
|
|
||||||
what_idx := 0;
|
|
||||||
incr str_idx
|
|
||||||
done;
|
|
||||||
if !what_idx <> String.length what then
|
|
||||||
raise Not_found
|
|
||||||
else
|
|
||||||
!str_idx - !what_idx
|
|
||||||
|
|
||||||
|
|
||||||
let sub_start str len =
|
|
||||||
let str_len = String.length str in
|
|
||||||
if len >= str_len then
|
|
||||||
""
|
|
||||||
else
|
|
||||||
String.sub str len (str_len - len)
|
|
||||||
|
|
||||||
|
|
||||||
let sub_end ?(offset=0) str len =
|
|
||||||
let str_len = String.length str in
|
|
||||||
if len >= str_len then
|
|
||||||
""
|
|
||||||
else
|
|
||||||
String.sub str 0 (str_len - len)
|
|
||||||
|
|
||||||
|
|
||||||
let starts_with ~what ?(offset=0) str =
|
|
||||||
let what_idx = ref 0 in
|
|
||||||
let str_idx = ref offset in
|
|
||||||
let ok = ref true in
|
|
||||||
while !ok &&
|
|
||||||
!str_idx < String.length str &&
|
|
||||||
!what_idx < String.length what do
|
|
||||||
if str.[!str_idx] = what.[!what_idx] then
|
|
||||||
incr what_idx
|
|
||||||
else
|
|
||||||
ok := false;
|
|
||||||
incr str_idx
|
|
||||||
done;
|
|
||||||
!what_idx = String.length what
|
|
||||||
|
|
||||||
|
|
||||||
let strip_starts_with ~what str =
|
|
||||||
if starts_with ~what str then
|
|
||||||
sub_start str (String.length what)
|
|
||||||
else
|
|
||||||
raise Not_found
|
|
||||||
|
|
||||||
|
|
||||||
let ends_with ~what ?(offset=0) str =
|
|
||||||
let what_idx = ref ((String.length what) - 1) in
|
|
||||||
let str_idx = ref ((String.length str) - 1) in
|
|
||||||
let ok = ref true in
|
|
||||||
while !ok &&
|
|
||||||
offset <= !str_idx &&
|
|
||||||
0 <= !what_idx do
|
|
||||||
if str.[!str_idx] = what.[!what_idx] then
|
|
||||||
decr what_idx
|
|
||||||
else
|
|
||||||
ok := false;
|
|
||||||
decr str_idx
|
|
||||||
done;
|
|
||||||
!what_idx = -1
|
|
||||||
|
|
||||||
|
|
||||||
let strip_ends_with ~what str =
|
|
||||||
if ends_with ~what str then
|
|
||||||
sub_end str (String.length what)
|
|
||||||
else
|
|
||||||
raise Not_found
|
|
||||||
|
|
||||||
|
|
||||||
let replace_chars f s =
|
|
||||||
let buf = Buffer.create (String.length s) in
|
|
||||||
String.iter (fun c -> Buffer.add_char buf (f c)) s;
|
|
||||||
Buffer.contents buf
|
|
||||||
|
|
||||||
let lowercase_ascii =
|
|
||||||
replace_chars
|
|
||||||
(fun c ->
|
|
||||||
if (c >= 'A' && c <= 'Z') then
|
|
||||||
Char.chr (Char.code c + 32)
|
|
||||||
else
|
|
||||||
c)
|
|
||||||
|
|
||||||
let uncapitalize_ascii s =
|
|
||||||
if s <> "" then
|
|
||||||
(lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
|
|
||||||
else
|
|
||||||
s
|
|
||||||
|
|
||||||
let uppercase_ascii =
|
|
||||||
replace_chars
|
|
||||||
(fun c ->
|
|
||||||
if (c >= 'a' && c <= 'z') then
|
|
||||||
Char.chr (Char.code c - 32)
|
|
||||||
else
|
|
||||||
c)
|
|
||||||
|
|
||||||
let capitalize_ascii s =
|
|
||||||
if s <> "" then
|
|
||||||
(uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
|
|
||||||
else
|
|
||||||
s
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module OASISUtils = struct
|
|
||||||
(* # 22 "src/oasis/OASISUtils.ml" *)
|
|
||||||
|
|
||||||
|
|
||||||
open OASISGettext
|
|
||||||
|
|
||||||
|
|
||||||
module MapExt =
|
|
||||||
struct
|
|
||||||
module type S =
|
|
||||||
sig
|
|
||||||
include Map.S
|
|
||||||
val add_list: 'a t -> (key * 'a) list -> 'a t
|
|
||||||
val of_list: (key * 'a) list -> 'a t
|
|
||||||
val to_list: 'a t -> (key * 'a) list
|
|
||||||
end
|
|
||||||
|
|
||||||
module Make (Ord: Map.OrderedType) =
|
|
||||||
struct
|
|
||||||
include Map.Make(Ord)
|
|
||||||
|
|
||||||
let rec add_list t =
|
|
||||||
function
|
|
||||||
| (k, v) :: tl -> add_list (add k v t) tl
|
|
||||||
| [] -> t
|
|
||||||
|
|
||||||
let of_list lst = add_list empty lst
|
|
||||||
|
|
||||||
let to_list t = fold (fun k v acc -> (k, v) :: acc) t []
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
module MapString = MapExt.Make(String)
|
|
||||||
|
|
||||||
|
|
||||||
module SetExt =
|
|
||||||
struct
|
|
||||||
module type S =
|
|
||||||
sig
|
|
||||||
include Set.S
|
|
||||||
val add_list: t -> elt list -> t
|
|
||||||
val of_list: elt list -> t
|
|
||||||
val to_list: t -> elt list
|
|
||||||
end
|
|
||||||
|
|
||||||
module Make (Ord: Set.OrderedType) =
|
|
||||||
struct
|
|
||||||
include Set.Make(Ord)
|
|
||||||
|
|
||||||
let rec add_list t =
|
|
||||||
function
|
|
||||||
| e :: tl -> add_list (add e t) tl
|
|
||||||
| [] -> t
|
|
||||||
|
|
||||||
let of_list lst = add_list empty lst
|
|
||||||
|
|
||||||
let to_list = elements
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
module SetString = SetExt.Make(String)
|
|
||||||
|
|
||||||
|
|
||||||
let compare_csl s1 s2 =
|
|
||||||
String.compare (OASISString.lowercase_ascii s1) (OASISString.lowercase_ascii s2)
|
|
||||||
|
|
||||||
|
|
||||||
module HashStringCsl =
|
|
||||||
Hashtbl.Make
|
|
||||||
(struct
|
|
||||||
type t = string
|
|
||||||
let equal s1 s2 = (compare_csl s1 s2) = 0
|
|
||||||
let hash s = Hashtbl.hash (OASISString.lowercase_ascii s)
|
|
||||||
end)
|
|
||||||
|
|
||||||
module SetStringCsl =
|
|
||||||
SetExt.Make
|
|
||||||
(struct
|
|
||||||
type t = string
|
|
||||||
let compare = compare_csl
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
let varname_of_string ?(hyphen='_') s =
|
|
||||||
if String.length s = 0 then
|
|
||||||
begin
|
|
||||||
invalid_arg "varname_of_string"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
let buf =
|
|
||||||
OASISString.replace_chars
|
|
||||||
(fun c ->
|
|
||||||
if ('a' <= c && c <= 'z')
|
|
||||||
||
|
|
||||||
('A' <= c && c <= 'Z')
|
|
||||||
||
|
|
||||||
('0' <= c && c <= '9') then
|
|
||||||
c
|
|
||||||
else
|
|
||||||
hyphen)
|
|
||||||
s;
|
|
||||||
in
|
|
||||||
let buf =
|
|
||||||
(* Start with a _ if digit *)
|
|
||||||
if '0' <= s.[0] && s.[0] <= '9' then
|
|
||||||
"_"^buf
|
|
||||||
else
|
|
||||||
buf
|
|
||||||
in
|
|
||||||
OASISString.lowercase_ascii buf
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
let varname_concat ?(hyphen='_') p s =
|
|
||||||
let what = String.make 1 hyphen in
|
|
||||||
let p =
|
|
||||||
try
|
|
||||||
OASISString.strip_ends_with ~what p
|
|
||||||
with Not_found ->
|
|
||||||
p
|
|
||||||
in
|
|
||||||
let s =
|
|
||||||
try
|
|
||||||
OASISString.strip_starts_with ~what s
|
|
||||||
with Not_found ->
|
|
||||||
s
|
|
||||||
in
|
|
||||||
p^what^s
|
|
||||||
|
|
||||||
|
|
||||||
let is_varname str =
|
|
||||||
str = varname_of_string str
|
|
||||||
|
|
||||||
|
|
||||||
let failwithf fmt = Printf.ksprintf failwith fmt
|
|
||||||
|
|
||||||
|
|
||||||
let rec file_location ?pos1 ?pos2 ?lexbuf () =
|
|
||||||
match pos1, pos2, lexbuf with
|
|
||||||
| Some p, None, _ | None, Some p, _ ->
|
|
||||||
file_location ~pos1:p ~pos2:p ?lexbuf ()
|
|
||||||
| Some p1, Some p2, _ ->
|
|
||||||
let open Lexing in
|
|
||||||
let fn, lineno = p1.pos_fname, p1.pos_lnum in
|
|
||||||
let c1 = p1.pos_cnum - p1.pos_bol in
|
|
||||||
let c2 = c1 + (p2.pos_cnum - p1.pos_cnum) in
|
|
||||||
Printf.sprintf (f_ "file %S, line %d, characters %d-%d") fn lineno c1 c2
|
|
||||||
| _, _, Some lexbuf ->
|
|
||||||
file_location
|
|
||||||
~pos1:(Lexing.lexeme_start_p lexbuf)
|
|
||||||
~pos2:(Lexing.lexeme_end_p lexbuf)
|
|
||||||
()
|
|
||||||
| None, None, None ->
|
|
||||||
s_ "<position undefined>"
|
|
||||||
|
|
||||||
|
|
||||||
let failwithpf ?pos1 ?pos2 ?lexbuf fmt =
|
|
||||||
let loc = file_location ?pos1 ?pos2 ?lexbuf () in
|
|
||||||
Printf.ksprintf (fun s -> failwith (Printf.sprintf "%s: %s" loc s)) fmt
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module OASISExpr = struct
|
|
||||||
(* # 22 "src/oasis/OASISExpr.ml" *)
|
|
||||||
|
|
||||||
|
|
||||||
open OASISGettext
|
|
||||||
open OASISUtils
|
|
||||||
|
|
||||||
|
|
||||||
type test = string
|
|
||||||
type flag = string
|
|
||||||
|
|
||||||
|
|
||||||
type t =
|
|
||||||
| EBool of bool
|
|
||||||
| ENot of t
|
|
||||||
| EAnd of t * t
|
|
||||||
| EOr of t * t
|
|
||||||
| EFlag of flag
|
|
||||||
| ETest of test * string
|
|
||||||
|
|
||||||
|
|
||||||
type 'a choices = (t * 'a) list
|
|
||||||
|
|
||||||
|
|
||||||
let eval var_get t =
|
|
||||||
let rec eval' =
|
|
||||||
function
|
|
||||||
| EBool b ->
|
|
||||||
b
|
|
||||||
|
|
||||||
| ENot e ->
|
|
||||||
not (eval' e)
|
|
||||||
|
|
||||||
| EAnd (e1, e2) ->
|
|
||||||
(eval' e1) && (eval' e2)
|
|
||||||
|
|
||||||
| EOr (e1, e2) ->
|
|
||||||
(eval' e1) || (eval' e2)
|
|
||||||
|
|
||||||
| EFlag nm ->
|
|
||||||
let v =
|
|
||||||
var_get nm
|
|
||||||
in
|
|
||||||
assert(v = "true" || v = "false");
|
|
||||||
(v = "true")
|
|
||||||
|
|
||||||
| ETest (nm, vl) ->
|
|
||||||
let v =
|
|
||||||
var_get nm
|
|
||||||
in
|
|
||||||
(v = vl)
|
|
||||||
in
|
|
||||||
eval' t
|
|
||||||
|
|
||||||
|
|
||||||
let choose ?printer ?name var_get lst =
|
|
||||||
let rec choose_aux =
|
|
||||||
function
|
|
||||||
| (cond, vl) :: tl ->
|
|
||||||
if eval var_get cond then
|
|
||||||
vl
|
|
||||||
else
|
|
||||||
choose_aux tl
|
|
||||||
| [] ->
|
|
||||||
let str_lst =
|
|
||||||
if lst = [] then
|
|
||||||
s_ "<empty>"
|
|
||||||
else
|
|
||||||
String.concat
|
|
||||||
(s_ ", ")
|
|
||||||
(List.map
|
|
||||||
(fun (cond, vl) ->
|
|
||||||
match printer with
|
|
||||||
| Some p -> p vl
|
|
||||||
| None -> s_ "<no printer>")
|
|
||||||
lst)
|
|
||||||
in
|
|
||||||
match name with
|
|
||||||
| Some nm ->
|
|
||||||
failwith
|
|
||||||
(Printf.sprintf
|
|
||||||
(f_ "No result for the choice list '%s': %s")
|
|
||||||
nm str_lst)
|
|
||||||
| None ->
|
|
||||||
failwith
|
|
||||||
(Printf.sprintf
|
|
||||||
(f_ "No result for a choice list: %s")
|
|
||||||
str_lst)
|
|
||||||
in
|
|
||||||
choose_aux (List.rev lst)
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# 437 "myocamlbuild.ml"
|
|
||||||
module BaseEnvLight = struct
|
|
||||||
(* # 22 "src/base/BaseEnvLight.ml" *)
|
|
||||||
|
|
||||||
|
|
||||||
module MapString = Map.Make(String)
|
|
||||||
|
|
||||||
|
|
||||||
type t = string MapString.t
|
|
||||||
|
|
||||||
|
|
||||||
let default_filename = Filename.concat (Sys.getcwd ()) "setup.data"
|
|
||||||
|
|
||||||
|
|
||||||
let load ?(allow_empty=false) ?(filename=default_filename) ?stream () =
|
|
||||||
let line = ref 1 in
|
|
||||||
let lexer st =
|
|
||||||
let st_line =
|
|
||||||
Stream.from
|
|
||||||
(fun _ ->
|
|
||||||
try
|
|
||||||
match Stream.next st with
|
|
||||||
| '\n' -> incr line; Some '\n'
|
|
||||||
| c -> Some c
|
|
||||||
with Stream.Failure -> None)
|
|
||||||
in
|
|
||||||
Genlex.make_lexer ["="] st_line
|
|
||||||
in
|
|
||||||
let rec read_file lxr mp =
|
|
||||||
match Stream.npeek 3 lxr with
|
|
||||||
| [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
|
|
||||||
Stream.junk lxr; Stream.junk lxr; Stream.junk lxr;
|
|
||||||
read_file lxr (MapString.add nm value mp)
|
|
||||||
| [] -> mp
|
|
||||||
| _ ->
|
|
||||||
failwith
|
|
||||||
(Printf.sprintf "Malformed data file '%s' line %d" filename !line)
|
|
||||||
in
|
|
||||||
match stream with
|
|
||||||
| Some st -> read_file (lexer st) MapString.empty
|
|
||||||
| None ->
|
|
||||||
if Sys.file_exists filename then begin
|
|
||||||
let chn = open_in_bin filename in
|
|
||||||
let st = Stream.of_channel chn in
|
|
||||||
try
|
|
||||||
let mp = read_file (lexer st) MapString.empty in
|
|
||||||
close_in chn; mp
|
|
||||||
with e ->
|
|
||||||
close_in chn; raise e
|
|
||||||
end else if allow_empty then begin
|
|
||||||
MapString.empty
|
|
||||||
end else begin
|
|
||||||
failwith
|
|
||||||
(Printf.sprintf
|
|
||||||
"Unable to load environment, the file '%s' doesn't exist."
|
|
||||||
filename)
|
|
||||||
end
|
|
||||||
|
|
||||||
let rec var_expand str env =
|
|
||||||
let buff = Buffer.create ((String.length str) * 2) in
|
|
||||||
Buffer.add_substitute
|
|
||||||
buff
|
|
||||||
(fun var ->
|
|
||||||
try
|
|
||||||
var_expand (MapString.find var env) env
|
|
||||||
with Not_found ->
|
|
||||||
failwith
|
|
||||||
(Printf.sprintf
|
|
||||||
"No variable %s defined when trying to expand %S."
|
|
||||||
var
|
|
||||||
str))
|
|
||||||
str;
|
|
||||||
Buffer.contents buff
|
|
||||||
|
|
||||||
|
|
||||||
let var_get name env = var_expand (MapString.find name env) env
|
|
||||||
let var_choose lst env = OASISExpr.choose (fun nm -> var_get nm env) lst
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# 517 "myocamlbuild.ml"
|
|
||||||
module MyOCamlbuildFindlib = struct
|
|
||||||
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
|
|
||||||
|
|
||||||
|
|
||||||
(** OCamlbuild extension, copied from
|
|
||||||
* https://ocaml.org/learn/tutorials/ocamlbuild/Using_ocamlfind_with_ocamlbuild.html
|
|
||||||
* by N. Pouillard and others
|
|
||||||
*
|
|
||||||
* Updated on 2016-06-02
|
|
||||||
*
|
|
||||||
* Modified by Sylvain Le Gall
|
|
||||||
*)
|
|
||||||
open Ocamlbuild_plugin
|
|
||||||
|
|
||||||
|
|
||||||
type conf = {no_automatic_syntax: bool}
|
|
||||||
|
|
||||||
|
|
||||||
let run_and_read = Ocamlbuild_pack.My_unix.run_and_read
|
|
||||||
|
|
||||||
|
|
||||||
let blank_sep_strings = Ocamlbuild_pack.Lexers.blank_sep_strings
|
|
||||||
|
|
||||||
|
|
||||||
let exec_from_conf exec =
|
|
||||||
let exec =
|
|
||||||
let env = BaseEnvLight.load ~allow_empty:true () in
|
|
||||||
try
|
|
||||||
BaseEnvLight.var_get exec env
|
|
||||||
with Not_found ->
|
|
||||||
Printf.eprintf "W: Cannot get variable %s\n" exec;
|
|
||||||
exec
|
|
||||||
in
|
|
||||||
let fix_win32 str =
|
|
||||||
if Sys.os_type = "Win32" then begin
|
|
||||||
let buff = Buffer.create (String.length str) in
|
|
||||||
(* Adapt for windowsi, ocamlbuild + win32 has a hard time to handle '\\'.
|
|
||||||
*)
|
|
||||||
String.iter
|
|
||||||
(fun c -> Buffer.add_char buff (if c = '\\' then '/' else c))
|
|
||||||
str;
|
|
||||||
Buffer.contents buff
|
|
||||||
end else begin
|
|
||||||
str
|
|
||||||
end
|
|
||||||
in
|
|
||||||
fix_win32 exec
|
|
||||||
|
|
||||||
|
|
||||||
let split s ch =
|
|
||||||
let buf = Buffer.create 13 in
|
|
||||||
let x = ref [] in
|
|
||||||
let flush () =
|
|
||||||
x := (Buffer.contents buf) :: !x;
|
|
||||||
Buffer.clear buf
|
|
||||||
in
|
|
||||||
String.iter
|
|
||||||
(fun c ->
|
|
||||||
if c = ch then
|
|
||||||
flush ()
|
|
||||||
else
|
|
||||||
Buffer.add_char buf c)
|
|
||||||
s;
|
|
||||||
flush ();
|
|
||||||
List.rev !x
|
|
||||||
|
|
||||||
|
|
||||||
let split_nl s = split s '\n'
|
|
||||||
|
|
||||||
|
|
||||||
let before_space s =
|
|
||||||
try
|
|
||||||
String.before s (String.index s ' ')
|
|
||||||
with Not_found -> s
|
|
||||||
|
|
||||||
(* ocamlfind command *)
|
|
||||||
let ocamlfind x = S[Sh (exec_from_conf "ocamlfind"); x]
|
|
||||||
|
|
||||||
(* This lists all supported packages. *)
|
|
||||||
let find_packages () =
|
|
||||||
List.map before_space (split_nl & run_and_read (exec_from_conf "ocamlfind" ^ " list"))
|
|
||||||
|
|
||||||
|
|
||||||
(* Mock to list available syntaxes. *)
|
|
||||||
let find_syntaxes () = ["camlp4o"; "camlp4r"]
|
|
||||||
|
|
||||||
|
|
||||||
let well_known_syntax = [
|
|
||||||
"camlp4.quotations.o";
|
|
||||||
"camlp4.quotations.r";
|
|
||||||
"camlp4.exceptiontracer";
|
|
||||||
"camlp4.extend";
|
|
||||||
"camlp4.foldgenerator";
|
|
||||||
"camlp4.listcomprehension";
|
|
||||||
"camlp4.locationstripper";
|
|
||||||
"camlp4.macro";
|
|
||||||
"camlp4.mapgenerator";
|
|
||||||
"camlp4.metagenerator";
|
|
||||||
"camlp4.profiler";
|
|
||||||
"camlp4.tracer"
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
let dispatch conf =
|
|
||||||
function
|
|
||||||
| After_options ->
|
|
||||||
(* By using Before_options one let command line options have an higher
|
|
||||||
* priority on the contrary using After_options will guarantee to have
|
|
||||||
* the higher priority override default commands by ocamlfind ones *)
|
|
||||||
Options.ocamlc := ocamlfind & A"ocamlc";
|
|
||||||
Options.ocamlopt := ocamlfind & A"ocamlopt";
|
|
||||||
Options.ocamldep := ocamlfind & A"ocamldep";
|
|
||||||
Options.ocamldoc := ocamlfind & A"ocamldoc";
|
|
||||||
Options.ocamlmktop := ocamlfind & A"ocamlmktop";
|
|
||||||
Options.ocamlmklib := ocamlfind & A"ocamlmklib"
|
|
||||||
|
|
||||||
| After_rules ->
|
|
||||||
|
|
||||||
(* Avoid warnings for unused tag *)
|
|
||||||
flag ["tests"] N;
|
|
||||||
|
|
||||||
(* When one link an OCaml library/binary/package, one should use
|
|
||||||
* -linkpkg *)
|
|
||||||
flag ["ocaml"; "link"; "program"] & A"-linkpkg";
|
|
||||||
|
|
||||||
(* For each ocamlfind package one inject the -package option when
|
|
||||||
* compiling, computing dependencies, generating documentation and
|
|
||||||
* linking. *)
|
|
||||||
List.iter
|
|
||||||
begin fun pkg ->
|
|
||||||
let base_args = [A"-package"; A pkg] in
|
|
||||||
(* TODO: consider how to really choose camlp4o or camlp4r. *)
|
|
||||||
let syn_args = [A"-syntax"; A "camlp4o"] in
|
|
||||||
let (args, pargs) =
|
|
||||||
(* Heuristic to identify syntax extensions: whether they end in
|
|
||||||
".syntax"; some might not.
|
|
||||||
*)
|
|
||||||
if not (conf.no_automatic_syntax) &&
|
|
||||||
(Filename.check_suffix pkg "syntax" ||
|
|
||||||
List.mem pkg well_known_syntax) then
|
|
||||||
(syn_args @ base_args, syn_args)
|
|
||||||
else
|
|
||||||
(base_args, [])
|
|
||||||
in
|
|
||||||
flag ["ocaml"; "compile"; "pkg_"^pkg] & S args;
|
|
||||||
flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S args;
|
|
||||||
flag ["ocaml"; "doc"; "pkg_"^pkg] & S args;
|
|
||||||
flag ["ocaml"; "link"; "pkg_"^pkg] & S base_args;
|
|
||||||
flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S args;
|
|
||||||
|
|
||||||
(* TODO: Check if this is allowed for OCaml < 3.12.1 *)
|
|
||||||
flag ["ocaml"; "compile"; "package("^pkg^")"] & S pargs;
|
|
||||||
flag ["ocaml"; "ocamldep"; "package("^pkg^")"] & S pargs;
|
|
||||||
flag ["ocaml"; "doc"; "package("^pkg^")"] & S pargs;
|
|
||||||
flag ["ocaml"; "infer_interface"; "package("^pkg^")"] & S pargs;
|
|
||||||
end
|
|
||||||
(find_packages ());
|
|
||||||
|
|
||||||
(* Like -package but for extensions syntax. Morover -syntax is useless
|
|
||||||
* when linking. *)
|
|
||||||
List.iter begin fun syntax ->
|
|
||||||
flag ["ocaml"; "compile"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
|
|
||||||
flag ["ocaml"; "ocamldep"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
|
|
||||||
flag ["ocaml"; "doc"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
|
|
||||||
flag ["ocaml"; "infer_interface"; "syntax_"^syntax] &
|
|
||||||
S[A"-syntax"; A syntax];
|
|
||||||
end (find_syntaxes ());
|
|
||||||
|
|
||||||
(* The default "thread" tag is not compatible with ocamlfind.
|
|
||||||
* Indeed, the default rules add the "threads.cma" or "threads.cmxa"
|
|
||||||
* options when using this tag. When using the "-linkpkg" option with
|
|
||||||
* ocamlfind, this module will then be added twice on the command line.
|
|
||||||
*
|
|
||||||
* To solve this, one approach is to add the "-thread" option when using
|
|
||||||
* the "threads" package using the previous plugin.
|
|
||||||
*)
|
|
||||||
flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]);
|
|
||||||
flag ["ocaml"; "pkg_threads"; "doc"] (S[A "-I"; A "+threads"]);
|
|
||||||
flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
|
|
||||||
flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"]);
|
|
||||||
flag ["c"; "pkg_threads"; "compile"] (S[A "-thread"]);
|
|
||||||
flag ["ocaml"; "package(threads)"; "compile"] (S[A "-thread"]);
|
|
||||||
flag ["ocaml"; "package(threads)"; "doc"] (S[A "-I"; A "+threads"]);
|
|
||||||
flag ["ocaml"; "package(threads)"; "link"] (S[A "-thread"]);
|
|
||||||
flag ["ocaml"; "package(threads)"; "infer_interface"] (S[A "-thread"]);
|
|
||||||
flag ["c"; "package(threads)"; "compile"] (S[A "-thread"]);
|
|
||||||
|
|
||||||
| _ ->
|
|
||||||
()
|
|
||||||
end
|
|
||||||
|
|
||||||
module MyOCamlbuildBase = struct
|
|
||||||
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
|
|
||||||
|
|
||||||
|
|
||||||
(** Base functions for writing myocamlbuild.ml
|
|
||||||
@author Sylvain Le Gall
|
|
||||||
*)
|
|
||||||
|
|
||||||
|
|
||||||
open Ocamlbuild_plugin
|
|
||||||
module OC = Ocamlbuild_pack.Ocaml_compiler
|
|
||||||
|
|
||||||
|
|
||||||
type dir = string
|
|
||||||
type file = string
|
|
||||||
type name = string
|
|
||||||
type tag = string
|
|
||||||
|
|
||||||
|
|
||||||
type t =
|
|
||||||
{
|
|
||||||
lib_ocaml: (name * dir list * string list) list;
|
|
||||||
lib_c: (name * dir * file list) list;
|
|
||||||
flags: (tag list * (spec OASISExpr.choices)) list;
|
|
||||||
(* Replace the 'dir: include' from _tags by a precise interdepends in
|
|
||||||
* directory.
|
|
||||||
*)
|
|
||||||
includes: (dir * dir list) list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
(* # 110 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
|
|
||||||
|
|
||||||
|
|
||||||
let env_filename = Pathname.basename BaseEnvLight.default_filename
|
|
||||||
|
|
||||||
|
|
||||||
let dispatch_combine lst =
|
|
||||||
fun e ->
|
|
||||||
List.iter
|
|
||||||
(fun dispatch -> dispatch e)
|
|
||||||
lst
|
|
||||||
|
|
||||||
|
|
||||||
let tag_libstubs nm =
|
|
||||||
"use_lib"^nm^"_stubs"
|
|
||||||
|
|
||||||
|
|
||||||
let nm_libstubs nm =
|
|
||||||
nm^"_stubs"
|
|
||||||
|
|
||||||
|
|
||||||
let dispatch t e =
|
|
||||||
let env = BaseEnvLight.load ~allow_empty:true () in
|
|
||||||
match e with
|
|
||||||
| Before_options ->
|
|
||||||
let no_trailing_dot s =
|
|
||||||
if String.length s >= 1 && s.[0] = '.' then
|
|
||||||
String.sub s 1 ((String.length s) - 1)
|
|
||||||
else
|
|
||||||
s
|
|
||||||
in
|
|
||||||
List.iter
|
|
||||||
(fun (opt, var) ->
|
|
||||||
try
|
|
||||||
opt := no_trailing_dot (BaseEnvLight.var_get var env)
|
|
||||||
with Not_found ->
|
|
||||||
Printf.eprintf "W: Cannot get variable %s\n" var)
|
|
||||||
[
|
|
||||||
Options.ext_obj, "ext_obj";
|
|
||||||
Options.ext_lib, "ext_lib";
|
|
||||||
Options.ext_dll, "ext_dll";
|
|
||||||
]
|
|
||||||
|
|
||||||
| After_rules ->
|
|
||||||
(* Declare OCaml libraries *)
|
|
||||||
List.iter
|
|
||||||
(function
|
|
||||||
| nm, [], intf_modules ->
|
|
||||||
ocaml_lib nm;
|
|
||||||
let cmis =
|
|
||||||
List.map (fun m -> (OASISString.uncapitalize_ascii m) ^ ".cmi")
|
|
||||||
intf_modules in
|
|
||||||
dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis
|
|
||||||
| nm, dir :: tl, intf_modules ->
|
|
||||||
ocaml_lib ~dir:dir (dir^"/"^nm);
|
|
||||||
List.iter
|
|
||||||
(fun dir ->
|
|
||||||
List.iter
|
|
||||||
(fun str ->
|
|
||||||
flag ["ocaml"; "use_"^nm; str] (S[A"-I"; P dir]))
|
|
||||||
["compile"; "infer_interface"; "doc"])
|
|
||||||
tl;
|
|
||||||
let cmis =
|
|
||||||
List.map (fun m -> dir^"/"^(OASISString.uncapitalize_ascii m)^".cmi")
|
|
||||||
intf_modules in
|
|
||||||
dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"]
|
|
||||||
cmis)
|
|
||||||
t.lib_ocaml;
|
|
||||||
|
|
||||||
(* Declare directories dependencies, replace "include" in _tags. *)
|
|
||||||
List.iter
|
|
||||||
(fun (dir, include_dirs) ->
|
|
||||||
Pathname.define_context dir include_dirs)
|
|
||||||
t.includes;
|
|
||||||
|
|
||||||
(* Declare C libraries *)
|
|
||||||
List.iter
|
|
||||||
(fun (lib, dir, headers) ->
|
|
||||||
(* Handle C part of library *)
|
|
||||||
flag ["link"; "library"; "ocaml"; "byte"; tag_libstubs lib]
|
|
||||||
(S[A"-dllib"; A("-l"^(nm_libstubs lib)); A"-cclib";
|
|
||||||
A("-l"^(nm_libstubs lib))]);
|
|
||||||
|
|
||||||
flag ["link"; "library"; "ocaml"; "native"; tag_libstubs lib]
|
|
||||||
(S[A"-cclib"; A("-l"^(nm_libstubs lib))]);
|
|
||||||
|
|
||||||
if bool_of_string (BaseEnvLight.var_get "native_dynlink" env) then
|
|
||||||
flag ["link"; "program"; "ocaml"; "byte"; tag_libstubs lib]
|
|
||||||
(S[A"-dllib"; A("dll"^(nm_libstubs lib))]);
|
|
||||||
|
|
||||||
(* When ocaml link something that use the C library, then one
|
|
||||||
need that file to be up to date.
|
|
||||||
This holds both for programs and for libraries.
|
|
||||||
*)
|
|
||||||
dep ["link"; "ocaml"; tag_libstubs lib]
|
|
||||||
[dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
|
|
||||||
|
|
||||||
dep ["compile"; "ocaml"; tag_libstubs lib]
|
|
||||||
[dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
|
|
||||||
|
|
||||||
(* TODO: be more specific about what depends on headers *)
|
|
||||||
(* Depends on .h files *)
|
|
||||||
dep ["compile"; "c"]
|
|
||||||
headers;
|
|
||||||
|
|
||||||
(* Setup search path for lib *)
|
|
||||||
flag ["link"; "ocaml"; "use_"^lib]
|
|
||||||
(S[A"-I"; P(dir)]);
|
|
||||||
)
|
|
||||||
t.lib_c;
|
|
||||||
|
|
||||||
(* Add flags *)
|
|
||||||
List.iter
|
|
||||||
(fun (tags, cond_specs) ->
|
|
||||||
let spec = BaseEnvLight.var_choose cond_specs env in
|
|
||||||
let rec eval_specs =
|
|
||||||
function
|
|
||||||
| S lst -> S (List.map eval_specs lst)
|
|
||||||
| A str -> A (BaseEnvLight.var_expand str env)
|
|
||||||
| spec -> spec
|
|
||||||
in
|
|
||||||
flag tags & (eval_specs spec))
|
|
||||||
t.flags
|
|
||||||
| _ ->
|
|
||||||
()
|
|
||||||
|
|
||||||
|
|
||||||
let dispatch_default conf t =
|
|
||||||
dispatch_combine
|
|
||||||
[
|
|
||||||
dispatch t;
|
|
||||||
MyOCamlbuildFindlib.dispatch conf;
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# 878 "myocamlbuild.ml"
|
|
||||||
open Ocamlbuild_plugin;;
|
|
||||||
let package_default =
|
|
||||||
{
|
|
||||||
MyOCamlbuildBase.lib_ocaml =
|
|
||||||
[
|
|
||||||
("sequence", ["src"], []);
|
|
||||||
("invert", ["src/invert"], []);
|
|
||||||
("bigarray", ["src/bigarray"], [])
|
|
||||||
];
|
|
||||||
lib_c = [];
|
|
||||||
flags = [];
|
|
||||||
includes =
|
|
||||||
[
|
|
||||||
("src/invert", ["src"]);
|
|
||||||
("src/bigarray", ["src"]);
|
|
||||||
("qtest", ["src"]);
|
|
||||||
("bench", ["src"])
|
|
||||||
]
|
|
||||||
}
|
|
||||||
;;
|
|
||||||
|
|
||||||
let conf = {MyOCamlbuildFindlib.no_automatic_syntax = false}
|
|
||||||
|
|
||||||
let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
|
|
||||||
|
|
||||||
# 905 "myocamlbuild.ml"
|
|
||||||
(* OASIS_STOP *)
|
|
||||||
Ocamlbuild_plugin.dispatch dispatch_default;;
|
|
||||||
15
qtest/Makefile
Normal file
15
qtest/Makefile
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
QTEST_PREAMBLE=''
|
||||||
|
DONTTEST=../src/sequenceLabels.ml
|
||||||
|
QTESTABLE=$(filter-out $(DONTTEST), \
|
||||||
|
$(wildcard ../src/*.ml) \
|
||||||
|
$(wildcard ../src/*.mli) \
|
||||||
|
)
|
||||||
|
|
||||||
|
qtest-gen:
|
||||||
|
@if which qtest > /dev/null ; then \
|
||||||
|
qtest extract --preamble $(QTEST_PREAMBLE) \
|
||||||
|
-o run_qtest.ml \
|
||||||
|
$(QTESTABLE) 2> /dev/null ; \
|
||||||
|
else touch qtest/run_qtest.ml ; \
|
||||||
|
fi
|
||||||
21
qtest/jbuild
Normal file
21
qtest/jbuild
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
(rule
|
||||||
|
((targets (run_qtest.ml))
|
||||||
|
(deps ((file Makefile)))
|
||||||
|
(fallback)
|
||||||
|
;(libraries (qtest qcheck))
|
||||||
|
(action
|
||||||
|
(run make qtest-gen))
|
||||||
|
))
|
||||||
|
|
||||||
|
(executable
|
||||||
|
((name run_qtest)
|
||||||
|
(libraries (sequence qcheck))
|
||||||
|
))
|
||||||
|
|
||||||
|
(alias
|
||||||
|
((name runtest)
|
||||||
|
(deps (run_qtest.exe))
|
||||||
|
(action (run ${<}))
|
||||||
|
))
|
||||||
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: 5ddf4abb4ebf6a133d6ce26868d8dbf0)
|
|
||||||
src/Sequence
|
|
||||||
src/SequenceLabels
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
@ -1,37 +1,36 @@
|
||||||
opam-version: "1.2"
|
opam-version: "1.2"
|
||||||
name: "sequence"
|
name: "sequence"
|
||||||
version: "0.11"
|
version: "1.0"
|
||||||
author: "Simon Cruanes"
|
author: "Simon Cruanes"
|
||||||
maintainer: "simon.cruanes.2007@m4x.org"
|
maintainer: "simon.cruanes.2007@m4x.org"
|
||||||
license: "BSD-2-clauses"
|
license: "BSD-2-clauses"
|
||||||
build: [
|
build: [
|
||||||
["./configure" "--disable-docs"
|
|
||||||
"--%{delimcc:enable}%-invert"
|
|
||||||
"--%{base-bigarray:enable}%-bigarray"
|
|
||||||
"--prefix" "%{prefix}%"
|
|
||||||
]
|
|
||||||
[make "build"]
|
[make "build"]
|
||||||
]
|
]
|
||||||
|
install: ["jbuilder" "install"]
|
||||||
build-doc: [
|
build-doc: [
|
||||||
["./configure" "--enable-docs"]
|
|
||||||
[make "doc"]
|
[make "doc"]
|
||||||
]
|
]
|
||||||
build-test: [
|
build-test: [
|
||||||
["./configure" "--enable-tests"]
|
|
||||||
[make "test"]
|
[make "test"]
|
||||||
]
|
]
|
||||||
install: [make "install"]
|
|
||||||
remove: [
|
remove: [
|
||||||
["ocamlfind" "remove" "sequence"]
|
["ocamlfind" "remove" "sequence"]
|
||||||
]
|
]
|
||||||
depends: [
|
depends: [
|
||||||
"ocamlfind"
|
"ocamlfind"
|
||||||
"base-bytes"
|
"base-bytes"
|
||||||
"ocamlbuild" {build}
|
"result"
|
||||||
|
"jbuilder" {build}
|
||||||
|
"qcheck" {test}
|
||||||
|
"qtest" {test}
|
||||||
|
"ocaml-version" { >= "4.02" }
|
||||||
]
|
]
|
||||||
tags: [ "sequence" "iterator" "iter" "fold" ]
|
tags: [ "sequence" "iterator" "iter" "fold" ]
|
||||||
homepage: "https://github.com/c-cube/sequence/"
|
homepage: "https://github.com/c-cube/sequence/"
|
||||||
depopts: ["delimcc" "base-bigarray"]
|
depopts: [
|
||||||
|
"base-bigarray"
|
||||||
|
]
|
||||||
doc: "http://cedeela.fr/~simon/software/sequence/Sequence.html"
|
doc: "http://cedeela.fr/~simon/software/sequence/Sequence.html"
|
||||||
bug-reports: "https://github.com/c-cube/sequence/issues"
|
bug-reports: "https://github.com/c-cube/sequence/issues"
|
||||||
dev-repo: "https://github.com/c-cube/sequence.git"
|
dev-repo: "https://github.com/c-cube/sequence.git"
|
||||||
33
src/META
33
src/META
|
|
@ -1,33 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: 0035cfa1879430f352e735e279af06d0)
|
|
||||||
version = "0.11"
|
|
||||||
description = "Simple sequence (iterator) datatype and combinators"
|
|
||||||
requires = "bytes"
|
|
||||||
archive(byte) = "sequence.cma"
|
|
||||||
archive(byte, plugin) = "sequence.cma"
|
|
||||||
archive(native) = "sequence.cmxa"
|
|
||||||
archive(native, plugin) = "sequence.cmxs"
|
|
||||||
exists_if = "sequence.cma"
|
|
||||||
package "invert" (
|
|
||||||
version = "0.11"
|
|
||||||
description = "Simple sequence (iterator) datatype and combinators"
|
|
||||||
requires = "sequence delimcc"
|
|
||||||
archive(byte) = "invert.cma"
|
|
||||||
archive(byte, plugin) = "invert.cma"
|
|
||||||
archive(native) = "invert.cmxa"
|
|
||||||
archive(native, plugin) = "invert.cmxs"
|
|
||||||
exists_if = "invert.cma"
|
|
||||||
)
|
|
||||||
|
|
||||||
package "bigarray" (
|
|
||||||
version = "0.11"
|
|
||||||
description = "Simple sequence (iterator) datatype and combinators"
|
|
||||||
requires = "sequence bigarray"
|
|
||||||
archive(byte) = "bigarray.cma"
|
|
||||||
archive(byte, plugin) = "bigarray.cma"
|
|
||||||
archive(native) = "bigarray.cmxa"
|
|
||||||
archive(native, plugin) = "bigarray.cmxs"
|
|
||||||
exists_if = "bigarray.cma"
|
|
||||||
)
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
||||||
|
|
@ -8,9 +8,6 @@ type 'a t = ('a -> unit) -> unit
|
||||||
|
|
||||||
type 'a sequence = 'a t
|
type 'a sequence = 'a t
|
||||||
|
|
||||||
type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
|
|
||||||
(** Sequence of pairs of values of type ['a] and ['b]. *)
|
|
||||||
|
|
||||||
(*$inject
|
(*$inject
|
||||||
let pp_ilist = Q.Print.(list int)
|
let pp_ilist = Q.Print.(list int)
|
||||||
*)
|
*)
|
||||||
|
|
@ -210,6 +207,17 @@ let filter_mapi f seq k =
|
||||||
| None -> ()
|
| None -> ()
|
||||||
| Some y -> k y)
|
| Some y -> k y)
|
||||||
|
|
||||||
|
let filter_count f seq =
|
||||||
|
let i = ref 0 in
|
||||||
|
seq (fun x -> if f x then incr i);
|
||||||
|
!i
|
||||||
|
|
||||||
|
(*$Q
|
||||||
|
Q.(list int) (fun l -> \
|
||||||
|
let seq = of_list l and f x = x mod 2 = 0 in \
|
||||||
|
filter_count f seq = (filter f seq |> length))
|
||||||
|
*)
|
||||||
|
|
||||||
let intersperse elem seq k =
|
let intersperse elem seq k =
|
||||||
let first = ref true in
|
let first = ref true in
|
||||||
seq (fun x -> (if !first then first := false else k elem); k x)
|
seq (fun x -> (if !first then first := false else k elem); k x)
|
||||||
|
|
@ -222,6 +230,24 @@ let intersperse elem seq k =
|
||||||
|> OUnit.assert_equal [1;0;2;0;3;0;4;0;5;0]
|
|> OUnit.assert_equal [1;0;2;0;3;0;4;0;5;0]
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
let keep_some seq k =
|
||||||
|
seq
|
||||||
|
(function
|
||||||
|
| Some x -> k x
|
||||||
|
| None -> ())
|
||||||
|
|
||||||
|
let keep_ok seq k =
|
||||||
|
seq
|
||||||
|
(function
|
||||||
|
| Result.Ok x -> k x
|
||||||
|
| Result.Error _ -> ())
|
||||||
|
|
||||||
|
let keep_error seq k =
|
||||||
|
seq
|
||||||
|
(function
|
||||||
|
| Result.Error x -> k x
|
||||||
|
| Result.Ok _ -> ())
|
||||||
|
|
||||||
(** Mutable unrolled list to serve as intermediate storage *)
|
(** Mutable unrolled list to serve as intermediate storage *)
|
||||||
module MList = struct
|
module MList = struct
|
||||||
type 'a node =
|
type 'a node =
|
||||||
|
|
@ -515,9 +541,6 @@ let product outer inner k =
|
||||||
"c",0; "c", 1; "c", 2;] s
|
"c",0; "c", 1; "c", 2;] s
|
||||||
*)
|
*)
|
||||||
|
|
||||||
let product2 outer inner k =
|
|
||||||
outer (fun x -> inner (fun y -> k x y))
|
|
||||||
|
|
||||||
let rec diagonal_l l yield = match l with
|
let rec diagonal_l l yield = match l with
|
||||||
| [] -> ()
|
| [] -> ()
|
||||||
| x::tail ->
|
| x::tail ->
|
||||||
|
|
@ -946,36 +969,21 @@ let is_empty seq =
|
||||||
|
|
||||||
(** {2 Transform a sequence} *)
|
(** {2 Transform a sequence} *)
|
||||||
|
|
||||||
let empty2 _ = ()
|
|
||||||
|
|
||||||
let is_empty2 seq2 =
|
|
||||||
try ignore (seq2 (fun _ _ -> raise ExitIsEmpty)); true
|
|
||||||
with ExitIsEmpty -> false
|
|
||||||
|
|
||||||
let length2 seq2 =
|
|
||||||
let r = ref 0 in
|
|
||||||
seq2 (fun _ _ -> incr r);
|
|
||||||
!r
|
|
||||||
|
|
||||||
let zip seq2 k = seq2 (fun x y -> k (x,y))
|
|
||||||
|
|
||||||
let unzip seq k = seq (fun (x,y) -> k x y)
|
|
||||||
|
|
||||||
let zip_i seq k =
|
let zip_i seq k =
|
||||||
let r = ref 0 in
|
let r = ref 0 in
|
||||||
seq (fun x -> let n = !r in incr r; k n x)
|
seq (fun x -> let n = !r in incr r; k (n, x))
|
||||||
|
|
||||||
let fold2 f acc seq2 =
|
let fold2 f acc seq2 =
|
||||||
let acc = ref acc in
|
let acc = ref acc in
|
||||||
seq2 (fun x y -> acc := f !acc x y);
|
seq2 (fun (x,y) -> acc := f !acc x y);
|
||||||
!acc
|
!acc
|
||||||
|
|
||||||
let iter2 f seq2 = seq2 f
|
let iter2 f seq2 = seq2 (fun (x,y) -> f x y)
|
||||||
|
|
||||||
let map2 f seq2 k = seq2 (fun x y -> k (f x y))
|
let map2 f seq2 k = seq2 (fun (x,y) -> k (f x y))
|
||||||
|
|
||||||
let map2_2 f g seq2 k =
|
let map2_2 f g seq2 k =
|
||||||
seq2 (fun x y -> k (f x y) (g x y))
|
seq2 (fun (x,y) -> k (f x y, g x y))
|
||||||
|
|
||||||
(** {2 Basic data structures converters} *)
|
(** {2 Basic data structures converters} *)
|
||||||
|
|
||||||
|
|
@ -1016,11 +1024,6 @@ let of_array_i a k =
|
||||||
k (i, Array.unsafe_get a i)
|
k (i, Array.unsafe_get a i)
|
||||||
done
|
done
|
||||||
|
|
||||||
let of_array2 a k =
|
|
||||||
for i = 0 to Array.length a - 1 do
|
|
||||||
k i (Array.unsafe_get a i)
|
|
||||||
done
|
|
||||||
|
|
||||||
let array_slice a i j k =
|
let array_slice a i j k =
|
||||||
assert (i >= 0 && j < Array.length a);
|
assert (i >= 0 && j < Array.length a);
|
||||||
for idx = i to j do
|
for idx = i to j do
|
||||||
|
|
@ -1047,7 +1050,7 @@ let hashtbl_add h seq =
|
||||||
(*$R
|
(*$R
|
||||||
let h = (1 -- 5)
|
let h = (1 -- 5)
|
||||||
|> zip_i
|
|> zip_i
|
||||||
|> to_hashtbl2 in
|
|> to_hashtbl in
|
||||||
(0 -- 4)
|
(0 -- 4)
|
||||||
|> iter (fun i -> OUnit.assert_equal (i+1) (Hashtbl.find h i));
|
|> iter (fun i -> OUnit.assert_equal (i+1) (Hashtbl.find h i));
|
||||||
OUnit.assert_equal [0;1;2;3;4] (hashtbl_keys h |> sort ?cmp:None |> to_list);
|
OUnit.assert_equal [0;1;2;3;4] (hashtbl_keys h |> sort ?cmp:None |> to_list);
|
||||||
|
|
@ -1061,15 +1064,8 @@ let to_hashtbl seq =
|
||||||
hashtbl_replace h seq;
|
hashtbl_replace h seq;
|
||||||
h
|
h
|
||||||
|
|
||||||
let to_hashtbl2 seq2 =
|
|
||||||
let h = Hashtbl.create 3 in
|
|
||||||
seq2 (fun k v -> Hashtbl.replace h k v);
|
|
||||||
h
|
|
||||||
|
|
||||||
let of_hashtbl h k = Hashtbl.iter (fun a b -> k (a, b)) h
|
let of_hashtbl h k = Hashtbl.iter (fun a b -> k (a, b)) h
|
||||||
|
|
||||||
let of_hashtbl2 h k = Hashtbl.iter k h
|
|
||||||
|
|
||||||
let hashtbl_keys h k = Hashtbl.iter (fun a _ -> k a) h
|
let hashtbl_keys h k = Hashtbl.iter (fun a _ -> k a) h
|
||||||
|
|
||||||
let hashtbl_values h k = Hashtbl.iter (fun _ b -> k b) h
|
let hashtbl_values h k = Hashtbl.iter (fun _ b -> k b) h
|
||||||
|
|
@ -1106,8 +1102,9 @@ let to_buffer seq buf =
|
||||||
|
|
||||||
(*$R
|
(*$R
|
||||||
let b = Buffer.create 4 in
|
let b = Buffer.create 4 in
|
||||||
|
let upp = function 'a'..'z' as c -> Char.chr (Char.code c - Char.code 'a' + Char.code 'A') | c -> c in
|
||||||
"hello world"
|
"hello world"
|
||||||
|> of_str |> rev |> map Char.uppercase_ascii
|
|> of_str |> rev |> map upp
|
||||||
|> (fun seq -> to_buffer seq b);
|
|> (fun seq -> to_buffer seq b);
|
||||||
OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b);
|
OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b);
|
||||||
*)
|
*)
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ type +'a t = ('a -> unit) -> unit
|
||||||
|
|
||||||
type +'a sequence = 'a t
|
type +'a sequence = 'a t
|
||||||
|
|
||||||
type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
|
(** {b NOTE} Type [('a, 'b) t2 = ('a -> 'b -> unit) -> unit]
|
||||||
(** Sequence of pairs of values of type ['a] and ['b]. *)
|
has been removed and subsumed by [('a * 'b) t] @since 1.0 *)
|
||||||
|
|
||||||
type 'a equal = 'a -> 'a -> bool
|
type 'a equal = 'a -> 'a -> bool
|
||||||
type 'a hash = 'a -> int
|
type 'a hash = 'a -> int
|
||||||
|
|
@ -224,9 +224,26 @@ val filter_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b t
|
||||||
(** Map with indices, and only keep non-[None] elements
|
(** Map with indices, and only keep non-[None] elements
|
||||||
@since 0.11 *)
|
@since 0.11 *)
|
||||||
|
|
||||||
|
val filter_count : ('a -> bool) -> 'a t -> int
|
||||||
|
(** Count how many elements satisfy the given predicate
|
||||||
|
@since 1.0 *)
|
||||||
|
|
||||||
val intersperse : 'a -> 'a t -> 'a t
|
val intersperse : 'a -> 'a t -> 'a t
|
||||||
(** Insert the single element between every element of the sequence *)
|
(** Insert the single element between every element of the sequence *)
|
||||||
|
|
||||||
|
val keep_some : 'a option t -> 'a t
|
||||||
|
(** [filter_some l] retains only elements of the form [Some x].
|
||||||
|
Same as [filter_map (fun x->x)]
|
||||||
|
@since 1.0 *)
|
||||||
|
|
||||||
|
val keep_ok : ('a, _) Result.result t -> 'a t
|
||||||
|
(** [keep_ok l] retains only elements of the form [Ok x].
|
||||||
|
@since 1.0 *)
|
||||||
|
|
||||||
|
val keep_error : (_, 'e) Result.result t -> 'e t
|
||||||
|
(** [keep_error l] retains only elements of the form [Error x].
|
||||||
|
@since 1.0 *)
|
||||||
|
|
||||||
(** {2 Caching} *)
|
(** {2 Caching} *)
|
||||||
|
|
||||||
val persistent : 'a t -> 'a t
|
val persistent : 'a t -> 'a t
|
||||||
|
|
@ -299,10 +316,6 @@ val diagonal : 'a t -> ('a * 'a) t
|
||||||
Iterates only once on the sequence, which must be finite.
|
Iterates only once on the sequence, which must be finite.
|
||||||
@since 0.9 *)
|
@since 0.9 *)
|
||||||
|
|
||||||
val product2 : 'a t -> 'b t -> ('a, 'b) t2
|
|
||||||
(** Binary version of {!product}. Same requirements.
|
|
||||||
@since 0.5 *)
|
|
||||||
|
|
||||||
val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
|
val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
|
||||||
(** [join ~join_row a b] combines every element of [a] with every
|
(** [join ~join_row a b] combines every element of [a] with every
|
||||||
element of [b] using [join_row]. If [join_row] returns None, then
|
element of [b] using [join_row]. If [join_row] returns None, then
|
||||||
|
|
@ -470,28 +483,17 @@ val rev : 'a t -> 'a t
|
||||||
sequence to be finite. The result is persistent and does
|
sequence to be finite. The result is persistent and does
|
||||||
not depend on the input being repeatable. *)
|
not depend on the input being repeatable. *)
|
||||||
|
|
||||||
(** {2 Binary sequences} *)
|
val zip_i : 'a t -> (int * 'a) t
|
||||||
|
(** Zip elements of the sequence with their index in the sequence.
|
||||||
|
Changed type @since 1.0 to just give a sequence of pairs *)
|
||||||
|
|
||||||
val empty2 : ('a, 'b) t2
|
val fold2 : ('c -> 'a -> 'b -> 'c) -> 'c -> ('a * 'b) t -> 'c
|
||||||
|
|
||||||
val is_empty2 : (_, _) t2 -> bool
|
val iter2 : ('a -> 'b -> unit) -> ('a * 'b) t -> unit
|
||||||
|
|
||||||
val length2 : (_, _) t2 -> int
|
val map2 : ('a -> 'b -> 'c) -> ('a * 'b) t -> 'c t
|
||||||
|
|
||||||
val zip : ('a, 'b) t2 -> ('a * 'b) t
|
val map2_2 : ('a -> 'b -> 'c) -> ('a -> 'b -> 'd) -> ('a * 'b) t -> ('c * 'd) t
|
||||||
|
|
||||||
val unzip : ('a * 'b) t -> ('a, 'b) t2
|
|
||||||
|
|
||||||
val zip_i : 'a t -> (int, 'a) t2
|
|
||||||
(** Zip elements of the sequence with their index in the sequence *)
|
|
||||||
|
|
||||||
val fold2 : ('c -> 'a -> 'b -> 'c) -> 'c -> ('a, 'b) t2 -> 'c
|
|
||||||
|
|
||||||
val iter2 : ('a -> 'b -> unit) -> ('a, 'b) t2 -> unit
|
|
||||||
|
|
||||||
val map2 : ('a -> 'b -> 'c) -> ('a, 'b) t2 -> 'c t
|
|
||||||
|
|
||||||
val map2_2 : ('a -> 'b -> 'c) -> ('a -> 'b -> 'd) -> ('a, 'b) t2 -> ('c, 'd) t2
|
|
||||||
(** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *)
|
(** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *)
|
||||||
|
|
||||||
(** {2 Basic data structures converters} *)
|
(** {2 Basic data structures converters} *)
|
||||||
|
|
@ -528,8 +530,6 @@ val of_array : 'a array -> 'a t
|
||||||
val of_array_i : 'a array -> (int * 'a) t
|
val of_array_i : 'a array -> (int * 'a) t
|
||||||
(** Elements of the array, with their index *)
|
(** Elements of the array, with their index *)
|
||||||
|
|
||||||
val of_array2 : 'a array -> (int, 'a) t2
|
|
||||||
|
|
||||||
val array_slice : 'a array -> int -> int -> 'a t
|
val array_slice : 'a array -> int -> int -> 'a t
|
||||||
(** [array_slice a i j] Sequence of elements whose indexes range
|
(** [array_slice a i j] Sequence of elements whose indexes range
|
||||||
from [i] to [j] *)
|
from [i] to [j] *)
|
||||||
|
|
@ -567,15 +567,9 @@ val hashtbl_replace : ('a, 'b) Hashtbl.t -> ('a * 'b) t -> unit
|
||||||
val to_hashtbl : ('a * 'b) t -> ('a, 'b) Hashtbl.t
|
val to_hashtbl : ('a * 'b) t -> ('a, 'b) Hashtbl.t
|
||||||
(** Build a hashtable from a sequence of key/value pairs *)
|
(** Build a hashtable from a sequence of key/value pairs *)
|
||||||
|
|
||||||
val to_hashtbl2 : ('a, 'b) t2 -> ('a, 'b) Hashtbl.t
|
|
||||||
(** Build a hashtable from a sequence of key/value pairs *)
|
|
||||||
|
|
||||||
val of_hashtbl : ('a, 'b) Hashtbl.t -> ('a * 'b) t
|
val of_hashtbl : ('a, 'b) Hashtbl.t -> ('a * 'b) t
|
||||||
(** Sequence of key/value pairs from the hashtable *)
|
(** Sequence of key/value pairs from the hashtable *)
|
||||||
|
|
||||||
val of_hashtbl2 : ('a, 'b) Hashtbl.t -> ('a, 'b) t2
|
|
||||||
(** Sequence of key/value pairs from the hashtable *)
|
|
||||||
|
|
||||||
val hashtbl_keys : ('a, 'b) Hashtbl.t -> 'a t
|
val hashtbl_keys : ('a, 'b) Hashtbl.t -> 'a t
|
||||||
val hashtbl_values : ('a, 'b) Hashtbl.t -> 'b t
|
val hashtbl_values : ('a, 'b) Hashtbl.t -> 'b t
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ type +'a t = ('a -> unit) -> unit
|
||||||
|
|
||||||
type +'a sequence = 'a t
|
type +'a sequence = 'a t
|
||||||
|
|
||||||
type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
|
(** {b NOTE} Type [('a, 'b) t2 = ('a -> 'b -> unit) -> unit]
|
||||||
(** Sequence of pairs of values of type ['a] and ['b]. *)
|
has been removed and subsumed by [('a * 'b) t] @since 1.0 *)
|
||||||
|
|
||||||
type 'a equal = 'a -> 'a -> bool
|
type 'a equal = 'a -> 'a -> bool
|
||||||
type 'a hash = 'a -> int
|
type 'a hash = 'a -> int
|
||||||
|
|
@ -197,9 +197,26 @@ val seq_list_map : f:('a -> 'b t) -> 'a list -> 'b list t
|
||||||
then calls {!seq_list}
|
then calls {!seq_list}
|
||||||
@since 0.11 *)
|
@since 0.11 *)
|
||||||
|
|
||||||
|
val filter_count : f:('a -> bool) -> 'a t -> int
|
||||||
|
(** Count how many elements satisfy the given predicate
|
||||||
|
@since 1.0 *)
|
||||||
|
|
||||||
val intersperse : x:'a -> 'a t -> 'a t
|
val intersperse : x:'a -> 'a t -> 'a t
|
||||||
(** Insert the single element between every element of the sequence *)
|
(** Insert the single element between every element of the sequence *)
|
||||||
|
|
||||||
|
val keep_some : 'a option t -> 'a t
|
||||||
|
(** [filter_some l] retains only elements of the form [Some x].
|
||||||
|
Same as [filter_map (fun x->x)]
|
||||||
|
@since 1.0 *)
|
||||||
|
|
||||||
|
val keep_ok : ('a, _) Result.result t -> 'a t
|
||||||
|
(** [keep_ok l] retains only elements of the form [Ok x].
|
||||||
|
@since 1.0 *)
|
||||||
|
|
||||||
|
val keep_error : (_, 'e) Result.result t -> 'e t
|
||||||
|
(** [keep_error l] retains only elements of the form [Error x].
|
||||||
|
@since 1.0 *)
|
||||||
|
|
||||||
(** {2 Caching} *)
|
(** {2 Caching} *)
|
||||||
|
|
||||||
val persistent : 'a t -> 'a t
|
val persistent : 'a t -> 'a t
|
||||||
|
|
@ -271,10 +288,6 @@ val diagonal : 'a t -> ('a * 'a) t
|
||||||
Iterates only once on the sequence, which must be finite.
|
Iterates only once on the sequence, which must be finite.
|
||||||
@since 0.9 *)
|
@since 0.9 *)
|
||||||
|
|
||||||
val product2 : 'a t -> 'b t -> ('a, 'b) t2
|
|
||||||
(** Binary version of {!product}. Same requirements.
|
|
||||||
@since 0.5 *)
|
|
||||||
|
|
||||||
val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
|
val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
|
||||||
(** [join ~join_row a b] combines every element of [a] with every
|
(** [join ~join_row a b] combines every element of [a] with every
|
||||||
element of [b] using [join_row]. If [join_row] returns None, then
|
element of [b] using [join_row]. If [join_row] returns None, then
|
||||||
|
|
@ -442,28 +455,17 @@ val rev : 'a t -> 'a t
|
||||||
sequence to be finite. The result is persistent and does
|
sequence to be finite. The result is persistent and does
|
||||||
not depend on the input being repeatable. *)
|
not depend on the input being repeatable. *)
|
||||||
|
|
||||||
(** {2 Binary sequences} *)
|
val zip_i : 'a t -> (int * 'a) t
|
||||||
|
(** Zip elements of the sequence with their index in the sequence.
|
||||||
|
Changed type @since 1.0 to just give a sequence of pairs *)
|
||||||
|
|
||||||
val empty2 : ('a, 'b) t2
|
val fold2 : f:('c -> 'a -> 'b -> 'c) -> init:'c -> ('a * 'b) t -> 'c
|
||||||
|
|
||||||
val is_empty2 : (_, _) t2 -> bool
|
val iter2 : f:('a -> 'b -> unit) -> ('a * 'b) t -> unit
|
||||||
|
|
||||||
val length2 : (_, _) t2 -> int
|
val map2 : f:('a -> 'b -> 'c) -> ('a * 'b) t -> 'c t
|
||||||
|
|
||||||
val zip : ('a, 'b) t2 -> ('a * 'b) t
|
val map2_2 : f:('a -> 'b -> 'c) -> ('a -> 'b -> 'd) -> ('a * 'b) t -> ('c * 'd) t
|
||||||
|
|
||||||
val unzip : ('a * 'b) t -> ('a, 'b) t2
|
|
||||||
|
|
||||||
val zip_i : 'a t -> (int, 'a) t2
|
|
||||||
(** Zip elements of the sequence with their index in the sequence *)
|
|
||||||
|
|
||||||
val fold2 : f:('c -> 'a -> 'b -> 'c) -> init:'c -> ('a, 'b) t2 -> 'c
|
|
||||||
|
|
||||||
val iter2 : f:('a -> 'b -> unit) -> ('a, 'b) t2 -> unit
|
|
||||||
|
|
||||||
val map2 : f:('a -> 'b -> 'c) -> ('a, 'b) t2 -> 'c t
|
|
||||||
|
|
||||||
val map2_2 : ('a -> 'b -> 'c) -> ('a -> 'b -> 'd) -> ('a, 'b) t2 -> ('c, 'd) t2
|
|
||||||
(** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *)
|
(** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *)
|
||||||
|
|
||||||
(** {2 Basic data structures converters} *)
|
(** {2 Basic data structures converters} *)
|
||||||
|
|
@ -500,8 +502,6 @@ val of_array : 'a array -> 'a t
|
||||||
val of_array_i : 'a array -> (int * 'a) t
|
val of_array_i : 'a array -> (int * 'a) t
|
||||||
(** Elements of the array, with their index *)
|
(** Elements of the array, with their index *)
|
||||||
|
|
||||||
val of_array2 : 'a array -> (int, 'a) t2
|
|
||||||
|
|
||||||
val array_slice : 'a array -> int -> int -> 'a t
|
val array_slice : 'a array -> int -> int -> 'a t
|
||||||
(** [array_slice a i j] Sequence of elements whose indexes range
|
(** [array_slice a i j] Sequence of elements whose indexes range
|
||||||
from [i] to [j] *)
|
from [i] to [j] *)
|
||||||
|
|
@ -539,15 +539,9 @@ val hashtbl_replace : ('a, 'b) Hashtbl.t -> ('a * 'b) t -> unit
|
||||||
val to_hashtbl : ('a * 'b) t -> ('a, 'b) Hashtbl.t
|
val to_hashtbl : ('a * 'b) t -> ('a, 'b) Hashtbl.t
|
||||||
(** Build a hashtable from a sequence of key/value pairs *)
|
(** Build a hashtable from a sequence of key/value pairs *)
|
||||||
|
|
||||||
val to_hashtbl2 : ('a, 'b) t2 -> ('a, 'b) Hashtbl.t
|
|
||||||
(** Build a hashtable from a sequence of key/value pairs *)
|
|
||||||
|
|
||||||
val of_hashtbl : ('a, 'b) Hashtbl.t -> ('a * 'b) t
|
val of_hashtbl : ('a, 'b) Hashtbl.t -> ('a * 'b) t
|
||||||
(** Sequence of key/value pairs from the hashtable *)
|
(** Sequence of key/value pairs from the hashtable *)
|
||||||
|
|
||||||
val of_hashtbl2 : ('a, 'b) Hashtbl.t -> ('a, 'b) t2
|
|
||||||
(** Sequence of key/value pairs from the hashtable *)
|
|
||||||
|
|
||||||
val hashtbl_keys : ('a, 'b) Hashtbl.t -> 'a t
|
val hashtbl_keys : ('a, 'b) Hashtbl.t -> 'a t
|
||||||
val hashtbl_values : ('a, 'b) Hashtbl.t -> 'b t
|
val hashtbl_values : ('a, 'b) Hashtbl.t -> 'b t
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: dca476c3b57e859aa3b1c75ec0959ed9)
|
|
||||||
SequenceBigarray
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: dca476c3b57e859aa3b1c75ec0959ed9)
|
|
||||||
SequenceBigarray
|
|
||||||
# OASIS_STOP
|
|
||||||
11
src/bigarray/jbuild
Normal file
11
src/bigarray/jbuild
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
(library
|
||||||
|
((name sequence_bigarray)
|
||||||
|
(public_name sequence.bigarray)
|
||||||
|
(libraries (sequence bigarray))
|
||||||
|
(wrapped false)
|
||||||
|
(optional)
|
||||||
|
(flags (:standard -w +a-4-42-44-48-50-58-32-60@8 -w -33 -safe-string -color always))
|
||||||
|
(ocamlopt_flags (:standard -O3 -color always
|
||||||
|
-unbox-closures -unbox-closures-factor 20))
|
||||||
|
))
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
REC
|
|
||||||
PKG delimcc
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
(*
|
|
||||||
Copyright (c) 2014, Simon Cruanes
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer. Redistributions in binary
|
|
||||||
form must reproduce the above copyright notice, this list of conditions and the
|
|
||||||
following disclaimer in the documentation and/or other materials provided with
|
|
||||||
the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*)
|
|
||||||
|
|
||||||
(** {1 Interface to Delimcc (Invert control flow)} *)
|
|
||||||
|
|
||||||
type 'a gen = unit -> 'a option
|
|
||||||
|
|
||||||
type 'a res =
|
|
||||||
| Start
|
|
||||||
| Yield of 'a
|
|
||||||
| Stop
|
|
||||||
|
|
||||||
let _ret_none () = None
|
|
||||||
let _ret_unit () = ()
|
|
||||||
|
|
||||||
let to_gen seq =
|
|
||||||
let p = Delimcc.new_prompt () in
|
|
||||||
let _next = ref None in
|
|
||||||
ignore (Delimcc.push_prompt p
|
|
||||||
(fun () ->
|
|
||||||
Delimcc.take_subcont p (fun c () -> _next := Some c; Start);
|
|
||||||
seq
|
|
||||||
(fun x ->
|
|
||||||
Delimcc.take_subcont p (fun c () -> _next := Some c; Yield x)
|
|
||||||
);
|
|
||||||
_next := None;
|
|
||||||
Stop
|
|
||||||
));
|
|
||||||
(* call next subcont *)
|
|
||||||
let rec next () =
|
|
||||||
match !_next with
|
|
||||||
| None -> None
|
|
||||||
| Some f ->
|
|
||||||
begin match Delimcc.push_delim_subcont f _ret_unit with
|
|
||||||
| Start -> next ()
|
|
||||||
| Yield x -> Some x
|
|
||||||
| Stop -> None
|
|
||||||
end
|
|
||||||
in
|
|
||||||
next
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
(*
|
|
||||||
Copyright (c) 2014, Simon Cruanes
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer. Redistributions in binary
|
|
||||||
form must reproduce the above copyright notice, this list of conditions and the
|
|
||||||
following disclaimer in the documentation and/or other materials provided with
|
|
||||||
the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*)
|
|
||||||
|
|
||||||
(** {1 Interface to Delimcc (Invert control flow)} *)
|
|
||||||
|
|
||||||
type 'a gen = unit -> 'a option
|
|
||||||
|
|
||||||
val to_gen : 'a Sequence.t -> 'a gen
|
|
||||||
(** Use delimited continuations to iterate on the sequence step by step.
|
|
||||||
Relatively costly but still useful *)
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: d74492d261fcc87665b60e0331c04236)
|
|
||||||
SequenceInvert
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: d74492d261fcc87665b60e0331c04236)
|
|
||||||
SequenceInvert
|
|
||||||
# OASIS_STOP
|
|
||||||
11
src/jbuild
Normal file
11
src/jbuild
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
(library
|
||||||
|
((name sequence)
|
||||||
|
(public_name sequence)
|
||||||
|
(wrapped false)
|
||||||
|
(flags (:standard -w +a-4-42-44-48-50-58-32-60@8 -safe-string -color always -nolabels))
|
||||||
|
(ocamlopt_flags (:standard -O3 -color always
|
||||||
|
-unbox-closures -unbox-closures-factor 20))
|
||||||
|
(libraries (bytes result))
|
||||||
|
))
|
||||||
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: 8c0ffebbdb3e063d4b3e5cc00517b199)
|
|
||||||
Sequence
|
|
||||||
SequenceLabels
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: 8c0ffebbdb3e063d4b3e5cc00517b199)
|
|
||||||
Sequence
|
|
||||||
SequenceLabels
|
|
||||||
# OASIS_STOP
|
|
||||||
Loading…
Add table
Reference in a new issue