diff options
Diffstat (limited to 'syntax/type_of.ml')
-rw-r--r-- | syntax/type_of.ml | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/syntax/type_of.ml b/syntax/type_of.ml index 5ef90f4..0a6bf34 100644 --- a/syntax/type_of.ml +++ b/syntax/type_of.ml @@ -7,6 +7,8 @@ module Helper = struct type t = Integer | Bool | String | Any [@@deriving show { with_path = false }] + type argument_repr = { pos : pos; t : t } + type dyn_type = t -> t (** Dynamic type is a type unknown during the code. @@ -32,10 +34,14 @@ module Helper = struct type argument = Fixed of t | Dynamic of dyn_type | Variable of argument let compare : - ?level:Report.level -> t -> pos * t -> Report.t list -> Report.t list = + ?level:Report.level -> + t -> + argument_repr -> + Report.t list -> + Report.t list = fun ?(level = Report.Warn) expected actual report -> let equal = - match (expected, snd actual) with + match (expected, actual.t) with | _, Any -> true | Any, _ -> true | String, String -> true @@ -51,21 +57,21 @@ module Helper = struct else let message = Format.asprintf "The type %a is expected but got %a" pp expected pp - (snd actual) + actual.t in - Report.message level (fst actual) message :: report + Report.message level actual.pos message :: report let rec compare_parameter : ?level:Report.level -> argument -> - pos * t -> + argument_repr -> Report.t list -> Report.t list = fun ?(level = Report.Warn) expected param report -> match expected with | Fixed t -> compare ~level t param report | Dynamic d -> - let type_ = d (snd param) in + let type_ = d param.t in compare ~level type_ param report | Variable c -> compare_parameter ~level c param report @@ -74,7 +80,7 @@ module Helper = struct ?level:Report.level -> pos -> argument list -> - (pos * t) list -> + argument_repr list -> Report.t list -> Report.t list = fun ?(level = Report.Warn) pos expected actuals report -> @@ -89,7 +95,7 @@ module Helper = struct let check = compare_parameter ~level hd param report in (tl, check) | [] -> - let msg = Report.error (fst param) "Unexpected argument" in + let msg = Report.error param.pos "Unexpected argument" in ([], msg :: report)) in match tl with @@ -116,11 +122,11 @@ module Expression = struct type variable = { pos : pos; name : string; index : repr option } - let arg_of_repr : t -> pos * Helper.t = + let arg_of_repr : t -> Helper.argument_repr = fun { result; report; pos; empty } -> ignore report; ignore empty; - (pos, result) + { pos; t = result } (** The variable has type string when starting with a '$' *) let ident : variable -> repr = @@ -245,7 +251,8 @@ module Expression = struct let boperator : pos -> T.boperator -> repr -> repr -> repr = fun pos operator t1 t2 report -> - let types = [ arg_of_repr (t1 report); arg_of_repr (t2 report) ] in + let t1 = t1 report and t2 = t2 report in + let types = [ arg_of_repr t1; arg_of_repr t2 ] in match operator with | T.Plus -> (* Operation over number *) @@ -253,7 +260,17 @@ module Expression = struct let expected = [ d; d ] in let report = Helper.compare_args pos expected types report in { result = Bool; report; pos; empty = false } - | T.Eq | T.Neq | Lt | Gte | Lte | Gt -> + | T.Eq | T.Neq -> + (* If the expression is '' or 0, we accept the comparaison as if + instead of raising a warning *) + if t1.empty || t2.empty then + { result = Bool; report; pos; empty = false } + else + let d = Helper.(Dynamic (dyn_type ())) in + let expected = [ d; d ] in + let report = Helper.compare_args pos expected types report in + { result = Bool; report; pos; empty = false } + | Lt | Gte | Lte | Gt -> let d = Helper.(Dynamic (dyn_type ())) in let expected = [ d; d ] in let report = Helper.compare_args pos expected types report in |