tree.ml 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. open StdLabels
  2. let identifier = "tree"
  3. let description = "Build the AST"
  4. let is_global = false
  5. let active = ref true
  6. type context = unit
  7. let initialize = Fun.id
  8. let finalize () = []
  9. module Ast = struct
  10. type 'a literal = 'a T.literal = Text of string | Expression of 'a
  11. [@@deriving eq, show]
  12. type 'a variable = { pos : 'a; name : string; index : 'a expression option }
  13. [@@deriving eq, show]
  14. and 'a expression =
  15. | Integer of 'a * string
  16. | Literal of 'a * 'a expression literal list
  17. | Ident of 'a variable
  18. | BinaryOp of 'a * T.boperator * 'a expression * 'a expression
  19. | Op of 'a * T.uoperator * 'a expression
  20. | Function of 'a * T.function_ * 'a expression list
  21. [@@deriving eq, show]
  22. and 'a condition = 'a * 'a expression * 'a statement list
  23. and 'a statement =
  24. | If of {
  25. loc : 'a;
  26. then_ : 'a condition;
  27. elifs : 'a condition list;
  28. else_ : 'a statement list;
  29. }
  30. | Act of { loc : 'a; label : 'a expression; statements : 'a statement list }
  31. | Declaration of ('a * 'a variable * T.assignation_operator * 'a expression)
  32. | Expression of 'a expression
  33. | Comment of 'a
  34. | Call of 'a * T.keywords * 'a expression list
  35. | Location of 'a * string
  36. | For of {
  37. loc : 'a;
  38. variable : 'a variable;
  39. start : 'a expression;
  40. to_ : 'a expression;
  41. step : 'a expression option;
  42. statements : 'a statement list;
  43. }
  44. [@@deriving eq, show]
  45. end
  46. (** Default implementation for the expression *)
  47. module Expression : sig
  48. include S.Expression with type t' = S.pos Ast.expression
  49. val eq : (S.pos -> S.pos -> bool) -> t' -> t' -> bool
  50. val hash : (S.pos -> int) -> t' -> int
  51. val exists : f:(t' -> bool) -> t' -> bool
  52. end = struct
  53. type t = S.pos Ast.expression
  54. type t' = t
  55. let eq : (S.pos -> S.pos -> bool) -> t -> t -> bool = Ast.equal_expression
  56. (* Add a way to filter an expression *)
  57. let rec exists : f:(t -> bool) -> t -> bool =
  58. fun ~f -> function
  59. | BinaryOp (_, _, o1, o2) as op -> f op || exists ~f o1 || exists ~f o2
  60. | Op (_, _, expr) as op -> f op || exists ~f expr
  61. | Function (_, _, exprs) as fn -> f fn || List.exists exprs ~f:(exists ~f)
  62. | Literal (_, litts) as litt ->
  63. f litt
  64. || List.exists litts ~f:(function
  65. | T.Text _ -> false
  66. | T.Expression ex -> exists ~f ex)
  67. | Ident { index; _ } as ident -> (
  68. f ident
  69. || match index with None -> false | Some expr -> exists ~f expr)
  70. | Integer _ as int -> f int
  71. let rec hash : (S.pos -> int) -> t -> int =
  72. fun f -> function
  73. | Integer (pos, v) -> Hashtbl.hash (f pos, v)
  74. | Literal (pos, l) ->
  75. let litt = List.map ~f:(T.map_litteral ~f:(hash f)) l in
  76. Hashtbl.hash (f pos, litt)
  77. | Ident { pos; name; index } ->
  78. Hashtbl.hash (f pos, name, Option.map (hash f) index)
  79. | BinaryOp (pos, op, o1, o2) ->
  80. Hashtbl.hash (f pos, op, hash f o1, hash f o2)
  81. | Op (pos, op, o1) -> Hashtbl.hash (f pos, op, hash f o1)
  82. | Function (pos, name, args) ->
  83. Hashtbl.hash (f pos, name, List.map ~f:(hash f) args)
  84. let v : t -> t' = fun t -> t
  85. let integer : S.pos -> string -> t = fun pos i -> Ast.Integer (pos, i)
  86. let literal : S.pos -> t T.literal list -> t =
  87. fun pos l -> Ast.Literal (pos, l)
  88. let function_ : S.pos -> T.function_ -> t list -> t =
  89. fun pos name args -> Ast.Function (pos, name, args)
  90. let uoperator : S.pos -> T.uoperator -> t -> t =
  91. fun pos op expression -> Ast.Op (pos, op, expression)
  92. let boperator : S.pos -> T.boperator -> t -> t -> t =
  93. fun pos op op1 op2 ->
  94. let op1 = op1 and op2 = op2 in
  95. Ast.BinaryOp (pos, op, op1, op2)
  96. let ident : (S.pos, t) S.variable -> t =
  97. fun { pos; name; index } ->
  98. let index = Option.map (fun i -> i) index in
  99. Ast.Ident { pos; name; index }
  100. end
  101. module Instruction :
  102. S.Instruction
  103. with type t' = S.pos Ast.statement
  104. and type expression = Expression.t' = struct
  105. type t = S.pos Ast.statement
  106. type t' = t
  107. type expression = Expression.t'
  108. let v : t -> t' = fun t -> t
  109. let call : S.pos -> T.keywords -> Expression.t' list -> t =
  110. fun pos name args -> Ast.Call (pos, name, args)
  111. let location : S.pos -> string -> t =
  112. fun loc label -> Ast.Location (loc, label)
  113. let comment : S.pos -> t = fun pos -> Ast.Comment pos
  114. let expression : Expression.t' -> t = fun expr -> Ast.Expression expr
  115. let if_ :
  116. S.pos ->
  117. (Expression.t', t) S.clause ->
  118. elifs:(Expression.t', t) S.clause list ->
  119. else_:(S.pos * t list) option ->
  120. t =
  121. fun pos predicate ~elifs ~else_ ->
  122. let clause (pos, expr, repr) = (pos, expr, repr) in
  123. let elifs = List.map ~f:clause elifs
  124. and else_ =
  125. match else_ with None -> [] | Some (_, instructions) -> instructions
  126. in
  127. Ast.If { loc = pos; then_ = clause predicate; elifs; else_ }
  128. let act : S.pos -> label:Expression.t' -> t list -> t =
  129. fun pos ~label statements -> Ast.Act { loc = pos; label; statements }
  130. let assign :
  131. S.pos ->
  132. (S.pos, Expression.t') S.variable ->
  133. T.assignation_operator ->
  134. Expression.t' ->
  135. t =
  136. fun pos_loc { pos; name; index } op expr ->
  137. (*let index = Option.map (fun i -> fst @@ Expression.observe (i [])) index*)
  138. Ast.Declaration (pos_loc, { pos; name; index }, op, expr)
  139. let for_ :
  140. S.pos ->
  141. (S.pos, Expression.t') S.variable ->
  142. start:Expression.t' ->
  143. to_:Expression.t' ->
  144. step:Expression.t' option ->
  145. t list ->
  146. t =
  147. fun loc variable ~start ~to_ ~step statements ->
  148. let variable =
  149. Ast.
  150. {
  151. pos = variable.S.pos;
  152. name = variable.S.name;
  153. index = variable.S.index;
  154. }
  155. in
  156. Ast.For { loc; variable; start; to_; step; statements }
  157. end
  158. module Location = struct
  159. type t = S.pos * S.pos Ast.statement list
  160. let v _ = []
  161. let location : unit -> S.pos -> Instruction.t' list -> t =
  162. fun () pos block -> (pos, block)
  163. end