10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-12-23 04:43:32 +01:00
QCaml/common/range.org

98 lines
2.3 KiB
Org Mode

#+begin_src elisp tangle: no :results none :exports none
(setq pwd (file-name-directory buffer-file-name))
(setq name (file-name-nondirectory (substring buffer-file-name 0 -4)))
(setq lib (concat pwd "lib/"))
(setq testdir (concat pwd "test/"))
(setq mli (concat lib name ".mli"))
(setq ml (concat lib name ".ml"))
(setq test-ml (concat testdir name ".ml"))
(org-babel-tangle)
#+end_src
* Range
:PROPERTIES:
:header-args: :noweb yes :comments both
:END:
A range is a sorted list of integers in an interval.
- ~"[a-b]"~ : range between a and b (included)
- ~"[a]"~ : the list with only one integer a
- ~"a"~ : equivalent to "[a]"
- ~"[36-53,72-107,126-131]"~ represents the list of integers
[ 37 ; 37 ; 38 ; ... ; 52 ; 53 ; 72 ; 73 ; ... ; 106 ; 107 ; 126 ; 127 ; ... ; 130 ; 131 ].
** Type
<<<~Range.t~>>>
#+begin_src ocaml :tangle (eval mli)
type t
#+end_src
#+begin_src ocaml :tangle (eval ml) :exports none
type t = int list
#+end_src
** Conversion
#+begin_src ocaml :tangle (eval mli)
val of_string : string -> t
val to_string : t -> string
val to_int_list : t -> int list
#+end_src
#+begin_src ocaml :tangle (eval ml) :exports none
let to_int_list r = r
let expand_range r =
match String.split_on_char '-' r with
| s :: f :: [] ->
begin
let start = int_of_string s
and finish = int_of_string f
in
assert (start <= finish) ;
let rec do_work = function
| i when i=finish -> [ i ]
| i -> i::(do_work (i+1))
in do_work start
end
| r :: [] -> [int_of_string r]
| [] -> []
| _ -> invalid_arg "Only one range expected"
let of_string s =
match s.[0] with
| '0' .. '9' -> [ int_of_string s ]
| _ ->
assert (s.[0] = '[') ;
assert (s.[(String.length s)-1] = ']') ;
let s = String.sub s 1 ((String.length s) - 2) in
let l = String.split_on_char ',' s in
let l = List.map expand_range l in
List.concat l
|> List.sort_uniq compare
let to_string l =
"[" ^
(List.map string_of_int l
|> String.concat ",") ^
"]"
#+end_src
** Printers
#+begin_src ocaml :tangle (eval mli)
val pp : Format.formatter -> t -> unit
#+end_src
#+begin_src ocaml :tangle (eval ml) :exports none
let pp ppf t =
Format.fprintf ppf "@[%s@]" (to_string t)
#+end_src