(** 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 All the elements of the syntax are represented with a dedicated function (instead of a big sum type). The module [Tree] provide an implementation which build the AST. *) type 'a repr = Report.t list -> 'a * Report.t list type pos = Lexing.position * Lexing.position (** 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 repr list (** 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 * Report.t list -> t' * Report.t list val ident : (pos, t repr) variable -> t repr (* Basic values, text, number… *) val integer : pos -> string -> t repr val literal : pos -> string -> t repr val function_ : pos -> T.function_ -> t repr list -> t repr (** Call a function. The functions list is hardcoded in lib/lexer.mll *) val uoperator : pos -> T.uoperator -> t repr -> t repr (** Unary operator like [-123] or [+'Text']*) val boperator : pos -> T.boperator -> t repr -> t repr -> t repr (** 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 * Report.t list -> t' * Report.t list type expression val call : pos -> T.keywords -> expression list -> t repr (** Call for an instruction like [GT] or [*CLR] *) val location : pos -> string -> t repr (** Label for a loop *) val comment : pos -> t repr (** Comment *) val expression : expression -> t repr (** Raw expression *) val if_ : pos -> (expression, t) clause -> elifs:(expression, t) clause list -> else_:t repr list -> t repr val act : pos -> label:expression -> t repr list -> t repr val assign : pos -> (pos, expression) variable -> T.assignation_operator -> expression -> t repr end module type Location = sig type t type instruction val location : pos -> instruction repr list -> t repr end module type Analyzer = sig module Expression : Expression module Instruction : Instruction with type expression = Expression.t' repr module Location : Location with type instruction = Instruction.t' end (** Helper module used in order to convert elements from the differents representation levels *) module Helper (E : sig type t (** Internal type used in the evaluation *) type t' (** External type used outside of the module *) val v : t * Report.t list -> t' * Report.t list end) : sig val v : E.t repr -> E.t' repr val variable : (pos, E.t repr) variable -> (pos, E.t' repr) variable (** Convert a variable from the [Expression.t] into [Expression.t'] *) end = struct let v : E.t repr -> E.t' repr = fun v report -> let value, report = v report in E.v (value, report) let variable : (pos, E.t repr) variable -> (pos, E.t' repr) variable = fun variable -> { variable with index = Option.map v variable.index } end