(** 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 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 -> t' * Report.t list val ident : (pos, t) variable -> t (* Basic values, text, number… *) val integer : pos -> string -> t val literal : pos -> string -> 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' * 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_:(pos * t repr list) option -> 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 list -> (t * Report.t list) repr end module type Analyzer = sig module Expression : Expression module Instruction : Instruction with type expression = Expression.t' * Report.t list module Location : Location with type instruction = (Instruction.t' * Report.t list) repr 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' * Report.t list end) : sig val v : E.t repr -> Report.t list -> E.t' * Report.t list (** Convert an instruction from the internal representation *) val v' : E.t -> E.t' * Report.t list (** Convert an expression from the internal representation *) val variable : (pos, E.t) variable -> (pos, Report.t list -> E.t' * Report.t list) variable val variable' : (pos, E.t) variable -> (pos, E.t' * Report.t list) variable (** Convert a variable from the [Expression.t] into [Expression.t'] *) end = struct let v : E.t repr -> Report.t list -> E.t' * Report.t list = fun v report -> let value = v report in E.v value let v' : E.t -> E.t' * Report.t list = fun v -> E.v v let variable : (pos, E.t) variable -> (pos, Report.t list -> E.t' * Report.t list) variable = fun variable -> let v' : E.t -> Report.t list -> E.t' * Report.t list = fun t report -> ignore report; E.v t in { variable with index = Option.map v' variable.index } let variable' : (pos, E.t) variable -> (pos, E.t' * Report.t list) variable = fun variable -> { variable with index = Option.map v' variable.index } end