diff options
-rw-r--r-- | src/cell.ml | 63 | ||||
-rw-r--r-- | src/dataType.ml | 104 | ||||
-rw-r--r-- | src/expression.ml | 104 | ||||
-rw-r--r-- | src/functions.ml | 276 | ||||
-rw-r--r-- | src/tools.ml | 223 | ||||
-rw-r--r-- | src/tree/pageMap.ml | 165 |
6 files changed, 386 insertions, 549 deletions
diff --git a/src/cell.ml b/src/cell.ml index dc5dcdc..9e28f2d 100644 --- a/src/cell.ml +++ b/src/cell.ml @@ -20,31 +20,27 @@ type t = (int * int) * (bool * bool) let u = UTF8.from_utf8string
let from_string (fixed_x, x_name) (fixed_y, y) =
-
let x = ref 0 in
- String.iter (function
- | 'a'..'z' as c -> x:= (!x * 26) + ((int_of_char c) - 96)
- | 'A'..'Z' as c -> x:= (!x * 26) + ((int_of_char c) - 64)
- | _ -> ()
- ) x_name;
- (!x, y), (fixed_x, fixed_y)
-
-let to_hname x = begin
+ String.iter
+ (function
+ | 'a' .. 'z' as c -> x := (!x * 26) + (int_of_char c - 96)
+ | 'A' .. 'Z' as c -> x := (!x * 26) + (int_of_char c - 64)
+ | _ -> ())
+ x_name;
+ ((!x, y), (fixed_x, fixed_y))
+
+let to_hname x =
let rec extract acc value =
- if value > 0 then (
+ if value > 0 then
let value' = value - 1 in
let rem = value' mod 26 in
- let quot = (value' - rem) / 26
- in (extract[@tailcall]) ((char_of_int (65 + rem))::acc) quot
- ) else (
- acc
- )
+ let quot = (value' - rem) / 26 in
+ (extract [@tailcall]) (char_of_int (65 + rem) :: acc) quot
+ else acc
in
- let res = extract [] x
- and buff = UTF8.Buffer.create 4 in
+ let res = extract [] x and buff = UTF8.Buffer.create 4 in
List.iter (fun c -> UTF8.Buffer.add_char buff c) res;
UTF8.Buffer.contents buff
-end
let to_string ((x, y), (fixed_x, fixed_y)) =
let buff = UTF8.Buffer.create 2 in
@@ -55,33 +51,34 @@ let to_string ((x, y), (fixed_x, fixed_y)) = UTF8.Buffer.add_string buff @@ u @@ string_of_int y;
UTF8.Buffer.contents buff
-let to_buffer buff ((x, y), (fixed_x, fixed_y)) = begin
+let to_buffer buff ((x, y), (fixed_x, fixed_y)) =
if fixed_x then UTF8.Buffer.add_char buff '$';
UTF8.Buffer.add_string buff (to_hname x);
if fixed_y then UTF8.Buffer.add_char buff '$';
UTF8.Buffer.add_string buff @@ u @@ string_of_int y
-end
let to_string t =
let buff = UTF8.Buffer.create 2 in
to_buffer buff t;
UTF8.Buffer.contents buff
-let to_pair = Pervasives.fst
+let to_pair = Stdlib.fst
+
+module Set = struct
+ include Set.Make (struct
+ type t = int * int
-module Set = (struct
- include Set.Make(struct
- type t = (int * int)
- let compare = Pervasives.compare
+ let compare = Stdlib.compare
end)
- let show_int_tuple b t = Tools.Tuple2.printb
- (fun b x -> UTF8.Buffer.add_string b @@u(string_of_int x))
- (fun b x -> UTF8.Buffer.add_string b @@u(string_of_int x))
- b t
+ let show_int_tuple b t =
+ Tools.Tuple2.printb
+ (fun b x -> UTF8.Buffer.add_string b @@ u (string_of_int x))
+ (fun b x -> UTF8.Buffer.add_string b @@ u (string_of_int x))
+ b t
let printb buff =
- iter (fun x -> to_buffer buff (x, (false,false)); UTF8.Buffer.add_char buff ' ')
-
-end)
-
+ iter (fun x ->
+ to_buffer buff (x, (false, false));
+ UTF8.Buffer.add_char buff ' ')
+end
diff --git a/src/dataType.ml b/src/dataType.ml index abac572..8d63d48 100644 --- a/src/dataType.ml +++ b/src/dataType.ml @@ -17,126 +17,94 @@ along with licht. If not, see <http://www.gnu.org/licenses/>. module type COMPARABLE = sig
type t
- val eq: t -> t -> bool
- val neq: t -> t -> bool
- val lt: t -> t -> bool
- val le: t -> t -> bool
- val gt: t -> t -> bool
- val ge: t -> t -> bool
+
+ val eq : t -> t -> bool
+ val neq : t -> t -> bool
+ val lt : t -> t -> bool
+ val le : t -> t -> bool
+ val gt : t -> t -> bool
+ val ge : t -> t -> bool
end
module Comparable = struct
-
- let eq = (=)
- let neq = (<>)
- let lt = (<)
- let le = (<=)
- let gt = (>)
- let ge = (>=)
-
+ let eq = ( = )
+ let neq = ( <> )
+ let lt = ( < )
+ let le = ( <= )
+ let gt = ( > )
+ let ge = ( >= )
end
module Num = struct
-
let rnd () =
let value = Random.bits () in
Q.make (Z.of_int value) (Z.of_int (1 lsl 30))
include Q
- let is_integer t = (Q.den t) == Z.one
-
+ let is_integer t = Q.den t == Z.one
let eq = Q.equal
-
let neq a b = not (Q.equal a b)
-
let mult = Q.mul
let floor t =
- let num = Q.num t
- and den = Q.den t in
+ let num = Q.num t and den = Q.den t in
- if is_integer t then
- Q.of_bigint num
- else
- Q.of_bigint @@ Z.fdiv num den
+ if is_integer t then Q.of_bigint num else Q.of_bigint @@ Z.fdiv num den
let round_down t =
- let num = Q.num t
- and den = Q.den t in
+ let num = Q.num t and den = Q.den t in
- if is_integer t then
- Q.of_bigint num
- else
- Q.of_bigint @@ Z.div num den
+ if is_integer t then Q.of_bigint num else Q.of_bigint @@ Z.div num den
let round t =
- if is_integer t then
- t
+ if is_integer t then t
else
- let t' = match Q.sign t with
- | 1 -> Q.add t @@ Q.of_ints 1 2
+ let t' =
+ match Q.sign t with
+ | 1 -> Q.add t @@ Q.of_ints 1 2
| -1 -> Q.add t @@ Q.of_ints (-1) 2
- | _ -> t in
- let num = Q.num t'
- and den = Q.den t' in
+ | _ -> t
+ in
+ let num = Q.num t' and den = Q.den t' in
Q.of_bigint (Z.div num den)
let ge = Q.geq
-
let ge = Q.geq
-
let le = Q.leq
- let pow t q_factor = begin
-
+ let pow t q_factor =
if is_integer q_factor then
-
- let factor = Q.to_int q_factor
- and num = Q.num t
- and den = Q.den t in
+ let factor = Q.to_int q_factor and num = Q.num t and den = Q.den t in
Q.make (Z.pow num factor) (Z.pow den factor)
-
else
-
let factor = Q.to_float q_factor
and num = Z.to_float @@ Q.num t
and den = Z.to_float @@ Q.den t in
- Q.div
- (Q.of_float (num ** factor))
- (Q.of_float (den ** factor))
-
- end
-
- let gcd t1 t2 =
- Q.of_bigint @@ Z.gcd (Q.to_bigint t1) (Q.to_bigint t2)
-
- let lcm t1 t2 =
- Q.of_bigint @@ Z.lcm (Q.to_bigint t1) (Q.to_bigint t2)
+ Q.div (Q.of_float (num ** factor)) (Q.of_float (den ** factor))
+ let gcd t1 t2 = Q.of_bigint @@ Z.gcd (Q.to_bigint t1) (Q.to_bigint t2)
+ let lcm t1 t2 = Q.of_bigint @@ Z.lcm (Q.to_bigint t1) (Q.to_bigint t2)
end
module Bool = struct
-
type t = bool
+
include Comparable
let true_ = true
let false_ = false
-
- let or_ = (||)
- let and_ = (&&)
- let not = Pervasives.not
-
+ let or_ = ( || )
+ let and_ = ( && )
+ let not = Stdlib.not
end
module String = struct
-
type t = UTF8.t
- include Comparable
+ include Comparable
end
-module Date = Date.Make(Num)
+module Date = Date.Make (Num)
diff --git a/src/expression.ml b/src/expression.ml index c2e4ec8..3afc37b 100644 --- a/src/expression.ml +++ b/src/expression.ml @@ -20,115 +20,99 @@ module Tuple2 = Tools.Tuple2 let u = UTF8.from_utf8string
type t =
- | Basic: 'a ScTypes.Type.t -> t (** A direct type *)
- | Formula: formula -> t (** A formula *)
- | Undefined: t (** The content is not defined *)
+ | Basic : 'a ScTypes.Type.t -> t (** A direct type *)
+ | Formula : formula -> t (** A formula *)
+ | Undefined : t (** The content is not defined *)
and formula =
| Expression of ScTypes.Expr.t (** A valid expression *)
- | Error of int * UTF8.t (** When the expression cannot be parsed *)
+ | Error of int * UTF8.t (** When the expression cannot be parsed *)
+let is_defined = function Undefined -> false | _ -> true
-let is_defined = function
- | Undefined -> false
- | _ -> true
-
-let load content = begin
+let load content =
let content = UTF8.to_utf8string content in
- if String.length content > 0 then (
- if content.[0] = '=' then (
+ if String.length content > 0 then
+ if content.[0] = '=' then
(* If the string start with a '=', load it as a formula *)
- Formula (
- try
- Expression (
- Lexing.from_string content
- |> ExpressionParser.value ExpressionLexer.read)
- with _ -> Error (1, UTF8.from_utf8string content)
- )
- ) else (
+ Formula
+ (try
+ Expression
+ (Lexing.from_string content
+ |> ExpressionParser.value ExpressionLexer.read)
+ with _ -> Error (1, UTF8.from_utf8string content))
+ else
(* First try to load the data with basic types, and fallback with string *)
let content' =
try String.sub content 0 (String.index content '\000')
- with Not_found -> content in
- try
- let ScTypes.Result.Ok r =
- ExpressionParser.content ExpressionLexer.read
- @@ Lexing.from_string content' in
- Basic r
- with _ -> Basic (ScTypes.Type.string (UTF8.from_utf8string content'))
- )
- ) else (
- (* If the string in empty, build an undefined value *)
+ with Not_found -> content
+ in
+ try
+ let (ScTypes.Result.Ok r) =
+ ExpressionParser.content ExpressionLexer.read
+ @@ Lexing.from_string content'
+ in
+ Basic r
+ with _ -> Basic (ScTypes.Type.string (UTF8.from_utf8string content'))
+ else (* If the string in empty, build an undefined value *)
Undefined
- )
-end
-
let load_expr expr = expr
-module EvalExpr = ScTypes.Expr.Eval(Evaluate)
+module EvalExpr = ScTypes.Expr.Eval (Evaluate)
(** Extract the parameters to give to a function.
return an Error if one of them is an error
*)
-let eval expr catalog mapper = begin
-
- begin try match expr with
+let eval expr catalog mapper =
+ try
+ match expr with
| Basic value -> ScTypes.Result.Ok value
| Formula (Expression e) -> EvalExpr.eval e (catalog, mapper)
| Formula (Error (i, s)) -> ScTypes.Result.Error ScTypes.Error
| Undefined -> ScTypes.Result.Error Not_found
- with ex -> ScTypes.Result.Error ex
- end
+ with ex -> ScTypes.Result.Error ex
-end
+module EvalSources = ScTypes.Expr.Eval (Collect_sources)
-
-module EvalSources = ScTypes.Expr.Eval(Collect_sources)
-
-let collect_sources = begin function
+let collect_sources = function
| Formula (Expression f) -> EvalSources.eval f Cell.Set.empty
| _ -> Cell.Set.empty
-end
-module Shifter = ScTypes.Expr.Eval(Shift_expr)
-module Printer = ScTypes.Expr.Eval(Show_expr.Show_Expr(Show_ref)(Show_type))
+module Shifter = ScTypes.Expr.Eval (Shift_expr)
+module Printer = ScTypes.Expr.Eval (Show_expr.Show_Expr (Show_ref) (Show_type))
(** Inherit the default representation, but print the float with all decimals *)
-module LongPrinter = ScTypes.Type.Eval(struct
-
+module LongPrinter = ScTypes.Type.Eval (struct
include Show_type
let num n buffer =
if DataType.Num.is_integer n then
- DataType.Num.to_int n
- |> string_of_int
- |> UTF8.from_utf8string
- |> UTF8.Buffer.add_string buffer
+ DataType.Num.to_int n |> string_of_int |> UTF8.from_utf8string
+ |> UTF8.Buffer.add_string buffer
else
let f = DataType.Num.to_float n
and to_b = UTF8.Format.formatter_of_buffer buffer in
ignore @@ UTF8.Format.fprintf to_b "%f" f;
Format.pp_print_flush to_b ()
-
end)
let show e =
let buffer = UTF8.Buffer.create 16 in
- begin match e with
+ (match e with
| Formula (Expression f) ->
UTF8.Buffer.add_char buffer '=';
Printer.eval f buffer
| Basic b -> LongPrinter.eval b buffer
- | Formula (Error (i,s)) -> UTF8.Buffer.add_string buffer s
- | Undefined -> ()
- end;
+ | Formula (Error (i, s)) -> UTF8.Buffer.add_string buffer s
+ | Undefined -> ());
UTF8.Buffer.contents buffer
let shift vector = function
| Formula (Expression f) -> Formula (Expression (Shifter.eval f vector))
| other -> other
-let (=) t1 t2 = match t1, t2 with
- | Basic b1, Basic b2 -> ScTypes.Type.(=) b1 b2
- | o1, o2 -> Pervasives.(=) o1 o2
+let ( = ) t1 t2 =
+ match (t1, t2) with
+ | Basic b1, Basic b2 -> ScTypes.Type.( = ) b1 b2
+ | o1, o2 -> Stdlib.( = ) o1 o2
diff --git a/src/functions.ml b/src/functions.ml index 491d968..87cff58 100644 --- a/src/functions.ml +++ b/src/functions.ml @@ -19,59 +19,52 @@ module D = DataType module T = Tools
type _ typ =
- | Unit: unit typ
- | Bool: D.Bool.t typ
- | Num: D.Num.t typ
- | String: UTF8.t typ
- | List: 'a typ -> 'a list typ
+ | Unit : unit typ
+ | Bool : D.Bool.t typ
+ | Num : D.Num.t typ
+ | String : UTF8.t typ
+ | List : 'a typ -> 'a list typ
let t_unit = Unit
-let t_bool: DataType.Bool.t typ = Bool
-let t_int: DataType.Num.t typ = Num
-let t_string: UTF8.t typ = String
-let t_list (t: 'a typ): 'a list typ = List t
+let t_bool : DataType.Bool.t typ = Bool
+let t_int : DataType.Num.t typ = Num
+let t_string : UTF8.t typ = String
+let t_list (t : 'a typ) : 'a list typ = List t
-let typ_of_format: type a. a ScTypes.DataFormat.t -> a typ = function
+let typ_of_format : type a. a ScTypes.DataFormat.t -> a typ = function
| ScTypes.DataFormat.Date -> Num
| ScTypes.DataFormat.Number -> Num
| ScTypes.DataFormat.String -> String
| ScTypes.DataFormat.Bool -> Bool
-
-let rec repr:
-type a. Format.formatter -> a typ -> unit =
-fun printer typ -> match typ with
- | Unit -> Format.fprintf printer "Unit"
- | Bool -> Format.fprintf printer "Bool"
- | Num -> Format.fprintf printer "Num"
+let rec repr : type a. Format.formatter -> a typ -> unit =
+ fun printer typ ->
+ match typ with
+ | Unit -> Format.fprintf printer "Unit"
+ | Bool -> Format.fprintf printer "Bool"
+ | Num -> Format.fprintf printer "Num"
| String -> Format.fprintf printer "String"
- | List t -> Format.fprintf printer "List[%a]"
- (repr[@tailcall]) t
-
-module C = Catalog.Make(struct
+ | List t -> Format.fprintf printer "List[%a]" (repr [@tailcall]) t
+module C = Catalog.Make (struct
let repr = repr
- let rec compare_typ: type a b. a typ -> b typ -> (a, b) T.cmp =
- begin fun a b ->
- match a, b with
- | Unit, Unit -> T.Eq
- | Bool, Bool -> T.Eq
- | Num, Num -> T.Eq
+ let rec compare_typ : type a b. a typ -> b typ -> (a, b) T.cmp =
+ fun a b ->
+ match (a, b) with
+ | Unit, Unit -> T.Eq
+ | Bool, Bool -> T.Eq
+ | Num, Num -> T.Eq
| String, String -> T.Eq
- | List l1, List l2 ->
- begin match compare_typ l1 l2 with
+ | List l1, List l2 -> (
+ match compare_typ l1 l2 with
| T.Lt -> T.Lt
| T.Eq -> T.Eq
- | T.Gt -> T.Gt
- end
- | x, y -> if (T.Ex x) > (T.Ex y) then T.Gt else T.Lt
- end
+ | T.Gt -> T.Gt)
+ | x, y -> if T.Ex x > T.Ex y then T.Gt else T.Lt
type 'a t = 'a typ
-
type 'a returnType = 'a ScTypes.ReturnType.t
-
end)
let f_num = ScTypes.ReturnType.f_num
@@ -80,131 +73,126 @@ let f_number = ScTypes.ReturnType.f_number let f_string = ScTypes.ReturnType.f_string
let f_bool = ScTypes.ReturnType.f_bool
-module Make_Compare(Comp: D.COMPARABLE) = struct
-
- let register t catalog = begin catalog
- |> C.register2 "=" (t, t) f_bool Comp.eq
+module Make_Compare (Comp : D.COMPARABLE) = struct
+ let register t catalog =
+ catalog
+ |> C.register2 "=" (t, t) f_bool Comp.eq
|> C.register2 "<>" (t, t) f_bool Comp.neq
- |> C.register2 ">" (t, t) f_bool Comp.gt
+ |> C.register2 ">" (t, t) f_bool Comp.gt
|> C.register2 ">=" (t, t) f_bool Comp.ge
- |> C.register2 "<" (t, t) f_bool Comp.lt
+ |> C.register2 "<" (t, t) f_bool Comp.lt
|> C.register2 "<=" (t, t) f_bool Comp.le
- end
-
end
-let built_in catalog = begin
-
- let module CompareNum = Make_Compare(D.Num) in
- let module CompareString = Make_Compare(D.String) in
- let module CompareBool = Make_Compare(D.Bool) in
-
+let built_in catalog =
+ let module CompareNum = Make_Compare (D.Num) in
+ let module CompareString = Make_Compare (D.String) in
+ let module CompareBool = Make_Compare (D.Bool) in
(* Helper for list functions : reduce over a list of elements *)
- let reduce name typ res f c = begin
- C.register1 name (t_list typ) res (fun x ->
- List.fold_left f (List.hd x) x) c
- |> C.register1 name (t_list (t_list typ)) res (fun x ->
- List.fold_left (List.fold_left f) (List.hd (List.hd x)) x);
- end in
+ let reduce name typ res f c =
+ C.register1 name (t_list typ) res
+ (fun x -> List.fold_left f (List.hd x) x)
+ c
+ |> C.register1 name
+ (t_list (t_list typ))
+ res
+ (fun x -> List.fold_left (List.fold_left f) (List.hd (List.hd x)) x)
+ in
(* Helper for list functions : fold over a list of elements *)
- let fold name t_in t_out f init c = begin
- C.register1 name (t_list t_in) t_out (fun x ->
- List.fold_left f init x) c
- |> C.register1 name (t_list (t_list t_in)) t_out (fun x ->
- List.fold_left (List.fold_left f) init x)
- end in
+ let fold name t_in t_out f init c =
+ C.register1 name (t_list t_in) t_out (fun x -> List.fold_left f init x) c
+ |> C.register1 name
+ (t_list (t_list t_in))
+ t_out
+ (fun x -> List.fold_left (List.fold_left f) init x)
+ in
-
- let if_: type a. bool -> a -> a -> a = fun a b c -> if a then b else c in
+ let if_ : type a. bool -> a -> a -> a = fun a b c -> if a then b else c in
(* Build a date *)
- C.register3 "date" (t_int, t_int, t_int) f_date (
- fun year month day ->
- D.Date.get_julian_day
- (D.Num.to_int year)
- (D.Num.to_int month)
- (D.Num.to_int day)
- ) catalog
+ C.register3 "date" (t_int, t_int, t_int) f_date
+ (fun year month day ->
+ D.Date.get_julian_day (D.Num.to_int year) (D.Num.to_int month)
+ (D.Num.to_int day))
+ catalog
|> CompareNum.register t_int
-
- |> C.register1 "rand" t_unit f_number D.Num.rnd
-
- |> C.register1 "pi" t_unit f_number (fun () -> D.Num.of_float (4. *. atan 1.))
- |> C.register1 "sin" t_int f_number (fun x -> D.Num.of_float (sin (D.Num.to_float x)))
- |> C.register1 "cos" t_int f_number (fun x -> D.Num.of_float (cos (D.Num.to_float x)))
- |> C.register1 "tan" t_int f_number (fun x -> D.Num.of_float (tan (D.Num.to_float x)))
- |> C.register1 "atan" t_int f_number (fun x -> D.Num.of_float (atan (D.Num.to_float x)))
- |> C.register1 "asin" t_int f_number (fun x -> D.Num.of_float (asin (D.Num.to_float x)))
- |> C.register1 "acos" t_int f_number (fun x -> D.Num.of_float (acos (D.Num.to_float x)))
- |> C.register1 "sinh" t_int f_number (fun x -> D.Num.of_float (sinh (D.Num.to_float x)))
- |> C.register1 "cosh" t_int f_number (fun x -> D.Num.of_float (cosh (D.Num.to_float x)))
- |> C.register1 "tanh" t_int f_number (fun x -> D.Num.of_float (tanh (D.Num.to_float x)))
- |> C.register2 "atan2" (t_int, t_int)f_number (fun x y ->
- D.Num.of_float (atan2 (D.Num.to_float x) (D.Num.to_float y))
- )
-
- |> C.register1 "sqrt" t_int f_number (fun x -> D.Num.of_float (sqrt(D.Num.to_float x)))
- |> C.register1 "exp" t_int f_number (fun x -> D.Num.of_float (exp (D.Num.to_float x)))
- |> C.register1 "ln" t_int f_number (fun x -> D.Num.of_float (log (D.Num.to_float x)))
-
+ |> C.register1 "rand" t_unit f_number D.Num.rnd
+ |> C.register1 "pi" t_unit f_number (fun () -> D.Num.of_float (4. *. atan 1.))
+ |> C.register1 "sin" t_int f_number (fun x ->
+ D.Num.of_float (sin (D.Num.to_float x)))
+ |> C.register1 "cos" t_int f_number (fun x ->
+ D.Num.of_float (cos (D.Num.to_float x)))
+ |> C.register1 "tan" t_int f_number (fun x ->
+ D.Num.of_float (tan (D.Num.to_float x)))
+ |> C.register1 "atan" t_int f_number (fun x ->
+ D.Num.of_float (atan (D.Num.to_float x)))
+ |> C.register1 "asin" t_int f_number (fun x ->
+ D.Num.of_float (asin (D.Num.to_float x)))
+ |> C.register1 "acos" t_int f_number (fun x ->
+ D.Num.of_float (acos (D.Num.to_float x)))
+ |> C.register1 "sinh" t_int f_number (fun x ->
+ D.Num.of_float (sinh (D.Num.to_float x)))
+ |> C.register1 "cosh" t_int f_number (fun x ->
+ D.Num.of_float (cosh (D.Num.to_float x)))
+ |> C.register1 "tanh" t_int f_number (fun x ->
+ D.Num.of_float (tanh (D.Num.to_float x)))
+ |> C.register2 "atan2" (t_int, t_int) f_number (fun x y ->
+ D.Num.of_float (atan2 (D.Num.to_float x) (D.Num.to_float y)))
+ |> C.register1 "sqrt" t_int f_number (fun x ->
+ D.Num.of_float (sqrt (D.Num.to_float x)))
+ |> C.register1 "exp" t_int f_number (fun x ->
+ D.Num.of_float (exp (D.Num.to_float x)))
+ |> C.register1 "ln" t_int f_number (fun x ->
+ D.Num.of_float (log (D.Num.to_float x)))
|> C.register3 "if" (t_bool, t_int, t_int) f_number if_
|> C.register3 "if" (t_bool, t_bool, t_bool) f_bool if_
|> C.register3 "if" (t_bool, t_string, t_string) f_string if_
-
- |> C.register1 "abs" t_int f_number D.Num.abs
- |> C.register1 "int" t_int f_number D.Num.floor
- |> C.register1 "rounddown" t_int f_number D.Num.round_down
- |> C.register1 "round" t_int f_number D.Num.round
-
- |> C.register1 "trim" t_string f_string UTF8.trim
- |> C.register1 "right" t_string f_string (fun x -> UTF8.get x (-1))
- |> C.register2 "right" (t_string, t_int) f_string (
- fun t n ->
- let n' = D.Num.to_int n in
- UTF8.sub t (-(n')) n'
- )
- |> C.register1 "left" t_string f_string (fun x -> UTF8.get x 0)
- |> C.register2 "left" (t_string, t_int) f_string (
- fun t n ->
- let n' = D.Num.to_int n in
- UTF8.sub t 0 n'
- )
- |> C.register1 "len" t_string f_number (fun x -> D.Num.of_int (UTF8.length x))
- |> C.register1 "lenb" t_string f_number (fun x -> D.Num.of_int (String.length (UTF8.to_utf8string x)))
- |> C.register1 "lower" t_string f_string UTF8.lower
- |> C.register1 "unicode" t_string f_number (fun x -> D.Num.of_int (UTF8.code x))
- |> C.register1 "unichar" t_int f_string (fun x -> UTF8.char (D.Num.to_int x))
- |> C.register1 "upper" t_string f_string UTF8.upper
- |> C.register3 "substitute" (t_string, t_string, t_string) f_string UTF8.replace
- |> C.register2 "rept" (t_string, t_int) f_string (fun t n -> UTF8.repeat (D.Num.to_int n) t)
-
+ |> C.register1 "abs" t_int f_number D.Num.abs
+ |> C.register1 "int" t_int f_number D.Num.floor
+ |> C.register1 "rounddown" t_int f_number D.Num.round_down
+ |> C.register1 "round" t_int f_number D.Num.round
+ |> C.register1 "trim" t_string f_string UTF8.trim
+ |> C.register1 "right" t_string f_string (fun x -> UTF8.get x (-1))
+ |> C.register2 "right" (t_string, t_int) f_string (fun t n ->
+ let n' = D.Num.to_int n in
+ UTF8.sub t (-n') n')
+ |> C.register1 "left" t_string f_string (fun x -> UTF8.get x 0)
+ |> C.register2 "left" (t_string, t_int) f_string (fun t n ->
+ let n' = D.Num.to_int n in
+ UTF8.sub t 0 n')
+ |> C.register1 "len" t_string f_number (fun x -> D.Num.of_int (UTF8.length x))
+ |> C.register1 "lenb" t_string f_number (fun x ->
+ D.Num.of_int (String.length (UTF8.to_utf8string x)))
+ |> C.register1 "lower" t_string f_string UTF8.lower
+ |> C.register1 "unicode" t_string f_number (fun x ->
+ D.Num.of_int (UTF8.code x))
+ |> C.register1 "unichar" t_int f_string (fun x -> UTF8.char (D.Num.to_int x))
+ |> C.register1 "upper" t_string f_string UTF8.upper
+ |> C.register3 "substitute"
+ (t_string, t_string, t_string)
+ f_string UTF8.replace
+ |> C.register2 "rept" (t_string, t_int) f_string (fun t n ->
+ UTF8.repeat (D.Num.to_int n) t)
|> CompareBool.register t_bool
- |> C.register1 "true" t_unit f_bool (fun () -> D.Bool.true_)
- |> C.register1 "false" t_unit f_bool (fun () -> D.Bool.false_)
- |> C.register1 "not" t_bool f_bool D.Bool.not
- |> C.register2 "and" (t_bool, t_bool) f_bool D.Bool.and_
- |> C.register2 "or" (t_bool, t_bool) f_bool D.Bool.or_
- |> C.register2 "xor" (t_bool, t_bool) f_bool D.Bool.neq
-
+ |> C.register1 "true" t_unit f_bool (fun () -> D.Bool.true_)
+ |> C.register1 "false" t_unit f_bool (fun () -> D.Bool.false_)
+ |> C.register1 "not" t_bool f_bool D.Bool.not
+ |> C.register2 "and" (t_bool, t_bool) f_bool D.Bool.and_
+ |> C.register2 "or" (t_bool, t_bool) f_bool D.Bool.or_
+ |> C.register2 "xor" (t_bool, t_bool) f_bool D.Bool.neq
|> CompareString.register t_string
-
|> reduce "min" t_int f_num D.Num.min (* Minimum value from a list *)
|> reduce "max" t_int f_num D.Num.max (* Maximum value from a list *)
-
- |> fold "sum" t_int f_number D.Num.add (D.Num.zero)
- |> fold "product" t_int f_number D.Num.mult (D.Num.one)
-
- |> C.register2 "^" (t_int, t_int) f_number D.Num.pow
- |> C.register2 "power" (t_int, t_int) f_number D.Num.pow
-
- |> C.register2 "gcd"(t_int, t_int) f_number D.Num.gcd
- |> C.register2 "lcm"(t_int, t_int) f_number D.Num.lcm
- |> C.register1 "+" t_int f_num (fun x -> x)
- |> C.register1 "-" t_int f_num D.Num.neg (* Unary negation *)
- |> C.register2 "+" (t_int, t_int) f_num D.Num.add
- |> C.register2 "-" (t_int, t_int) f_num D.Num.sub
- |> C.register2 "*" (t_int, t_int) f_number D.Num.mult
- |> C.register2 "/" (t_int, t_int) f_number D.Num.div
-
-end
+ |> fold "sum" t_int f_number D.Num.add D.Num.zero
+ |> fold "product" t_int f_number D.Num.mult D.Num.one
+ |> C.register2 "^" (t_int, t_int) f_number D.Num.pow
+ |> C.register2 "power" (t_int, t_int) f_number D.Num.pow
+ |> C.register2 "gcd" (t_int, t_int) f_number D.Num.gcd
+ |> C.register2 "lcm" (t_int, t_int) f_number D.Num.lcm
+ |> C.register1 "+" t_int f_num (fun x -> x)
+ |> C.register1 "-" t_int f_num D.Num.neg (* Unary negation *)
+ |> C.register2 "+" (t_int, t_int) f_num D.Num.add
+ |> C.register2 "-" (t_int, t_int) f_num D.Num.sub
+ |> C.register2 "*" (t_int, t_int) f_number D.Num.mult
+ |> C.register2 "/" (t_int, t_int) f_number D.Num.div
diff --git a/src/tools.ml b/src/tools.ml index c9d78a7..88feade 100644 --- a/src/tools.ml +++ b/src/tools.ml @@ -18,213 +18,150 @@ along with licht. If not, see <http://www.gnu.org/licenses/>. let u = UTF8.from_utf8string module Option = struct - - let map f = function - | Some x -> Some (f x) - | None -> None - - let iter f = function - | Some x -> f x - | None -> () - - let bind f = function - | None -> None - | Some x -> f x - - let default v = function - | None -> v - | Some x -> x - - let test f v = begin - match f v with - | Some x -> x - | None -> v - end - - + let map f = function Some x -> Some (f x) | None -> None + let iter f = function Some x -> f x | None -> () + let bind f = function None -> None | Some x -> f x + let default v = function None -> v | Some x -> x + let test f v = match f v with Some x -> x | None -> v end module String = struct - include String - let split str ~by:sep = begin + let split str ~by:sep = let p = String.index str sep in let slen = String.length str in - String.sub str 0 p, String.sub str (p + 1) (slen - p - 1) - end + (String.sub str 0 p, String.sub str (p + 1) (slen - p - 1)) - let string_of_ints v = begin + let string_of_ints v = let buff = Buffer.create 1 in - let rec convert value = begin - Buffer.add_char buff @@ char_of_int @@ value land 0xFF; + let rec convert value = + Buffer.add_char buff @@ char_of_int @@ (value land 0xFF); let rem = value lsr 8 in - match rem with - | 0 -> Buffer.contents buff - | x -> (convert[@tailcall]) x - end in + match rem with 0 -> Buffer.contents buff | x -> (convert [@tailcall]) x + in let res = convert v in let buff' = Buffer.create @@ String.length res in - for i = ((String.length res) - 1) downto 0 do + for i = String.length res - 1 downto 0 do Buffer.add_char buff' @@ String.get res i done; Buffer.contents buff' - end - let print_buffer f t = begin + let print_buffer f t = let buff = UTF8.Buffer.create 16 in f buff t; UTF8.Buffer.contents buff - end - let filter_float str = begin + let filter_float str = let l = String.length str in - if l > 0 && String.get str (l - 1) = '.' then - String.sub str 0 (l - 1) - else - str - end - + if l > 0 && String.get str (l - 1) = '.' then String.sub str 0 (l - 1) + else str end module List = struct - (** fold_left over only the first element *) - let fst f init = function - | hd::tl -> f init hd - | [] -> init - - let printb ?(first=(u"(")) ?(last=(u")")) ?(sep=(u",")) f buffer elems = begin - - let rec print = begin function - | [] -> () - | hd::[] -> - f buffer hd; - | hd::tl -> - f buffer hd; - UTF8.Buffer.add_string buffer sep; - (print[@tailcall]) tl - end in + let fst f init = function hd :: tl -> f init hd | [] -> init + + let printb ?(first = u "(") ?(last = u ")") ?(sep = u ",") f buffer elems = + let rec print = function + | [] -> () + | [ hd ] -> f buffer hd + | hd :: tl -> + f buffer hd; + UTF8.Buffer.add_string buffer sep; + (print [@tailcall]) tl + in UTF8.Buffer.add_string buffer first; print elems; UTF8.Buffer.add_string buffer last - end - - let rec find_map f = begin function - | [] -> raise Not_found - | hd::tl -> begin match f hd with - | Some x -> x - | None -> (find_map[@tailcall]) f tl - end - end - - and find_map2 p = begin function - | [] -> raise Not_found - | x::l -> - begin try find_map p x with - Not_found -> (find_map2[@tailcall]) p l - end - end + let rec find_map f = function + | [] -> raise Not_found + | hd :: tl -> ( + match f hd with Some x -> x | None -> (find_map [@tailcall]) f tl) + + and find_map2 p = function + | [] -> raise Not_found + | x :: l -> ( + try find_map p x with Not_found -> (find_map2 [@tailcall]) p l) end module Tuple2 = struct - - let fst = Pervasives.fst - - let snd = Pervasives.snd - + let fst = Stdlib.fst + let snd = Stdlib.snd let map1 f (a, b) = (f a, b) - let map2 f (a, b) = (a, f b) - let replace1 v (a, b) = (v, b) - let replace2 v (a, b) = (a, v) - let printb ?(first="(") ?(last=")") ?(sep=",") format1 format2 out (a, b) = begin - UTF8.Printf.bprintf out "%s%a%s%a%s" - first - format1 a - sep - format2 b - last - end - + let printb ?(first = "(") ?(last = ")") ?(sep = ",") format1 format2 out (a, b) + = + UTF8.Printf.bprintf out "%s%a%s%a%s" first format1 a sep format2 b last end module NCurses = struct - type mouse_event = - | BUTTON1_PRESSED - | BUTTON1_RELEASED - | BUTTON1_CLICKED - | BUTTON1_DOUBLE_CLICKED - | BUTTON1_TRIPLE_CLICKED - | BUTTON2_PRESSED - | BUTTON2_RELEASED - | BUTTON2_CLICKED - | BUTTON2_DOUBLE_CLICKED - | BUTTON2_TRIPLE_CLICKED - | BUTTON3_PRESSED - | BUTTON3_RELEASED - | BUTTON3_CLICKED - | BUTTON3_DOUBLE_CLICKED - | BUTTON3_TRIPLE_CLICKED - | BUTTON4_PRESSED - | BUTTON4_RELEASED - | BUTTON4_CLICKED - | BUTTON4_DOUBLE_CLICKED - | BUTTON4_TRIPLE_CLICKED - | BUTTON_SHIFT - | BUTTON_CTRL - | BUTTON_ALT - | ALL_MOUSE_EVENTS - | REPORT_MOUSE_POSITION + | BUTTON1_PRESSED + | BUTTON1_RELEASED + | BUTTON1_CLICKED + | BUTTON1_DOUBLE_CLICKED + | BUTTON1_TRIPLE_CLICKED + | BUTTON2_PRESSED + | BUTTON2_RELEASED + | BUTTON2_CLICKED + | BUTTON2_DOUBLE_CLICKED + | BUTTON2_TRIPLE_CLICKED + | BUTTON3_PRESSED + | BUTTON3_RELEASED + | BUTTON3_CLICKED + | BUTTON3_DOUBLE_CLICKED + | BUTTON3_TRIPLE_CLICKED + | BUTTON4_PRESSED + | BUTTON4_RELEASED + | BUTTON4_CLICKED + | BUTTON4_DOUBLE_CLICKED + | BUTTON4_TRIPLE_CLICKED + | BUTTON_SHIFT + | BUTTON_CTRL + | BUTTON_ALT + | ALL_MOUSE_EVENTS + | REPORT_MOUSE_POSITION type event_type - external set_mouse_event: mouse_event list -> unit = "c_set_mouse_event" - - external get_mouse_event: unit -> (int * event_type * (int * int * int)) option = "c_get_mouse_event" + external set_mouse_event : mouse_event list -> unit = "c_set_mouse_event" - external is_event_of_type: mouse_event -> event_type -> bool = "c_is_event_of_type" + external get_mouse_event : + unit -> (int * event_type * (int * int * int)) option = "c_get_mouse_event" + external is_event_of_type : mouse_event -> event_type -> bool + = "c_is_event_of_type" end let try_finally f except = - try let res = f () in + try + let res = f () in except (); res with e -> except (); raise e -type (_,_) cmp = - | Eq : ('a,'a) cmp - | Lt : ('a,'b) cmp - | Gt : ('a,'b) cmp +type (_, _) cmp = Eq : ('a, 'a) cmp | Lt : ('a, 'b) cmp | Gt : ('a, 'b) cmp (** Existencial type for comparing two types. This type has no utility, except for structural comparison between two values. *) -type existencial = Ex: 'a -> existencial +type existencial = Ex : 'a -> existencial module type COMPARABLE_TYPE = sig + type 'a t - type 'a t - - val comp: 'a t -> 'b t -> ('a, 'b) cmp - + val comp : 'a t -> 'b t -> ('a, 'b) cmp end let fold_for f a b init = - let rec _fold res i = begin - if i >= b then res - else - _fold (f i res) (i + 1) - end in - (_fold[@tailcall]) init a - + let rec _fold res i = if i >= b then res else _fold (f i res) (i + 1) in + (_fold [@tailcall]) init a diff --git a/src/tree/pageMap.ml b/src/tree/pageMap.ml index e18ba6f..967ccfe 100644 --- a/src/tree/pageMap.ml +++ b/src/tree/pageMap.ml @@ -18,178 +18,141 @@ along with licht. If not, see <http://www.gnu.org/licenses/>. type cell = int * int
module type T_DEFAULT = sig
-
type t
val default : t
-
end
-module MapArray(T:T_DEFAULT) = struct
-
+module MapArray (T : T_DEFAULT) = struct
+ type t = int * T.t array array
(** The type is composed by the number of defined cell in the page, and the page itself *)
- type t = int * (T.t array array)
- let find (x:int) (y:int) (t:t) : T.t = begin
+ let find (x : int) (y : int) (t : t) : T.t =
let block = snd t in
block.(y).(x)
- end
- let add (x:int) (y:int) (value:T.t) (t:t) : t = begin
+ let add (x : int) (y : int) (value : T.t) (t : t) : t =
let n, block = t in
- let n' =
- if (block.(y).(x) == T.default) then
- n + 1
- else
- n in
+ let n' = if block.(y).(x) == T.default then n + 1 else n in
block.(y).(x) <- value;
- n', block
- end
+ (n', block)
- let remove (x:int) (y:int) (t:t) : t = begin
+ let remove (x : int) (y : int) (t : t) : t =
let n, block = t in
- if (block.(y).(x) = T.default) then
- t
+ if block.(y).(x) = T.default then t
+ else if n = 1 then (* Do not keep empty block in memory *)
+ raise Not_found
else (
- if n = 1 then
- (* Do not keep empty block in memory *)
- raise Not_found
- else (
- block.(y).(x) <- T.default;
- (n -1, block)
- )
- )
- end
+ block.(y).(x) <- T.default;
+ (n - 1, block))
- let create array_size = begin
- 0, Array.make_matrix array_size array_size T.default
- end
+ let create array_size = (0, Array.make_matrix array_size array_size T.default)
- let fold_line f y init t = begin
- let n, block = t
- and res = ref init in
+ let fold_line f y init t =
+ let n, block = t and res = ref init in
let array_size = Array.length block in
- for x = 0 to (array_size - 1) do
+ for x = 0 to array_size - 1 do
let value = block.(y).(x) in
- if value != T.default then
- res := f x value !res;
+ if value != T.default then res := f x value !res
done;
!res
- end
-
end
-module SplayMap(T:T_DEFAULT) = struct
-
+module SplayMap (T : T_DEFAULT) = struct
let array_size = 8
- module PageMap = MapArray(T)
+ module PageMap = MapArray (T)
(** Module for the keys *)
module K = struct
-
type 'a t = K : (int * int) -> PageMap.t t [@@unboxed]
- let comp:type a b. a t -> b t -> (a, b) Tools.cmp = fun a b -> begin
- match a, b with K (x1, y1), K (x2, y2) ->
- let res = Pervasives.compare (y1, x1) (y2, x2) in
- if res < 0 then
- Tools.Lt
- else if res > 0 then
- Tools.Gt
- else
- Tools.Eq
- end
-
- let repr: type a. Format.formatter -> a t -> unit = fun formatter (K (x, y)) ->
- Format.fprintf formatter "%d, %d" x y
+ let comp : type a b. a t -> b t -> (a, b) Tools.cmp =
+ fun a b ->
+ match (a, b) with
+ | K (x1, y1), K (x2, y2) ->
+ let res = Stdlib.compare (y1, x1) (y2, x2) in
+ if res < 0 then Tools.Lt else if res > 0 then Tools.Gt else Tools.Eq
+ let repr : type a. Format.formatter -> a t -> unit =
+ fun formatter (K (x, y)) -> Format.fprintf formatter "%d, %d" x y
end
- module Map = Splay.Make(K)
+ module Map = Splay.Make (K)
type t = Map.t
(* Values are always positive *)
- let get_bounded_values (x, y) = (max 0 x), (max 0 y)
+ let get_bounded_values (x, y) = (max 0 x, max 0 y)
- let find (id:cell) (t:Map.t) : T.t = begin
+ let find (id : cell) (t : Map.t) : T.t =
let x, y = get_bounded_values id in
- let block_x = x / array_size
- and block_y = y / array_size in
+ let block_x = x / array_size and block_y = y / array_size in
try
let block = Map.find (K (block_x, block_y)) t in
PageMap.find (x mod array_size) (y mod array_size) block
with Not_found -> T.default
- end
- let add (id:cell) (value:T.t) (t:Map.t) : Map.t = begin
+ let add (id : cell) (value : T.t) (t : Map.t) : Map.t =
let x, y = get_bounded_values id in
- let block_x = x / array_size
- and block_y = y / array_size in
+ let block_x = x / array_size and block_y = y / array_size in
let block =
try Map.find (K (block_x, block_y)) t
- with Not_found -> PageMap.create array_size in
+ with Not_found -> PageMap.create array_size
+ in
let page = PageMap.add (x mod array_size) (y mod array_size) value block in
Map.add (K (block_x, block_y)) page t
- end
- let remove (id:cell) (t:Map.t) : Map.t = begin
+ let remove (id : cell) (t : Map.t) : Map.t =
let x, y = get_bounded_values id in
- let block_x = x / array_size
- and block_y = y / array_size in
+ let block_x = x / array_size and block_y = y / array_size in
try
let block = Map.find (K (block_x, block_y)) t in
try
- let block' = PageMap.remove (x mod array_size) (y mod array_size) block in
+ let block' =
+ PageMap.remove (x mod array_size) (y mod array_size) block
+ in
Map.add (K (block_x, block_y)) block' t
- with Not_found ->
- Map.remove (K (block_x, block_y)) t
+ with Not_found -> Map.remove (K (block_x, block_y)) t
with Not_found -> t
- end
(** Empty map *)
let empty = Map.empty
(** Fold over the elements in the Map.*)
- let fold f (t:Map.t) init = begin
+ let fold f (t : Map.t) init =
let res = ref init in
- let call_function column row x value acc = begin
- f (column + x, row) value acc
- end in
+ let call_function column row x value acc = f (column + x, row) value acc in
(* Call process_line for each block on the same row *)
- let process_pages block_y acc = begin
- let blocks = List.rev acc
- and row_index = block_y * array_size in
- for y = 0 to (array_size - 1) do
+ let process_pages block_y acc =
+ let blocks = List.rev acc and row_index = block_y * array_size in
+ for y = 0 to array_size - 1 do
let row = row_index + y in
- res := List.fold_left (fun init (column, block) ->
- PageMap.fold_line (call_function column row) y init block
- ) !res blocks;
-
+ res :=
+ List.fold_left
+ (fun init (column, block) ->
+ PageMap.fold_line (call_function column row) y init block)
+ !res blocks
done
- end in
-
- let fold_blocks (current_row, acc) (Map.C key_val) = begin
- match key_val with ((K.K (block_x, block_y)), (block:PageMap.t)) ->
- (* As long as the page lay in the same row, accumulate it *)
- if current_row = block_y then
- current_row, (block_x * array_size, block)::acc
- else (
- (* We apply the function for each accumulated block in the row *)
- process_pages current_row acc;
- block_y, (block_x, block)::[]
- )
- end in
+ in
+
+ let fold_blocks (current_row, acc) (Map.C key_val) =
+ match key_val with
+ | K.K (block_x, block_y), (block : PageMap.t) ->
+ (* As long as the page lay in the same row, accumulate it *)
+ if current_row = block_y then
+ (current_row, (block_x * array_size, block) :: acc)
+ else (
+ (* We apply the function for each accumulated block in the row *)
+ process_pages current_row acc;
+ (block_y, [ (block_x, block) ]))
+ in
let row_number, acc = Map.fold fold_blocks (1, []) t in
(* Apply the function to the last row *)
process_pages row_number acc;
!res
- end
-
-
end
|