1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
(**
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].*)
(** 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 *)
type clause = pos * expression * t repr list
val if_ : pos -> clause -> elifs: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 repr
type instruction
val location : pos -> instruction list -> 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' repr
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
|