Browse Source

Implemented constant array initialisation

Taddeus Kroes 12 năm trước cách đây
mục cha
commit
2afacac5e5
4 tập tin đã thay đổi với 44 bổ sung10 xóa
  1. 2 1
      ast.ml
  2. 34 5
      phases/desug.ml
  3. 2 1
      stringify.ml
  4. 6 3
      util.ml

+ 2 - 1
ast.ml

@@ -46,7 +46,8 @@ and node =
     | Arg of node
 
     (* additional types for convenience in traversals *)
-    | ArrayScalar of node * ctype
+    | ArrayScalar of node
+    | ArrayInit of node * ctype
     | Cond of node * node * node * loc
     | VarLet of node * ctype * int
     | VarUse of node * ctype * int

+ 34 - 5
phases/desug.ml

@@ -1,3 +1,4 @@
+open Printf
 open Ast
 open Util
 
@@ -37,7 +38,14 @@ let rec var_init = function
                           Some (FloatConst _ as v), loc) :: t
                 | VarDec (ArrayDef _ as vtype, name,
                           Some (IntConst _   as v), loc) :: t ->
-                    trav inits (VarDec (vtype, name, Some (ArrayScalar (v, vtype)), loc) :: t)
+                    let init = Some (ArrayInit (ArrayScalar v, vtype)) in
+                    trav inits (VarDec (vtype, name, init, loc) :: t)
+
+                (* Wrap ArrayConst in ArrayInit to pass dimensions *)
+                | VarDec (ArrayDef _ as vtype, name,
+                          Some (ArrayConst _ as v), loc) :: t ->
+                    let init = Some (ArrayInit (v, vtype)) in
+                    trav inits (VarDec (vtype, name, init, loc) :: t)
 
                 | VarDec (ctype, name, init, loc) as dec :: tl ->
                     (* array definition: create __allocate statement *)
@@ -119,7 +127,7 @@ let for_to_while node =
 
 let rec array_init = function
     (* Transform scalar assignment into nested for-loops *)
-    | Assign (name, None, ArrayScalar (value, ArrayDef (_, dims)), loc) ->
+    | Assign (name, None, ArrayInit (ArrayScalar value, ArrayDef (_, dims)), loc) ->
         let rec add_loop indices = function
             | [] ->
                 Assign (name, Some indices, value, loc)
@@ -130,9 +138,30 @@ let rec array_init = function
         in
         add_loop [] dims
 
-    (* TODO *)
-    | Assign (name, None, ArrayConst (dims, _), _) ->
-        Block []
+    (* Transform array constant inisialisation into separate assign statements
+     * for all entries in the constant array *)
+    (* TODO: only allow when array dimensions are constant? *)
+    | Assign (name, None, ArrayInit (ArrayConst _ as value, ArrayDef (_, dims)), loc) ->
+        let ndims = list_size dims in
+        let rec make_assigns depth i indices = function
+            | [] -> []
+            | hd :: tl ->
+                let assigns = traverse depth (i :: indices) hd in
+                make_assigns depth (i + 1) indices tl @ assigns
+        and traverse depth indices = function
+            | ArrayConst (values, _) ->
+                make_assigns (depth + 1) 0 indices values
+            | value when depth = ndims ->
+                let indices = List.map (fun i -> IntConst (i, noloc)) indices in
+                [Assign (name, Some (List.rev indices), value, loc)]
+            | node ->
+                let msg = sprintf
+                    "dimension mismatch: expected %d nesting levels, got %d"
+                    ndims depth
+                in
+                raise (NodeError (node, msg))
+        in
+        Block (List.rev (traverse 0 [] value))
 
     | node -> transform_children array_init node
 

+ 2 - 1
stringify.ml

@@ -100,7 +100,7 @@ and node2str node =
     | IntConst (i, _) -> string_of_int i
     | FloatConst (f, _) -> string_of_float f
     | ArrayConst (dims, _) -> "[" ^ concat ", " dims ^ "]"
-    | ArrayScalar (value, _) -> "<scalar>(" ^ str value ^ ")"
+    | ArrayScalar value -> "<scalar>(" ^ str value ^ ")"
     (*| ArrayScalar (value, _) -> str value*)
     | Var (v, _) -> v
     | Deref (name, dims, _) -> name ^ (str (ArrayConst (dims, noloc)))
@@ -118,6 +118,7 @@ and node2str node =
     | FunUse (value, _, _) -> "<use>(" ^ str value ^ ")"
     *)
 
+    | ArrayInit (node, _)
     | Arg node
     | Type (node, _)
     | FunUse (node, _, _)

+ 6 - 3
util.ml

@@ -77,8 +77,10 @@ let transform_children trav node =
     | Deref (name, dims, loc) ->
         Deref (name, trav_all dims, loc)
 
-    | ArrayScalar (value, dims) ->
-        ArrayScalar (trav value, dims)
+    | ArrayInit (value, dims) ->
+        ArrayInit (trav value, dims)
+    | ArrayScalar value ->
+        ArrayScalar (trav value)
     | Type (value, ctype) ->
         Type (trav value, ctype)
     | VarLet (assign, def, depth) ->
@@ -127,7 +129,8 @@ let rec transform_all trav = function
     | TypeCast (_, _, loc)
     | FunCall (_, _, loc) -> loc
 
-    | ArrayScalar (value, _)
+    | ArrayInit (value, _)
+    | ArrayScalar value
     | Expr value
     | VarLet (value, _, _)
     | VarUse (value, _, _)