aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChimrod <>2023-10-07 10:35:10 +0200
committerChimrod <>2023-10-15 19:04:36 +0200
commit7f2b8c0b9fbe6c9b3b4291c1749fc4d53866b85b (patch)
treedd0204f94aa978dd8884a6c1e7bf3df6eda7e5e5
parent5a18a66763bcc19de117cb83293d7bd25a0ea10c (diff)
Made the report result explicit in parsing
-rw-r--r--lib/syntax/type_of.ml136
1 files changed, 60 insertions, 76 deletions
diff --git a/lib/syntax/type_of.ml b/lib/syntax/type_of.ml
index 462f1cd..1cefc22 100644
--- a/lib/syntax/type_of.ml
+++ b/lib/syntax/type_of.ml
@@ -110,30 +110,18 @@ end
module Expression = struct
type 'a obs
+ type t = { result : Helper.t; pos : pos; empty : bool }
- type t = {
- result : Helper.t;
- report : Report.t list; (* See the comment below *)
- pos : pos;
- empty : bool;
- }
-
- type repr = Report.t list -> t
+ type repr = Report.t list -> t * Report.t list
(** The type repr is a function accepting the report as a first argement.
When the report is given, it will be reported into the tree and collected
in bottom-top.
-
- It’s easy to forget that the report is updated when the type is created.
- The function takes the report in argument, and store the report in the
- returned type. Maybe should I make a tupple instead in order to make it
- explicit ?
*)
type variable = { pos : pos; name : string; index : repr option }
let arg_of_repr : t -> Helper.argument_repr =
- fun { result; report; pos; empty } ->
- ignore report;
+ fun { result; pos; empty } ->
ignore empty;
{ pos; t = result }
@@ -142,8 +130,8 @@ module Expression = struct
fun var report ->
let empty = false in
match var.name.[0] with
- | '$' -> { result = String; report; pos = var.pos; empty }
- | _ -> { result = Integer; report; pos = var.pos; empty }
+ | '$' -> ({ result = String; pos = var.pos; empty }, report)
+ | _ -> ({ result = Integer; pos = var.pos; empty }, report)
let integer : pos -> string -> repr =
fun pos value report ->
@@ -151,12 +139,12 @@ module Expression = struct
match int_of_string_opt value with Some 0 -> true | _ -> false
in
- { result = Integer; report; pos; empty }
+ ({ result = Integer; pos; empty }, report)
let literal : pos -> string -> repr =
fun pos value report ->
let empty = String.equal String.empty value in
- { result = String; report; pos; empty }
+ ({ result = String; pos; empty }, report)
let function_ : pos -> T.function_ -> repr list -> repr =
fun pos function_ params _acc ->
@@ -165,106 +153,105 @@ module Expression = struct
parameters. *)
let types, report =
List.fold_left params ~init:([], _acc) ~f:(fun (types, report) param ->
- let t = param report in
+ let t, report = param report in
let arg = arg_of_repr t in
- (arg :: types, t.report))
+ (arg :: types, report))
in
let types = List.rev types
- and default = { result = Any; report; pos; empty = false } in
+ and default = { result = Any; pos; empty = false } in
match function_ with
| Arrcomp | Arrpos | Arrsize | Countobj | Desc | Dyneval | Func | Getobj
| Instr | Isplay ->
- { default with result = Integer }
- | Desc' | Dyneval' | Func' | Getobj' -> { default with result = String }
+ ({ default with result = Integer }, report)
+ | Desc' | Dyneval' | Func' | Getobj' ->
+ ({ default with result = String }, report)
| Iif | Iif' ->
let d = Helper.dyn_type () in
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 *)
let result = d Helper.Bool in
- { result; report; pos; empty = false }
+ ({ result; pos; empty = false }, report)
| Input | Input' ->
(* Input should check the result if the variable is a num and raise a
message in this case.*)
let expected = Helper.[ Fixed String ] in
let report = Helper.compare_args pos expected types report in
- { result = String; report; pos; empty = false }
+ ({ result = String; pos; empty = false }, report)
| Isnum ->
let expected = Helper.[ Fixed String ] in
let report = Helper.compare_args pos expected types report in
- { result = Bool; report; pos; empty = false }
+ ({ result = Bool; pos; empty = false }, report)
| Lcase | Lcase' | Ucase | Ucase' ->
let expected = Helper.[ Fixed String ] in
let report = Helper.compare_args pos expected types report in
- { result = String; report; pos; empty = false }
+ ({ result = String; pos; empty = false }, report)
| Len ->
let expected = Helper.[ Fixed Any ] in
let report = Helper.compare_args pos expected types report in
- { result = Integer; report; pos; empty = false }
+ ({ result = Integer; pos; empty = false }, report)
| Loc ->
let expected = Helper.[ Fixed String ] in
let report = Helper.compare_args pos expected types report in
- { result = Bool; report; pos; empty = false }
+ ({ result = Bool; pos; empty = false }, report)
| Max | Max' | Min | Min' ->
let d = Helper.dyn_type () in
(* 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
let result = d Helper.Bool in
- { result; report; pos; empty = false }
+ ({ result; pos; empty = false }, report)
| Mid | Mid' ->
let expected = Helper.[ Fixed String; Variable (Fixed Integer) ] in
let report = Helper.compare_args pos expected types report in
- { result = String; report; pos; empty = false }
- | Msecscount -> { result = Integer; report; pos; empty = false }
+ ({ result = String; pos; empty = false }, report)
+ | Msecscount -> ({ result = Integer; pos; empty = false }, report)
| Rand ->
let expected = Helper.[ Variable (Fixed Integer) ] in
let report = Helper.compare_args pos expected types report in
- { result = Integer; report; pos; empty = false }
- | Replace -> { result = Integer; report; pos; empty = false }
- | Replace' -> { result = String; report; pos; empty = false }
- | Rgb -> { result = Integer; report; pos; empty = false }
+ ({ result = Integer; pos; empty = false }, report)
+ | Replace -> ({ result = Integer; pos; empty = false }, report)
+ | Replace' -> ({ result = String; pos; empty = false }, report)
+ | Rgb -> ({ result = Integer; pos; empty = false }, report)
| Qspver | Qspver' | Rnd ->
(* No arg *)
let report = Helper.compare_args pos [] types report in
- { result = Integer; report; pos; empty = false }
- | Selact -> { result = Integer; report; pos; empty = false }
- | Stattxt -> { result = Integer; report; pos; empty = false }
- | Stattxt' -> { result = String; report; pos; empty = false }
+ ({ result = Integer; pos; empty = false }, report)
+ | Selact -> ({ result = Integer; pos; empty = false }, report)
+ | Stattxt -> ({ result = Integer; pos; empty = false }, report)
+ | Stattxt' -> ({ result = String; pos; empty = false }, report)
| Str | Str' ->
let expected = Helper.[ Variable (Fixed Integer) ] in
let report = Helper.compare_args pos expected types report in
- { default with result = String; report }
- | Strcomp -> { result = Integer; report; pos; empty = false }
- | Strfind -> { result = Integer; report; pos; empty = false }
- | Strfind' -> { result = String; report; pos; empty = false }
- | Strpos -> { result = Integer; report; pos; empty = false }
- | Trim -> { result = Integer; report; pos; empty = false }
- | Trim' -> { result = String; report; pos; empty = false }
+ ({ default with result = String }, report)
+ | Strcomp -> ({ result = Integer; pos; empty = false }, report)
+ | Strfind -> ({ result = Integer; pos; empty = false }, report)
+ | Strfind' -> ({ result = String; pos; empty = false }, report)
+ | Strpos -> ({ result = Integer; pos; empty = false }, report)
+ | Trim -> ({ result = Integer; pos; empty = false }, report)
+ | Trim' -> ({ result = String; pos; empty = false }, report)
| Val ->
let expected = Helper.[ Fixed Any ] in
let report = Helper.compare_args pos expected types report in
- { result = Integer; report; pos; empty = false }
+ ({ result = Integer; pos; empty = false }, report)
(** Unary operator like [-123] or [+'Text']*)
let uoperator : pos -> T.uoperator -> repr -> repr =
fun pos operator t1 report ->
- let t = t1 report in
- let report = t.report in
+ let t, report = t1 report in
match operator with
- | Add -> t
+ | Add -> (t, report)
| Neg | No ->
let types = [ arg_of_repr t ] in
let expected = Helper.[ Fixed Integer ] in
let report = Helper.compare_args pos expected types report in
- { result = Integer; report; pos; empty = false }
+ ({ result = Integer; pos; empty = false }, report)
let boperator : pos -> T.boperator -> repr -> repr -> repr =
fun pos operator t1 t2 report ->
- let t1 = t1 report in
- let t2 = t2 t1.report in
- let report = t2.report in
+ let t1, report = t1 report in
+ let t2, report = t2 report in
let types = [ arg_of_repr t1; arg_of_repr t2 ] in
match operator with
| T.Plus ->
@@ -273,12 +260,12 @@ module Expression = struct
let expected = Helper.[ Dynamic d; Dynamic d ] in
let report = Helper.compare_args pos expected types report in
let result = d Helper.Integer in
- { result; report; pos; empty = false }
+ ({ result; pos; empty = false }, report)
| 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 }
+ ({ result = Bool; pos; empty = false }, report)
else
let d = Helper.(Dynamic (dyn_type ())) in
let expected = [ d; d ] in
@@ -286,22 +273,22 @@ module Expression = struct
Helper.compare_args ~strict:true pos expected (List.rev types)
report
in
- { result = Bool; report; pos; empty = false }
+ ({ result = Bool; pos; empty = false }, report)
| 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
- { result = Bool; report; pos; empty = false }
+ ({ result = Bool; pos; empty = false }, 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
- { result = Integer; report; pos; empty = false }
+ ({ result = Integer; pos; empty = false }, 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
- { result = Bool; report; pos; empty = false }
+ ({ result = Bool; pos; empty = false }, report)
end
module Instruction = struct
@@ -313,8 +300,9 @@ module Instruction = struct
let call : pos -> T.keywords -> expression list -> repr =
fun _pos _ expressions report ->
List.fold_left expressions ~init:report ~f:(fun report expression ->
- let result = expression report in
- result.Expression.report)
+ let result, report = expression report in
+ ignore result;
+ report)
let location : pos -> string -> repr = fun _pos _ report -> report
@@ -323,7 +311,7 @@ module Instruction = struct
(** Raw expression *)
let expression : expression -> repr =
- fun expression report -> (expression report).report
+ fun expression report -> snd (expression report)
type clause = pos * expression * repr list
@@ -331,11 +319,9 @@ module Instruction = struct
fun _pos clause ~elifs ~else_ report ->
(* Helper function *)
let fold_clause report (_pos, expr, instructions) : Report.t list =
- let result = expr report in
+ let result, report = expr report in
let report =
- Helper.compare Helper.Bool
- (Expression.arg_of_repr result)
- result.Expression.report
+ Helper.compare Helper.Bool (Expression.arg_of_repr result) report
in
List.fold_left instructions ~init:report ~f:(fun report instruction ->
instruction report)
@@ -349,23 +335,21 @@ module Instruction = struct
let act : pos -> label:expression -> repr list -> repr =
fun _pos ~label instructions report ->
- let result = label report in
+ let result, report = label report in
let report =
- Helper.compare Helper.String
- (Expression.arg_of_repr result)
- result.Expression.report
+ Helper.compare Helper.String (Expression.arg_of_repr result) report
in
List.fold_left instructions ~init:report ~f:(fun report instruction ->
instruction report)
let assign : pos -> variable -> T.assignation_operator -> expression -> repr =
fun pos variable _ expression report ->
- let right_expression = expression report in
+ let right_expression, report = expression report in
match right_expression.empty with
| true -> report
| false ->
- let op1 = Expression.arg_of_repr (Expression.ident variable report) in
- let report = right_expression.Expression.report in
+ let expr1, report = Expression.ident variable report in
+ let op1 = Expression.arg_of_repr expr1 in
let op2 = Expression.arg_of_repr right_expression in
let d = Helper.dyn_type () in