diff options
Diffstat (limited to 'lib/checks')
| -rw-r--r-- | lib/checks/check.ml | 163 | ||||
| -rw-r--r-- | lib/checks/check.mli | 64 | 
2 files changed, 72 insertions, 155 deletions
diff --git a/lib/checks/check.ml b/lib/checks/check.ml index 76d5c34..6169bb1 100644 --- a/lib/checks/check.ml +++ b/lib/checks/check.ml @@ -1,66 +1,20 @@ -module Id = Type.Id +module S = Qsp_syntax.S +module C = Qsp_syntax.Catalog  (** The the Id module, wrap a value in an existencial type with a witness      associate with. *) -type result = R : { value : 'a; witness : 'a Id.t } -> result +type result = R : { value : 'a; witness : 'a Type.Id.t } -> result -let get : type a. a Id.t -> result -> a option = +let get : type a. a Type.Id.t -> result -> a option =   fun typeid (R { value; witness }) -> -  match Id.provably_equal typeid witness with +  match Type.Id.provably_equal typeid witness with    | Some Type.Equal -> Some value    | None -> None -type t = -  | E : { -      module_ : -        (module Qsp_syntax.S.Analyzer -           with type Expression.t = 'a -            and type Expression.t' = 'b -            and type Instruction.t = 'c -            and type Instruction.t' = 'd -            and type Location.t = 'e -            and type context = 'f); -      expr_witness : 'a Id.t; -      expr' : 'b Id.t; -      instr_witness : 'c Id.t; -      instr' : 'd Id.t; -      location_witness : 'e Id.t; -      context : 'f Id.t; -    } -      -> t - -let build : -    (module Qsp_syntax.S.Analyzer -       with type Expression.t = _ -        and type Expression.t' = _ -        and type Instruction.t = _ -        and type Instruction.t' = _ -        and type Location.t = 'a -        and type context = _) -> -    'a Id.t * t = - fun module_ -> -  let expr_witness = Id.make () -  and expr' = Id.make () -  and instr_witness = Id.make () -  and instr' = Id.make () -  and location_witness = Id.make () -  and context = Id.make () in -  let t = -    E -      { -        module_; -        expr_witness; -        expr'; -        instr_witness; -        instr'; -        location_witness; -        context; -      } -  in -  (location_witness, t) - -let get_module : t -> (module Qsp_syntax.S.Analyzer) = - fun (E { module_; _ }) -> (module_ :> (module Qsp_syntax.S.Analyzer)) +type t = Qsp_syntax.Catalog.ex + +let get_module : t -> (module S.Analyzer) = + fun (E { module_; _ }) -> (module_ :> (module S.Analyzer))  module type App = sig    val t : t array @@ -69,9 +23,9 @@ end  open StdLabels  module Helper = struct -  type 'a expr_list = { witness : 'a Id.t; values : 'a list } +  type 'a expr_list = { witness : 'a Type.Id.t; values : 'a list } -  let expr_i : result array list -> 'a Id.t -> int -> 'a expr_list = +  let expr_i : result array list -> 'a Type.Id.t -> int -> 'a expr_list =     fun args witness i ->      let result =        List.fold_left args ~init:{ values = []; witness } @@ -96,7 +50,7 @@ module Make (A : App) = struct    (** Initialize each test, and keep the result in the context. *)    let initialize : unit -> context =     fun () -> -    Array.map A.t ~f:(fun (E { module_ = (module S); context; _ }) -> +    Array.map A.t ~f:(fun (C.E { module_ = (module S); context; _ }) ->          let value = S.initialize () in          R { value; witness = context }) @@ -104,7 +58,7 @@ module Make (A : App) = struct     fun context_array ->      let _, report =        Array.fold_left A.t ~init:(0, []) -        ~f:(fun (i, acc) (E { module_ = (module S); context; _ }) -> +        ~f:(fun (i, acc) (C.E { module_ = (module S); context; _ }) ->            let result = Array.get context_array i in            let local_context = Option.get (get context result) in            let reports = S.finalize local_context in @@ -115,14 +69,14 @@ module Make (A : App) = struct    (* Global variable for the whole module *)    let len = Array.length A.t -  module Expression : Qsp_syntax.S.Expression with type t' = result array = -  struct +  module Expression : S.Expression with type t' = result array = struct      type t = result array      type t' = result array -    let literal : Qsp_syntax.S.pos -> t Qsp_syntax.T.literal list -> t = +    let literal : S.pos -> t Qsp_syntax.T.literal list -> t =       fun pos values -> -      Array.mapi A.t ~f:(fun i (E { module_ = (module S); expr_witness; _ }) -> +      Array.mapi A.t +        ~f:(fun i (C.E { module_ = (module S); expr_witness; _ }) ->            (* Map every values to the Checker *)            let values' =              List.map values @@ -133,14 +87,14 @@ module Make (A : App) = struct            let value = S.Expression.literal pos values' in            R { value; witness = expr_witness }) -    let integer : Qsp_syntax.S.pos -> string -> t = +    let integer : S.pos -> string -> t =       fun pos value -> -      Array.map A.t ~f:(fun (E { module_ = (module S); expr_witness; _ }) -> +      Array.map A.t ~f:(fun (C.E { module_ = (module S); expr_witness; _ }) ->            let value = S.Expression.integer pos value in            R { value; witness = expr_witness })      (** Unary operator like [-123] or [+'Text']*) -    let uoperator : Qsp_syntax.S.pos -> Qsp_syntax.T.uoperator -> t -> t = +    let uoperator : S.pos -> Qsp_syntax.T.uoperator -> t -> t =       fun pos op values ->        (* Evaluate the nested expression *)        let results = values in @@ -156,7 +110,7 @@ module Make (A : App) = struct        *)        let results =          Array.map2 A.t results -          ~f:(fun (E { module_ = (module S); expr_witness; _ }) value -> +          ~f:(fun (C.E { module_ = (module S); expr_witness; _ }) value ->              match get expr_witness value with              | None -> failwith "Does not match"              | Some value -> @@ -168,7 +122,7 @@ module Make (A : App) = struct      (** Basically the same as uoperator, but operate over two operands instead          of a single one. *) -    let boperator : Qsp_syntax.S.pos -> Qsp_syntax.T.boperator -> t -> t -> t = +    let boperator : S.pos -> Qsp_syntax.T.boperator -> t -> t -> t =       fun pos op expr1 expr2 ->        Array.init len ~f:(fun i ->            let (E { module_ = (module S); expr_witness; _ }) = Array.get A.t i in @@ -182,7 +136,7 @@ module Make (A : App) = struct            | _ -> failwith "Does not match")      (** Call a function. The functions list is hardcoded in lib/lexer.mll *) -    let function_ : Qsp_syntax.S.pos -> Qsp_syntax.T.function_ -> t list -> t = +    let function_ : S.pos -> Qsp_syntax.T.function_ -> t list -> t =       fun pos func args ->        Array.init len ~f:(fun i ->            let (E { module_ = (module S); expr_witness; _ }) = Array.get A.t i in @@ -191,8 +145,8 @@ module Make (A : App) = struct            let value = S.Expression.function_ pos func args_i in            R { witness = expr_witness; value }) -    let ident : (Qsp_syntax.S.pos, t) Qsp_syntax.S.variable -> t = -     fun { pos : Qsp_syntax.S.pos; name : string; index : t option } -> +    let ident : (S.pos, t) S.variable -> t = +     fun { pos : S.pos; name : string; index : t option } ->        Array.init len ~f:(fun i ->            let (E { module_ = (module S); expr_witness; _ }) = Array.get A.t i in @@ -216,7 +170,8 @@ module Make (A : App) = struct       fun t ->        let result =          Array.map2 A.t t -          ~f:(fun (E { module_ = (module S); expr_witness; expr'; _ }) result -> +          ~f:(fun +              (C.E { module_ = (module S); expr_witness; expr'; _ }) result ->              match get expr_witness result with              | None -> failwith "Does not match"              | Some value -> @@ -227,29 +182,30 @@ module Make (A : App) = struct    end    module Instruction : -    Qsp_syntax.S.Instruction +    S.Instruction        with type expression = Expression.t'         and type t' = result array = struct      type expression = Expression.t'      type t = result array      type t' = result array -    let location : Qsp_syntax.S.pos -> string -> t = +    let location : S.pos -> string -> t =       fun pos label -> -      Array.map A.t ~f:(fun (E { module_ = (module S); instr_witness; _ }) -> +      Array.map A.t ~f:(fun (C.E { module_ = (module S); instr_witness; _ }) ->            let value = S.Instruction.location pos label in            R { value; witness = instr_witness }) -    let comment : Qsp_syntax.S.pos -> t = +    let comment : S.pos -> t =       fun pos -> -      Array.map A.t ~f:(fun (E { module_ = (module S); instr_witness; _ }) -> +      Array.map A.t ~f:(fun (C.E { module_ = (module S); instr_witness; _ }) ->            let value = S.Instruction.comment pos in            R { value; witness = instr_witness })      let expression : expression -> t =       fun expr ->        Array.map2 A.t expr -        ~f:(fun (E { module_ = (module S); instr_witness; expr'; _ }) result -> +        ~f:(fun +            (C.E { module_ = (module S); instr_witness; expr'; _ }) result ->            match get expr' result with            | None -> failwith "Does not match"            | Some value -> @@ -257,8 +213,7 @@ module Make (A : App) = struct                let value = S.Instruction.expression value in                R { value; witness = instr_witness }) -    let call : Qsp_syntax.S.pos -> Qsp_syntax.T.keywords -> expression list -> t -        = +    let call : S.pos -> Qsp_syntax.T.keywords -> expression list -> t =       fun pos keyword args ->        (* The arguments are given like an array of array. Each expression is           actually the list of each expression in the differents modules. *) @@ -272,7 +227,7 @@ module Make (A : App) = struct            let value = S.Instruction.call pos keyword values in            R { witness = instr_witness; value }) -    let act : Qsp_syntax.S.pos -> label:expression -> t list -> t = +    let act : S.pos -> label:expression -> t list -> t =       fun pos ~label instructions ->        Array.init len ~f:(fun i ->            let (E { module_ = (module S); instr_witness; expr'; _ }) = @@ -291,8 +246,8 @@ module Make (A : App) = struct      (* I think it’s one of the longest module I’ve ever written in OCaml… *)      let assign : -        Qsp_syntax.S.pos -> -        (Qsp_syntax.S.pos, expression) Qsp_syntax.S.variable -> +        S.pos -> +        (S.pos, expression) S.variable ->          Qsp_syntax.T.assignation_operator ->          expression ->          t = @@ -308,9 +263,7 @@ module Make (A : App) = struct                  Option.get (get expr' (Array.get expression i)))                index            in -          let variable = -            Qsp_syntax.S.{ pos = var_pos; name; index = index_i } -          in +          let variable = S.{ pos = var_pos; name; index = index_i } in            match get expr' (Array.get expression i) with            | None -> failwith "Does not match" @@ -319,13 +272,12 @@ module Make (A : App) = struct                R { value; witness = instr_witness }) -    let rebuild_clause : -        type a b. +    let rebuild_clause : type a b.          int -> -        a Id.t -> -        b Id.t -> -        Qsp_syntax.S.pos * result array * result array list -> -        (b, a) Qsp_syntax.S.clause = +        a Type.Id.t -> +        b Type.Id.t -> +        S.pos * result array * result array list -> +        (b, a) S.clause =       fun i instr_witness expr' clause ->        let pos_clause, expr_clause, ts = clause in        match get expr' (Array.get expr_clause i) with @@ -337,10 +289,10 @@ module Make (A : App) = struct            clause      let if_ : -        Qsp_syntax.S.pos -> -        (expression, t) Qsp_syntax.S.clause -> -        elifs:(expression, t) Qsp_syntax.S.clause list -> -        else_:(Qsp_syntax.S.pos * t list) option -> +        S.pos -> +        (expression, t) S.clause -> +        elifs:(expression, t) S.clause list -> +        else_:(S.pos * t list) option ->          t =       fun pos clause ~elifs ~else_ ->        (* First, apply the report for all the instructions *) @@ -367,14 +319,14 @@ module Make (A : App) = struct            let value = A.Instruction.if_ pos clause ~elifs ~else_ in            R { value; witness = instr_witness }) -    (** This code is almost a copy/paste from Expression.v but I did not found -        a way to factorize it. *) +    (** This code is almost a copy/paste from Expression.v but I did not found a +        way to factorize it. *)      let v : t -> t' =       fun t ->        let result =          Array.map2 A.t t            ~f:(fun -              (E { module_ = (module S); instr_witness; instr'; _ }) result -> +              (C.E { module_ = (module S); instr_witness; instr'; _ }) result ->              match get instr_witness result with              | None -> failwith "Does not match"              | Some value -> @@ -385,22 +337,27 @@ module Make (A : App) = struct    end    module Location : -    Qsp_syntax.S.Location +    S.Location        with type t = result array         and type instruction = Instruction.t'         and type context := context = struct      type instruction = Instruction.t'      type t = result array -    let location : context -> Qsp_syntax.S.pos -> instruction list -> t = +    let location : context -> S.pos -> instruction list -> t =       fun local_context pos args ->        ignore pos;        let result =          Array.init len ~f:(fun i ->              let (E -                  { module_ = (module A); instr'; location_witness; context; _ }) -                = +                   { +                     module_ = (module A); +                     instr'; +                     location_witness; +                     context; +                     _; +                   }) =                Array.get A.t i              in diff --git a/lib/checks/check.mli b/lib/checks/check.mli index 321b67b..8502753 100644 --- a/lib/checks/check.mli +++ b/lib/checks/check.mli @@ -1,68 +1,28 @@  (** This module is a meta-checker. It will take many checkers and aggregate -    their result together before providing an unified result.  +    their result together before providing an unified result.      The modules required to be declared before being used, using the [build]      method, and provided as an array : -    {[  -    let _, e1 = build (module …) -    let _, e2 = build (module …) -     -    module Check = Make (struct -      let t = [| e1; e2 |] -    end) -    ]} -*) +    {[ +      let _, e1 = build (module …) +      let _, e2 = build (module …) -module Id : sig -  type 'a t -  (** The type created on-the-fly. *) -end - -type t = -  | E : { -      module_ : -        (module Qsp_syntax.S.Analyzer -           with type Expression.t = 'a -            and type Expression.t' = 'b -            and type Instruction.t = 'c -            and type Instruction.t' = 'd -            and type Location.t = 'e -            and type context = 'f); -      expr_witness : 'a Id.t; -      expr' : 'b Id.t; -      instr_witness : 'c Id.t; -      instr' : 'd Id.t; -      location_witness : 'e Id.t; -      context : 'f Id.t; -    } -      -> t  (** Type of check to apply *) - -val build : -  (module Qsp_syntax.S.Analyzer -     with type Expression.t = _ -      and type Expression.t' = _ -      and type Instruction.t = _ -      and type Instruction.t' = _ -      and type Location.t = 'a -      and type context = _) -> -  'a Id.t * t -(** Build a new check from a module following S.Analyzer signature.  -ypeid  -    Return the result type which hold the final result value, and checker -    itself. *) +      module Check = Make (struct +        let t = [| e1; e2 |] +      end) +    ]} *) -val get_module : t -> (module Qsp_syntax.S.Analyzer) +val get_module : Qsp_syntax.Catalog.ex -> (module Qsp_syntax.S.Analyzer)  type result -val get : 'a Id.t -> result -> 'a option +val get : 'a Type.Id.t -> result -> 'a option  (** The method [get] can be used to get the internal value for one of the -    checker used. - *) +    checker used. *)  module Make (A : sig -  val t : t array +  val t : Qsp_syntax.Catalog.ex array  end) : sig    include Qsp_syntax.S.Analyzer with type Location.t = result array  end  | 
