compose.ml 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. (** Build a module with the result from another one module *)
  2. open StdLabels
  3. (** Make a module lazy *)
  4. module Lazier (E : S.Expression) :
  5. S.Expression with type t' = E.t' Lazy.t and type t = E.t Lazy.t = struct
  6. type t = E.t Lazy.t
  7. type t' = E.t' Lazy.t
  8. let v : E.t Lazy.t -> E.t' Lazy.t = Lazy.map E.v
  9. let integer : S.pos -> string -> t = fun pos i -> lazy (E.integer pos i)
  10. let ident : (S.pos, t) S.variable -> t =
  11. fun { pos; name : string; index : t option } ->
  12. lazy (E.ident { pos; name; index = Option.map Lazy.force index })
  13. let literal : S.pos -> t T.literal list -> t =
  14. fun pos litts ->
  15. lazy
  16. (let e_litts = List.map litts ~f:(T.map_litteral ~f:Lazy.force) in
  17. E.literal pos e_litts)
  18. let function_ : S.pos -> T.function_ -> t list -> t =
  19. fun pos f e ->
  20. lazy
  21. (let e' = List.map ~f:Lazy.force e in
  22. E.function_ pos f e')
  23. let uoperator : S.pos -> T.uoperator -> t -> t =
  24. fun pos op t ->
  25. let t' = lazy (E.uoperator pos op (Lazy.force t)) in
  26. t'
  27. let boperator : S.pos -> T.boperator -> t -> t -> t =
  28. fun pos op t1 t2 ->
  29. let t' = lazy (E.boperator pos op (Lazy.force t1) (Lazy.force t2)) in
  30. t'
  31. end
  32. (** Build an expression module with the result from another expression. The
  33. signature of the fuctions is a bit different, as they all receive the
  34. result from the previous evaluated element in argument. *)
  35. module Expression (E : S.Expression) = struct
  36. module type SIG = sig
  37. type t
  38. type t'
  39. (* Override the type [t] in the definition of all the functions. The
  40. signatures differs a bit from the standard signature as they get the
  41. result from E.t in last argument *)
  42. val ident : (S.pos, E.t' Lazy.t * t) S.variable -> E.t' Lazy.t -> t
  43. val integer : S.pos -> string -> E.t' Lazy.t -> t
  44. val literal : S.pos -> (E.t' Lazy.t * t) T.literal list -> E.t' Lazy.t -> t
  45. val function_ :
  46. S.pos -> T.function_ -> (E.t' Lazy.t * t) list -> E.t' Lazy.t -> t
  47. val uoperator : S.pos -> T.uoperator -> E.t' Lazy.t * t -> E.t' Lazy.t -> t
  48. val boperator :
  49. S.pos ->
  50. T.boperator ->
  51. E.t' Lazy.t * t ->
  52. E.t' Lazy.t * t ->
  53. E.t' Lazy.t ->
  54. t
  55. val v : E.t' Lazy.t * t -> t'
  56. (** Convert from the internal representation to the external one. *)
  57. end
  58. (* Create a lazy version of the module *)
  59. module E = Lazier (E)
  60. module Make (M : SIG) : S.Expression with type t' = M.t' = struct
  61. type t = E.t * M.t
  62. type t' = M.t'
  63. let v' : E.t -> E.t' = E.v
  64. let v : t -> t' = fun (type_of, v) -> M.v (v' type_of, v)
  65. let ident : (S.pos, t) S.variable -> t =
  66. fun { pos; name : string; index : t option } ->
  67. let t' = E.ident { pos; name; index = Option.map fst index } in
  68. let index' = Option.map (fun (e, m) -> (v' e, m)) index in
  69. (t', M.ident { pos; name; index = index' } (v' t'))
  70. let integer : S.pos -> string -> t =
  71. fun pos i ->
  72. let t' = E.integer pos i in
  73. (t', M.integer pos i (v' t'))
  74. let literal : S.pos -> t T.literal list -> t =
  75. fun pos litts ->
  76. let litts' =
  77. List.map litts ~f:(T.map_litteral ~f:(fun (e, m) -> (v' e, m)))
  78. in
  79. let t' =
  80. let e_litts = List.map litts ~f:(T.map_litteral ~f:fst) in
  81. E.literal pos e_litts
  82. in
  83. (t', M.literal pos litts' (v' t'))
  84. let function_ : S.pos -> T.function_ -> t list -> t =
  85. fun pos f expressions ->
  86. let e = List.map ~f:fst expressions
  87. and expressions' = List.map ~f:(fun (e, m) -> (v' e, m)) expressions in
  88. let t' = E.function_ pos f e in
  89. (t', M.function_ pos f expressions' (v' t'))
  90. let uoperator : S.pos -> T.uoperator -> t -> t =
  91. fun pos op (t, expr) ->
  92. let t' = E.uoperator pos op t in
  93. (t', M.uoperator pos op (v' t, expr) (v' t'))
  94. let boperator : S.pos -> T.boperator -> t -> t -> t =
  95. fun pos op (t1, expr1) (t2, expr2) ->
  96. let t' = E.boperator pos op t1 t2 in
  97. (t', M.boperator pos op (v' t1, expr1) (v' t2, expr2) (v' t'))
  98. end
  99. end