|
@@ -1,3 +1,4 @@
|
|
|
|
|
+open Printf
|
|
|
open Ast
|
|
open Ast
|
|
|
open Util
|
|
open Util
|
|
|
|
|
|
|
@@ -37,7 +38,14 @@ let rec var_init = function
|
|
|
Some (FloatConst _ as v), loc) :: t
|
|
Some (FloatConst _ as v), loc) :: t
|
|
|
| VarDec (ArrayDef _ as vtype, name,
|
|
| VarDec (ArrayDef _ as vtype, name,
|
|
|
Some (IntConst _ as v), loc) :: t ->
|
|
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 ->
|
|
| VarDec (ctype, name, init, loc) as dec :: tl ->
|
|
|
(* array definition: create __allocate statement *)
|
|
(* array definition: create __allocate statement *)
|
|
@@ -119,7 +127,7 @@ let for_to_while node =
|
|
|
|
|
|
|
|
let rec array_init = function
|
|
let rec array_init = function
|
|
|
(* Transform scalar assignment into nested for-loops *)
|
|
(* 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
|
|
let rec add_loop indices = function
|
|
|
| [] ->
|
|
| [] ->
|
|
|
Assign (name, Some indices, value, loc)
|
|
Assign (name, Some indices, value, loc)
|
|
@@ -130,9 +138,30 @@ let rec array_init = function
|
|
|
in
|
|
in
|
|
|
add_loop [] dims
|
|
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
|
|
| node -> transform_children array_init node
|
|
|
|
|
|