|
@@ -144,6 +144,7 @@ module TypeBuilder = Compose.Expression (Get_type)
|
|
|
|
|
|
type t' = { result : Get_type.t Lazy.t; pos : S.pos }
|
|
|
|
|
|
+(** Evaluate the expression, and extract it’s type. *)
|
|
|
let arg_of_repr : Get_type.t Lazy.t -> S.pos -> Helper.argument_repr =
|
|
|
fun type_of pos -> { pos; t = Lazy.force type_of }
|
|
|
|
|
@@ -210,7 +211,6 @@ module TypedExpression = struct
|
|
|
let types, report =
|
|
|
List.fold_left params ~init:([], [])
|
|
|
~f:(fun (types, report) (type_of, param) ->
|
|
|
- ignore type_of;
|
|
|
let t, r = param in
|
|
|
let arg = arg_of_repr type_of t.pos in
|
|
|
(arg :: types, r @ report))
|
|
@@ -359,6 +359,10 @@ end
|
|
|
|
|
|
module Expression = TypeBuilder.Make (TypedExpression)
|
|
|
|
|
|
+let arg_of_expr : Expression.t' -> Helper.argument_repr * Report.t list =
|
|
|
+ fun (expression, report) ->
|
|
|
+ ({ pos = expression.pos; t = Lazy.force expression.result }, report)
|
|
|
+
|
|
|
module Instruction = struct
|
|
|
type t = Report.t list
|
|
|
type t' = Report.t list
|
|
@@ -470,21 +474,39 @@ module Instruction = struct
|
|
|
[ op1; op2 ] report
|
|
|
| reports -> reports @ report)
|
|
|
|
|
|
+ let ( @@ ) = List.rev_append
|
|
|
+
|
|
|
let for_ :
|
|
|
S.pos ->
|
|
|
- (S.pos, Expression.t') S.variable ->
|
|
|
- start:Expression.t' ->
|
|
|
- to_:Expression.t' ->
|
|
|
- step:Expression.t' option ->
|
|
|
+ (S.pos, expression) S.variable ->
|
|
|
+ start:expression ->
|
|
|
+ to_:expression ->
|
|
|
+ step:expression option ->
|
|
|
t list ->
|
|
|
t =
|
|
|
- fun _loc variable ~start ~to_ ~step statements ->
|
|
|
- ignore variable;
|
|
|
- ignore start;
|
|
|
- ignore to_;
|
|
|
- ignore step;
|
|
|
- (* TODO ensure all the variable are INT *)
|
|
|
- let report = [] in
|
|
|
+ fun pos variable ~start ~to_ ~step statements ->
|
|
|
+ let expected = Helper.[ Fixed Integer ] in
|
|
|
+
|
|
|
+ let variable' =
|
|
|
+ arg_of_repr (Lazy.from_val (Get_type.ident variable)) variable.pos
|
|
|
+ in
|
|
|
+
|
|
|
+ let step_report =
|
|
|
+ Option.map
|
|
|
+ (fun step ->
|
|
|
+ let step, report = arg_of_expr step in
|
|
|
+ Helper.compare_args pos expected [ step ] report)
|
|
|
+ step
|
|
|
+ |> Option.value ~default:[]
|
|
|
+ in
|
|
|
+ let start', report_start = arg_of_expr start
|
|
|
+ and to', report_to = arg_of_expr to_ in
|
|
|
+ let report =
|
|
|
+ Helper.compare_args ~strict:true pos expected [ start' ]
|
|
|
+ (step_report @@ report_start @@ report_to)
|
|
|
+ |> Helper.compare_args ~strict:true pos expected [ to' ]
|
|
|
+ |> Helper.compare_args ~strict:true pos expected [ variable' ]
|
|
|
+ in
|
|
|
List.fold_left statements ~init:report ~f:(fun acc a ->
|
|
|
let report = a in
|
|
|
(List.rev_append report) acc)
|