|
@@ -1,53 +1,6 @@
|
|
|
open Ast
|
|
open Ast
|
|
|
open Util
|
|
open Util
|
|
|
|
|
|
|
|
-let rec replace_var var replacement node =
|
|
|
|
|
- let trav = (replace_var var replacement) in
|
|
|
|
|
- match node with
|
|
|
|
|
- | Var (name, loc) when name = var ->
|
|
|
|
|
- Var (replacement, loc)
|
|
|
|
|
- | For (counter, start, stop, step, body, loc) when counter = var ->
|
|
|
|
|
- For (replacement, trav start, trav stop, trav step, trav body, loc)
|
|
|
|
|
- | node ->
|
|
|
|
|
- transform_children trav node
|
|
|
|
|
-
|
|
|
|
|
-let for_to_while node =
|
|
|
|
|
- let new_vars = ref [] in
|
|
|
|
|
- let rec traverse = function
|
|
|
|
|
- (* Do not traverse into local functions (already done by var_init) *)
|
|
|
|
|
- | FunDef (_, _, _, _, _, _) as node -> node
|
|
|
|
|
-
|
|
|
|
|
- (* Transform for-loops to while-loops *)
|
|
|
|
|
- | For (counter, start, stop, step, body, loc) ->
|
|
|
|
|
- let _i = fresh_var counter in
|
|
|
|
|
- let _stop = fresh_var "stop" in
|
|
|
|
|
- let _step = fresh_var "step" in
|
|
|
|
|
- new_vars := !new_vars @ [_i; _stop; _step];
|
|
|
|
|
-
|
|
|
|
|
- let vi = Var (_i, noloc) in
|
|
|
|
|
- let vstop = Var (_stop, locof stop) in
|
|
|
|
|
- let vstep = Var (_step, locof step) in
|
|
|
|
|
- let cond = Cond (
|
|
|
|
|
- Binop (Gt, vstep, IntConst (0, noloc), noloc),
|
|
|
|
|
- Binop (Lt, vi, vstop, noloc),
|
|
|
|
|
- Binop (Gt, vi, vstop, noloc),
|
|
|
|
|
- noloc
|
|
|
|
|
- ) in
|
|
|
|
|
- Block [
|
|
|
|
|
- Assign (_i, None, start, locof start);
|
|
|
|
|
- Assign (_stop, None, stop, locof stop);
|
|
|
|
|
- Assign (_step, None, step, locof step);
|
|
|
|
|
- While (cond, traverse (Block (
|
|
|
|
|
- (* TODO: check for illegal assigments of counter in body *)
|
|
|
|
|
- block_body (replace_var counter _i body) @
|
|
|
|
|
- [Assign (_i, None, Binop (Add, vi, vstep, noloc), noloc)]
|
|
|
|
|
- )), loc);
|
|
|
|
|
- ]
|
|
|
|
|
-
|
|
|
|
|
- | node -> transform_children traverse node
|
|
|
|
|
- in
|
|
|
|
|
- (traverse node, new_vars)
|
|
|
|
|
-
|
|
|
|
|
let rec var_init = function
|
|
let rec var_init = function
|
|
|
(* Move global initialisations to __init function *)
|
|
(* Move global initialisations to __init function *)
|
|
|
| Program (decls, loc) ->
|
|
| Program (decls, loc) ->
|
|
@@ -78,13 +31,13 @@ let rec var_init = function
|
|
|
let rec trav inits node = match node with
|
|
let rec trav inits node = match node with
|
|
|
(* translate scalar array initialisation to ArrayScalar node,
|
|
(* translate scalar array initialisation to ArrayScalar node,
|
|
|
* for easy replacement later on *)
|
|
* for easy replacement later on *)
|
|
|
- | VarDec (ArrayDef (_, _) as vtype, name,
|
|
|
|
|
- Some ((BoolConst (_, l)) as v), loc) :: t
|
|
|
|
|
- | VarDec (ArrayDef (_, _) as vtype, name,
|
|
|
|
|
- Some ((FloatConst (_, l)) as v), loc) :: t
|
|
|
|
|
- | VarDec (ArrayDef (_, _) as vtype, name,
|
|
|
|
|
- Some ((IntConst (_, l)) as v), loc) :: t ->
|
|
|
|
|
- trav inits (VarDec (vtype, name, Some (ArrayScalar (v, l)), loc) :: t)
|
|
|
|
|
|
|
+ | VarDec (ArrayDef _ as vtype, name,
|
|
|
|
|
+ Some (BoolConst _ as v), loc) :: t
|
|
|
|
|
+ | VarDec (ArrayDef _ as vtype, name,
|
|
|
|
|
+ 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)
|
|
|
|
|
|
|
|
| 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 *)
|
|
@@ -109,36 +62,83 @@ let rec var_init = function
|
|
|
flatten_blocks (trav [] body)
|
|
flatten_blocks (trav [] body)
|
|
|
in
|
|
in
|
|
|
let params = flatten_blocks (List.map var_init params) in
|
|
let params = flatten_blocks (List.map var_init params) in
|
|
|
- let (body, new_vars) = for_to_while (Block (move_inits body)) in
|
|
|
|
|
- let create_vardec name = VarDec (Int, name, None, noloc) in
|
|
|
|
|
- let new_vardecs = List.map create_vardec !new_vars in
|
|
|
|
|
- let stats = new_vardecs @ (flatten_blocks (block_body body)) in
|
|
|
|
|
- FunDef (export, ret_type, name, params, Block stats, loc)
|
|
|
|
|
|
|
+ FunDef (export, ret_type, name, params, Block (move_inits body), loc)
|
|
|
|
|
|
|
|
| node -> transform_children var_init node
|
|
| node -> transform_children var_init node
|
|
|
|
|
|
|
|
-(*
|
|
|
|
|
|
|
+let rec replace_var var replacement node =
|
|
|
|
|
+ let trav = (replace_var var replacement) in
|
|
|
|
|
+ match node with
|
|
|
|
|
+ | Var (name, loc) when name = var ->
|
|
|
|
|
+ Var (replacement, loc)
|
|
|
|
|
+ | For (counter, start, stop, step, body, loc) when counter = var ->
|
|
|
|
|
+ For (replacement, trav start, trav stop, trav step, trav body, loc)
|
|
|
|
|
+ | node ->
|
|
|
|
|
+ transform_children trav node
|
|
|
|
|
+
|
|
|
|
|
+let for_to_while node =
|
|
|
|
|
+ let rec traverse new_vars = function
|
|
|
|
|
+ | FunDef (export, ret_type, name, params, body, loc) ->
|
|
|
|
|
+ let new_vars = ref [] in
|
|
|
|
|
+ let body = traverse new_vars body in
|
|
|
|
|
+ let create_vardec name = VarDec (Int, name, None, noloc) in
|
|
|
|
|
+ let new_vardecs = List.map create_vardec !new_vars in
|
|
|
|
|
+ let _body = new_vardecs @ (flatten_blocks (block_body body)) in
|
|
|
|
|
+ FunDef (export, ret_type, name, params, Block _body, loc)
|
|
|
|
|
+
|
|
|
|
|
+ (* Transform for-loops to while-loops *)
|
|
|
|
|
+ | For (counter, start, stop, step, body, loc) ->
|
|
|
|
|
+ let _i = fresh_var counter in
|
|
|
|
|
+ let _stop = fresh_var "stop" in
|
|
|
|
|
+ let _step = fresh_var "step" in
|
|
|
|
|
+ new_vars := !new_vars @ [_i; _stop; _step];
|
|
|
|
|
+
|
|
|
|
|
+ let vi = Var (_i, noloc) in
|
|
|
|
|
+ let vstop = Var (_stop, locof stop) in
|
|
|
|
|
+ let vstep = Var (_step, locof step) in
|
|
|
|
|
+ let cond = Cond (
|
|
|
|
|
+ Binop (Gt, vstep, IntConst (0, noloc), noloc),
|
|
|
|
|
+ Binop (Lt, vi, vstop, noloc),
|
|
|
|
|
+ Binop (Gt, vi, vstop, noloc),
|
|
|
|
|
+ noloc
|
|
|
|
|
+ ) in
|
|
|
|
|
+ Block [
|
|
|
|
|
+ Assign (_i, None, start, locof start);
|
|
|
|
|
+ Assign (_stop, None, stop, locof stop);
|
|
|
|
|
+ Assign (_step, None, step, locof step);
|
|
|
|
|
+ While (cond, traverse new_vars (Block (
|
|
|
|
|
+ (* TODO: check for illegal assigments of counter in body *)
|
|
|
|
|
+ block_body (replace_var counter _i body) @
|
|
|
|
|
+ [Assign (_i, None, Binop (Add, vi, vstep, noloc), noloc)]
|
|
|
|
|
+ )), loc);
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ | node -> transform_children (traverse new_vars) node
|
|
|
|
|
+ in
|
|
|
|
|
+ traverse (ref []) node
|
|
|
|
|
+
|
|
|
let rec array_init = function
|
|
let rec array_init = function
|
|
|
- (* transform scalar assignment into nested for loops *)
|
|
|
|
|
- | Assign (name, None, ArrayScalar (value), loc) ->
|
|
|
|
|
|
|
+ (* Transform scalar assignment into nested for-loops *)
|
|
|
|
|
+ | Assign (name, None, ArrayScalar (value, ArrayDef (_, dims)), loc) ->
|
|
|
let rec add_loop indices = function
|
|
let rec add_loop indices = function
|
|
|
| [] ->
|
|
| [] ->
|
|
|
- Assign (name, indices, value, loc)
|
|
|
|
|
|
|
+ Assign (name, Some indices, value, loc)
|
|
|
| dim :: rest ->
|
|
| dim :: rest ->
|
|
|
- let counter = fresh_var "counter" in
|
|
|
|
|
- let ind = (indices @ [Var counter]) in
|
|
|
|
|
- For (counter, IntConst 0, dim, IntConst 1, add_loop ind rest)
|
|
|
|
|
|
|
+ let counter = fresh_var "i" in
|
|
|
|
|
+ let body = Block [add_loop (indices @ [Var (counter, noloc)]) rest] in
|
|
|
|
|
+ For (counter, IntConst (0, noloc), dim, IntConst (1, noloc), body, noloc)
|
|
|
in
|
|
in
|
|
|
add_loop [] dims
|
|
add_loop [] dims
|
|
|
|
|
|
|
|
- | Assign (name, None, ArrayConst (dims), loc) -> Block []
|
|
|
|
|
|
|
+ (* TODO *)
|
|
|
|
|
+ | Assign (name, None, ArrayConst (dims, _), _) ->
|
|
|
|
|
+ Block []
|
|
|
|
|
|
|
|
- | node -> transform array_init node
|
|
|
|
|
-*)
|
|
|
|
|
|
|
+ | node -> transform_children array_init node
|
|
|
|
|
|
|
|
let rec phase input =
|
|
let rec phase input =
|
|
|
prerr_endline "- Desugaring";
|
|
prerr_endline "- Desugaring";
|
|
|
match input with
|
|
match input with
|
|
|
| Ast (node, args) ->
|
|
| Ast (node, args) ->
|
|
|
- Ast (var_init node, args)
|
|
|
|
|
|
|
+ Ast (for_to_while (array_init (var_init node)), args)
|
|
|
| _ -> raise (InvalidInput "desugar")
|
|
| _ -> raise (InvalidInput "desugar")
|