123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- (**
- This module describe the type an analyzer must implement in order to be
- used with the parser.
- The module is divided in three modules :
- - Expression : the finest part of the QSP syntax.
- - Instruction : if/act block,
- - Location
- *)
- (** {1 Generic types used in the module } *)
- type pos = Lexing.position * Lexing.position
- (** The type pos is used to track the starting and ending position for the
- given location. *)
- type ('a, 'b) variable = { pos : 'a; name : string; index : 'b option }
- (** Describe a variable, using the name in capitalized text, and an optionnal
- index.
- If missing, the index should be considered as [0].*)
- type ('a, 'b) clause = pos * 'a * 'b list
- (** {1 Checker Signature} *)
- (** Represent the evaluation over an expression *)
- module type Expression = sig
- type t
- (** Internal type used in the evaluation *)
- type t'
- (** External type used outside of the module *)
- val v : t -> t'
- val ident : (pos, t) variable -> t
- (*
- Basic values, text, number…
- *)
- val integer : pos -> string -> t
- val literal : pos -> t T.literal list -> t
- val function_ : pos -> T.function_ -> t list -> t
- (** Call a function. The functions list is hardcoded in lib/lexer.mll *)
- val uoperator : pos -> T.uoperator -> t -> t
- (** Unary operator like [-123] or [+'Text']*)
- val boperator : pos -> T.boperator -> t -> t -> t
- (** Binary operator, for a comparaison, or an operation *)
- end
- module type Instruction = sig
- type t
- (** Internal type used in the evaluation *)
- type t'
- (** External type used outside of the module *)
- val v : t -> t'
- type expression
- val call : pos -> T.keywords -> expression list -> t
- (** Call for an instruction like [GT] or [*CLR] *)
- val location : pos -> string -> t
- (** Label for a loop *)
- val comment : pos -> t
- (** Comment *)
- val expression : expression -> t
- (** Raw expression *)
- val if_ :
- pos ->
- (expression, t) clause ->
- elifs:(expression, t) clause list ->
- else_:(pos * t list) option ->
- t
- val act : pos -> label:expression -> t list -> t
- val assign :
- pos ->
- (pos, expression) variable ->
- T.assignation_operator ->
- expression ->
- t
- val for_ :
- pos ->
- (pos, expression) variable ->
- start:expression ->
- to_:expression ->
- step:expression option ->
- t list ->
- t
- (**
- for j = 1 to 5 step var:
- stri = 1 & strmax = 3
- for i = stri to strmax:
- …
- end
- end
- *)
- end
- module type Location = sig
- type t
- type instruction
- type context
- val v : t -> Report.t list
- val location : context -> pos -> instruction list -> t
- end
- (** {1 Unified module used by the parser } *)
- module type Analyzer = sig
- val identifier : string
- (** Identifier for the module *)
- val description : string
- (** Short description*)
- val active : bool ref
- (** Is the test active or not *)
- val is_global : bool
- (** Declare the checker as global. It requires to run over the whole file and
- will be disabled if the application only check a single location.
- Also, the test will be disabled if a syntax error is reported during the
- parsing, because this tell that I haven’t been able to analyse the whole
- source code. *)
- type context
- (** Context used to keep information during the whole test *)
- val initialize : unit -> context
- (** Initialize the context before starting to parse the content *)
- module Expression : Expression
- module Instruction : Instruction with type expression := Expression.t'
- module Location :
- Location with type instruction := Instruction.t' and type context := context
- val finalize : context -> (string * Report.t) list
- end
- (** Helper module used in order to convert elements from the differents
- representation levels.
- Thoses functions are intended to be used in the menhir parser, in order to
- limit the code in the mly file.
- *)
- module Helper (E : sig
- type t
- (** Internal type used in the evaluation *)
- type t'
- (** External type used outside of the module *)
- val v : t -> t'
- end) : sig
- val variable : (pos, E.t) variable -> (pos, E.t') variable
- (** Convert a variable from the [Expression.t] into [Expression.t'] *)
- end = struct
- let variable : (pos, E.t) variable -> (pos, E.t') variable =
- fun variable -> { variable with index = Option.map E.v variable.index }
- end
|