aboutsummaryrefslogtreecommitdiff
path: root/lib/checks/type_of.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/checks/type_of.ml')
-rw-r--r--lib/checks/type_of.ml115
1 files changed, 55 insertions, 60 deletions
diff --git a/lib/checks/type_of.ml b/lib/checks/type_of.ml
index 42f9a2d..243c8b3 100644
--- a/lib/checks/type_of.ml
+++ b/lib/checks/type_of.ml
@@ -12,12 +12,15 @@ type context = unit
let initialize = Fun.id
let finalize () = []
+let depends = [ Get_type.ex ]
+
+type ex = Qsp_syntax.Identifier.t
module Helper = struct
- type argument_repr = { pos : S.pos; t : Get_type.t }
+ type argument_repr = { pos : S.pos; t : Get_type.Expression.t }
module DynType = struct
- type nonrec t = Get_type.t -> Get_type.t
+ type nonrec t = Get_type.Expression.t -> Get_type.Expression.t
(** Dynamic type is a type unknown during the code.
For example, the equality operator accept either Integer or String, but
@@ -143,35 +146,35 @@ module Helper = struct
msg :: report
end
-type t' = { result : Get_type.t Lazy.t; pos : S.pos }
+type t' = { result : Get_type.Expression.t; pos : S.pos }
-let arg_of_repr : Get_type.t Lazy.t -> S.pos -> Helper.argument_repr =
- fun type_of pos -> { pos; t = Lazy.force type_of }
+let arg_of_repr : Get_type.Expression.t -> S.pos -> Helper.argument_repr =
+ fun type_of pos -> { pos; t = type_of }
-module TypedExpression = struct
+module Expression = struct
type nonrec t' = t' * Report.t list
- type state = { pos : S.pos }
+ type state = { pos : S.pos; type_of : Get_type.Expression.t }
type t = state * Report.t list
- let v : Get_type.t Lazy.t * t -> t' =
- fun (type_of, (t, r)) -> ({ result = type_of; pos = t.pos }, r)
+ let v : t -> t' = fun (t, r) -> ({ result = t.type_of; pos = t.pos }, r)
(** The variable has type string when starting with a '$' *)
- let ident :
- (S.pos, Get_type.t Lazy.t * t) S.variable -> Get_type.t Lazy.t -> t =
- fun var _type_of ->
+ let ident : ctx:Qsp_syntax.S.extract_context -> (S.pos, t) S.variable -> t =
+ fun ~ctx var ->
(* Extract the error from the index *)
let report =
match var.index with
| None -> []
| Some (_, expr) ->
- let _, r = expr in
+ let r = expr in
r
in
- ({ pos = var.pos }, report)
+ let type_of = Option.get (ctx.f Get_type.expression_id) in
+ ({ pos = var.pos; type_of }, report)
- let integer : S.pos -> string -> Get_type.t Lazy.t -> t =
- fun pos value _type_of ->
+ let integer : ctx:Qsp_syntax.S.extract_context -> S.pos -> string -> t =
+ fun ~ctx pos value ->
+ let type_of = Option.get (ctx.f Get_type.expression_id) in
let int_value = int_of_string_opt value in
let report =
@@ -181,42 +184,36 @@ module TypedExpression = struct
| None -> Report.error pos "Invalid integer value" :: []
in
- ({ pos }, report)
+ ({ pos; type_of }, report)
let literal :
- S.pos -> (Get_type.t Lazy.t * t) T.literal list -> Get_type.t Lazy.t -> t
- =
- fun pos values type_of ->
- ignore type_of;
+ ctx:Qsp_syntax.S.extract_context -> S.pos -> t T.literal list -> t =
+ fun ~ctx pos values ->
+ let type_of = Option.get (ctx.f Get_type.expression_id) in
let init = [] in
let report =
List.fold_left values ~init ~f:(fun report -> function
| T.Text _ -> report
- | T.Expression (_, t) ->
+ | T.Expression t ->
let report = List.rev_append (snd t) report in
report)
in
- ({ pos }, report)
+ ({ pos; type_of }, report)
let function_ :
- S.pos ->
- T.function_ ->
- (Get_type.t Lazy.t * t) list ->
- Get_type.t Lazy.t ->
- t =
- fun pos function_ params _type_of ->
+ ctx:Qsp_syntax.S.extract_context -> S.pos -> T.function_ -> t list -> t =
+ fun ~ctx pos function_ params ->
+ let type_of = Option.get (ctx.f Get_type.expression_id) in
(* Accumulate the expressions and get the results, the report is given in
the differents arguments, and we build a list with the type of the
parameters. *)
let types, report =
- List.fold_left params ~init:([], [])
- ~f:(fun (types, report) (type_of, param) ->
- ignore type_of;
+ List.fold_left params ~init:([], []) ~f:(fun (types, report) param ->
let t, r = param in
- let arg = arg_of_repr type_of t.pos in
+ let arg = arg_of_repr t.type_of t.pos in
(arg :: types, r @ report))
in
- let types = List.rev types and default = { pos } in
+ let types = List.rev types and default = { pos; type_of } in
match function_ with
| Arrcomp | Arrpos | Arrsize | Countobj | Desc | Dyneval | Getobj | Instr
@@ -229,7 +226,7 @@ module TypedExpression = struct
let expected = Helper.[ Fixed Bool; Dynamic d; Dynamic d ] in
let report = Helper.compare_args pos expected types report in
(* Extract the type for the expression *)
- ({ pos }, report)
+ ({ pos; type_of }, report)
| Input | Input' ->
(* Input should check the result if the variable is a num and raise a
message in this case.*)
@@ -257,7 +254,7 @@ module TypedExpression = struct
(* All the arguments must have the same type *)
let expected = Helper.[ Variable (Dynamic d) ] in
let report = Helper.compare_args pos expected types report in
- ({ pos }, report)
+ ({ pos; type_of }, report)
| Mid | Mid' ->
let expected = Helper.[ Fixed String; Variable (Fixed Integer) ] in
let report = Helper.compare_args pos expected types report in
@@ -292,29 +289,25 @@ module TypedExpression = struct
(** Unary operator like [-123] or [+'Text']*)
let uoperator :
- S.pos -> T.uoperator -> Get_type.t Lazy.t * t -> Get_type.t Lazy.t -> t =
- fun pos operator t1 type_of ->
- ignore type_of;
- let type_of, (t, report) = t1 in
+ ctx:Qsp_syntax.S.extract_context -> S.pos -> T.uoperator -> t -> t =
+ fun ~ctx pos operator t1 ->
+ let t, report = t1 in
match operator with
| Add -> (t, report)
| Neg | No ->
- let types = [ arg_of_repr type_of t.pos ] in
+ let types = [ arg_of_repr t.type_of t.pos ] in
let expected = Helper.[ Fixed Integer ] in
let report = Helper.compare_args pos expected types report in
- ({ pos }, report)
+ let type_of = Option.get (ctx.f Get_type.expression_id) in
+ ({ pos; type_of }, report)
let boperator :
- S.pos ->
- T.boperator ->
- Get_type.t Lazy.t * t ->
- Get_type.t Lazy.t * t ->
- Get_type.t Lazy.t ->
- t =
- fun pos operator (type_1, t1) (type_2, t2) type_of ->
- ignore type_of;
+ ctx:Qsp_syntax.S.extract_context -> S.pos -> T.boperator -> t -> t -> t =
+ fun ~ctx pos operator t1 t2 ->
let t1, report1 = t1 in
let t2, report2 = t2 in
+ let type_1 = t1.type_of and type_2 = t2.type_of in
+ let type_of = Option.get (ctx.f Get_type.expression_id) in
let report = report1 @ report2 in
@@ -327,7 +320,7 @@ module TypedExpression = struct
When concatenating, it’s allowed to add an integer and a number.
*)
- ({ pos }, report)
+ ({ pos; type_of }, report)
| T.Eq | T.Neq | Lt | Gte | Lte | Gt ->
(* If the expression is '' or 0, we accept the comparaison as if
instead of raising a warning *)
@@ -345,26 +338,24 @@ module TypedExpression = struct
report
| report -> report
in
- ({ pos }, report)
+ ({ pos; type_of }, report)
| T.Mod | T.Minus | T.Product | T.Div ->
(* Operation over number *)
let expected = Helper.[ Fixed Integer; Fixed Integer ] in
let report = Helper.compare_args pos expected types report in
- ({ pos }, report)
+ ({ pos; type_of }, report)
| T.And | T.Or ->
(* Operation over booleans *)
let expected = Helper.[ Fixed Bool; Fixed Bool ] in
let report = Helper.compare_args pos expected types report in
- ({ pos }, report)
+ ({ pos; type_of }, report)
end
-module Expression = Compose.TypeBuilder.Make (TypedExpression)
-
module Instruction = struct
type t = Report.t list
type t' = Report.t list
- let v : t -> t' = fun local_report -> local_report
+ let v : t -> t' = Fun.id
type expression = Expression.t'
@@ -444,17 +435,21 @@ module Instruction = struct
let report = List.rev_append report' report in
- match (op, Get_type.get_type (Lazy.force right_expression.result)) with
+ match (op, Get_type.Expression.get_type right_expression.result) with
| T.Eq', Get_type.Integer ->
(* Assigning an intger is allowed in a string variable, but raise a
warning. *)
- let var_type = Lazy.from_val (Get_type.ident variable) in
+ let var_type =
+ Get_type.Expression.ident ~ctx:{ f = (fun _ -> None) } variable
+ in
let op1 = arg_of_repr var_type variable.pos in
let expected = Helper.[ Fixed Integer ] in
Helper.compare_args ~strict:true ~level:Report.Warn pos expected [ op1 ]
report
| _, _ -> (
- let var_type = Lazy.from_val (Get_type.ident variable) in
+ let var_type =
+ Get_type.Expression.ident ~ctx:{ f = (fun _ -> None) } variable
+ in
let op1 = arg_of_repr var_type variable.pos in
let op2 = arg_of_repr right_expression.result right_expression.pos in