aboutsummaryrefslogtreecommitdiff
path: root/scTypes.ml
diff options
context:
space:
mode:
Diffstat (limited to 'scTypes.ml')
-rwxr-xr-xscTypes.ml168
1 files changed, 168 insertions, 0 deletions
diff --git a/scTypes.ml b/scTypes.ml
new file mode 100755
index 0000000..ddbae12
--- /dev/null
+++ b/scTypes.ml
@@ -0,0 +1,168 @@
+(** All the types used in the spreadsheet. *)
+
+module Calendar = CalendarLib.Calendar.Precise
+
+let u = UTF8.from_utf8string
+
+exception Error
+
+type cell = Cell.t
+
+type ident = UTF8.t
+
+type types =
+ | Num : Num.num * (UTF8.t option) -> types (** A number *)
+ | Str : UTF8.t -> types (** A string *)
+ | Date : Num.num -> types (** A date in julian day *)
+
+ | Undefined : types (** The content is not defined *)
+ | Bool : bool -> types (** A boolean *)
+ | List : types list -> types (** List with heterogenous datas *)
+
+type refs =
+ | Cell of cell (** A cell *)
+ | Range of cell * cell (** An area of cells *)
+
+type expression =
+ | Value of types (** A direct value *)
+ | Ref of refs (** A reference to another cell *)
+ | Call of ident * expression list (** A call to a function *)
+ | Expression of expression (** An expression *)
+
+(** Result from a computation *)
+type result =
+ | Result of types
+ | Error of exn
+
+module Type = struct
+ (* Required because Num.Big_int cannot be compared with Pervasives.(=) *)
+ let (=) t1 t2 =
+ match t1, t2 with
+ | Num (n1,_), Num (n2,_) -> Num.eq_num n1 n2
+ | Date n1, Date n2 -> Num.eq_num n1 n2
+ | Num _, Date n2 -> false
+ | Date n1, Num _ -> false
+ | _, _ -> t1 = t2
+
+ (** Show a list of elements
+ *)
+ let rec show_list printer buffer = begin function
+ | [] -> ()
+ | hd::[] ->
+ UTF8.Printf.bprintf buffer "%a"
+ printer hd
+ | hd::tl ->
+ UTF8.Printf.bprintf buffer "%a, "
+ printer hd;
+ show_list printer buffer tl
+ end
+
+ and show buffer = begin function
+ | Undefined -> ()
+ | Num (n,x) ->
+ begin match x with
+ | Some value -> UTF8.Buffer.add_string buffer value
+ | None ->
+ if Num.is_integer_num n then
+ UTF8.Buffer.add_string buffer @@ u(Num.string_of_num n)
+ else
+ UTF8.Printf.bprintf buffer "%.*f" 2 (Num.float_of_num n)
+ end
+ | Str x -> UTF8.Buffer.add_string buffer x
+ | Bool b -> UTF8.Printf.bprintf buffer "%B" b
+ | List l ->
+ UTF8.Printf.bprintf buffer "[%a]"
+ (show_list show) l
+ | Date n ->
+ Num.float_of_num n
+ |> Calendar.from_jd
+ |> CalendarLib.Printer.Precise_Calendar.to_string
+ |> u
+ |> UTF8.Buffer.add_string buffer
+ end
+
+end
+
+module Refs = struct
+
+ let collect = function
+ | Cell x -> [Pervasives.fst x]
+ | Range (first, snd) ->
+ let (x1, y1) = Pervasives.fst first
+ and (x2, y2) = Pervasives.fst snd in
+ let min_x = min x1 x2
+ and max_x = max x1 x2
+ and min_y = min y1 y2
+ and max_y = max y1 y2 in
+ let elms = ref [] in
+ for x = min_x to max_x do
+ for y = min_y to max_y do
+ elms := (x, y)::!elms
+ done
+ done;
+ List.rev (!elms)
+
+ let shift (vector_x, vector_y) ref =
+ let _shift ((x, y), (fixed_x, fixed_y)) =
+ let x' = if fixed_x then x else x + vector_x
+ and y' = if fixed_y then y else y + vector_y in
+ (x', y'), (fixed_x, fixed_y)
+ in match ref with
+ | Cell x -> Cell (_shift x)
+ | Range (fst, snd) -> Range (_shift fst, _shift snd)
+
+ let show buffer = begin function
+ | Cell r -> UTF8.Buffer.add_string buffer @@ Cell.to_string r
+ | Range (f,t) ->
+ Tools.Tuple2.printb ~first:"" ~last:"" ~sep:":" Cell.to_buffer Cell.to_buffer buffer (f,t)
+ end
+
+end
+
+module Result = struct
+ let (=) t1 t2 =
+ match t1, t2 with
+ | Result v1, Result v2 -> Type.(=) v1 v2
+ | _, _ -> t1 = t2
+
+
+ let show = begin function
+ | Error _ -> u"#Error"
+ | Result v ->
+ let buffer = UTF8.Buffer.create 16 in
+ Type.show buffer v;
+ UTF8.Buffer.contents buffer
+ end
+
+end
+
+(** Represent an expression.
+ *)
+let rec show_expr buffer : expression -> unit = begin function
+ | Value (Str x) ->
+ (** Print the value with quotes *)
+ UTF8.Printf.bprintf buffer "\"%s\"" (UTF8.to_utf8string x)
+ | Value v -> Type.show buffer v
+ | Ref r -> Refs.show buffer r
+ | Call (ident, params) ->
+ let utf8ident = UTF8.to_utf8string ident in
+ begin match utf8ident with
+ | "+" | "*" | "-" | "/" | "^" | "="
+ | "<>" | "<=" | ">=" | "<" | ">" -> begin match params with
+ | v1::v2::[] ->
+ UTF8.Printf.bprintf buffer "%a%s%a"
+ show_expr v1
+ utf8ident
+ show_expr v2
+ | _ ->
+ UTF8.Buffer.add_string buffer ident;
+ Tools.List.printb ~sep:(u";") show_expr buffer params
+ end
+ | _ ->
+ UTF8.Buffer.add_string buffer ident;
+ Tools.List.printb ~sep:(u";") show_expr buffer params
+ end
+ | Expression expr ->
+ UTF8.Printf.bprintf buffer "(%a)" show_expr expr
+end
+