Bläddra i källkod

Updated the tests with the for...end syntax

Chimrod 5 månader sedan
förälder
incheckning
a062bfee6d
2 ändrade filer med 58 tillägg och 9 borttagningar
  1. 44 9
      lib/syntax/check.ml
  2. 14 0
      lib/syntax/locations.ml

+ 44 - 9
lib/syntax/check.ml

@@ -108,6 +108,9 @@ open StdLabels
 module Helper = struct
   type 'a expr_list = { witness : 'a Id.typeid; values : 'a list }
 
+  (** Extract a list of statements from the argements. 
+      The function return the list in reverse order.
+   *)
   let expr_i : result array list -> 'a Id.typeid -> int -> 'a expr_list =
    fun args witness i ->
     let result =
@@ -118,6 +121,19 @@ module Helper = struct
           | Some value_1 -> { values = value_1 :: values; witness })
     in
     { result with values = result.values }
+
+  let variable :
+      'a Id.typeid ->
+      int ->
+      (S.pos, result array) S.variable ->
+      (S.pos, 'a) S.variable =
+   fun typeid i { pos = var_pos; name; index } ->
+    let index_i =
+      Option.map
+        (fun expression -> Option.get (get typeid (Array.get expression i)))
+        index
+    in
+    S.{ pos = var_pos; name; index = index_i }
 end
 
 module Make (A : App) = struct
@@ -331,19 +347,12 @@ module Make (A : App) = struct
         T.assignation_operator ->
         expression ->
         t =
-     fun pos { pos = var_pos; name; index } op expression ->
+     fun pos variable op expression ->
       Array.init len ~f:(fun i ->
           let (E { module_ = (module A); instr_witness; expr'; _ }) =
             Array.get A.t i
           in
-
-          let index_i =
-            Option.map
-              (fun expression ->
-                Option.get (get expr' (Array.get expression i)))
-              index
-          in
-          let variable = S.{ pos = var_pos; name; index = index_i } in
+          let variable = Helper.variable expr' i variable in
 
           match get expr' (Array.get expression i) with
           | None -> failwith "Does not match"
@@ -400,6 +409,32 @@ module Make (A : App) = struct
           let value = A.Instruction.if_ pos clause ~elifs ~else_ in
           R { value; witness = instr_witness })
 
+    let for_ :
+        S.pos ->
+        (S.pos, expression) S.variable ->
+        start:expression ->
+        to_:expression ->
+        step:expression option ->
+        t list ->
+        t =
+     fun loc variable ~start ~to_ ~step statements ->
+      Array.init len ~f:(fun i ->
+          let (E { module_ = (module A); expr'; instr_witness; _ }) =
+            Array.get A.t i
+          in
+          let start = Option.get @@ get expr' (Array.get start i)
+          and to_ = Option.get @@ get expr' (Array.get to_ i)
+          and step = Option.bind step (fun v -> get expr' (Array.get v i))
+          and variable' = Helper.variable expr' i variable
+          and statements' =
+            List.rev (Helper.expr_i statements instr_witness i).values
+          in
+
+          let value =
+            A.Instruction.for_ loc variable' ~start ~to_ ~step statements'
+          in
+          R { value; witness = instr_witness })
+
     (** This code is almost a copy/paste from Expression.v but I did not found
         a way to factorize it. *)
     let v : t -> t' =

+ 14 - 0
lib/syntax/locations.ml

@@ -140,6 +140,20 @@ module Instruction = struct
       Expression.t' ->
       t =
    fun _ _ _ _ -> Fun.id
+
+  let for_ :
+      S.pos ->
+      (S.pos, Expression.t') S.variable ->
+      start:Expression.t' ->
+      to_:Expression.t' ->
+      step:Expression.t' option ->
+      t list ->
+      t =
+   fun _ _ ~start ~to_ ~step statements t ->
+    ignore start;
+    ignore to_;
+    ignore step;
+    List.fold_left statements ~init:t ~f:(fun t instruction -> instruction t)
 end
 
 module Location = struct