|
|
@@ -97,77 +97,131 @@ let rec flatten_blocks lst =
|
|
|
|
|
|
(* Default tree transformation
|
|
|
* (node -> node) -> node -> node *)
|
|
|
-let transform_children trav node =
|
|
|
- let trav_all nodes = List.map trav nodes in
|
|
|
+let rec traverse u ( *: ) trav node =
|
|
|
+ let trav_all nodes =
|
|
|
+ let (nodes, res) = List.split (List.map trav nodes) in
|
|
|
+ (nodes, List.fold_left ( *: ) u res)
|
|
|
+ in
|
|
|
match node with
|
|
|
| Program (decls, ann) ->
|
|
|
- Program (flatten_blocks (trav_all decls), ann)
|
|
|
+ let (decls, res_decls) = trav_all decls in
|
|
|
+ (Program (flatten_blocks decls, ann), res_decls)
|
|
|
| FunDec (ret_type, name, params, ann) ->
|
|
|
- FunDec (ret_type, name, trav_all params, ann)
|
|
|
+ let (params, res_params) = trav_all params in
|
|
|
+ (FunDec (ret_type, name, params, ann), res_params)
|
|
|
| FunDef (export, ret_type, name, params, body, ann) ->
|
|
|
- FunDef (export, ret_type, name, trav_all params, trav body, ann)
|
|
|
+ let (params, resp) = trav_all params in
|
|
|
+ let (body, resb) = trav body in
|
|
|
+ (FunDef (export, ret_type, name, params, body, ann), resp *: resb)
|
|
|
| GlobalDec (ctype, name, ann) ->
|
|
|
- GlobalDec (ctype, name, ann)
|
|
|
+ (GlobalDec (ctype, name, ann), u)
|
|
|
| GlobalDef (export, ctype, name, Some init, ann) ->
|
|
|
- GlobalDef (export, ctype, name, Some (trav init), ann)
|
|
|
+ let (init, res_init) = trav init in
|
|
|
+ (GlobalDef (export, ctype, name, Some init, ann), res_init)
|
|
|
|
|
|
| VarDecs decs ->
|
|
|
- VarDecs (trav_all decs)
|
|
|
+ let (decs, res_decs) = trav_all decs in
|
|
|
+ (VarDecs decs, res_decs)
|
|
|
| LocalFuns funs ->
|
|
|
- LocalFuns (trav_all funs)
|
|
|
+ let (funs, res_funs) = trav_all funs in
|
|
|
+ (LocalFuns funs, res_funs)
|
|
|
|
|
|
| VarDec (ctype, name, Some init, ann) ->
|
|
|
- VarDec (ctype, name, Some (trav init), ann)
|
|
|
+ let (init, res_init) = trav init in
|
|
|
+ (VarDec (ctype, name, Some init, ann), res_init)
|
|
|
| Assign (name, None, value, ann) ->
|
|
|
- Assign (name, None, trav value, ann)
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (Assign (name, None, value, ann), res_value)
|
|
|
| Assign (name, Some dims, value, ann) ->
|
|
|
- Assign (name, Some (trav_all dims), trav value, ann)
|
|
|
+ let (dims, res_dims) = trav_all dims in
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (Assign (name, Some dims, value, ann), res_dims *: res_value)
|
|
|
| VarLet (dec, None, value, ann) ->
|
|
|
- VarLet (dec, None, trav value, ann)
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (VarLet (dec, None, value, ann), res_value)
|
|
|
| VarLet (dec, Some dims, value, ann) ->
|
|
|
- VarLet (dec, Some (trav_all dims), trav value, ann)
|
|
|
+ let (dims, res_dims) = trav_all dims in
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (VarLet (dec, Some dims, value, ann), res_dims *: res_value)
|
|
|
| Return (value, ann) ->
|
|
|
- Return (trav value, ann)
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (Return (value, ann), res_value)
|
|
|
| If (cond, body, ann) ->
|
|
|
- If (trav cond, trav body, ann)
|
|
|
- | IfElse (cond, true_body, false_body, ann) ->
|
|
|
- IfElse (trav cond, trav true_body, trav false_body, ann)
|
|
|
+ let (cond, res_cond) = trav cond in
|
|
|
+ let (body, res_body) = trav body in
|
|
|
+ (If (cond, body, ann), res_cond *: res_body)
|
|
|
+ | IfElse (cond, tbody, fbody, ann) ->
|
|
|
+ let (cond, resa) = trav cond in
|
|
|
+ let (tbody, resb) = trav tbody in
|
|
|
+ let (fbody, resc) = trav fbody in
|
|
|
+ (IfElse (cond, tbody, fbody, ann), resa *: resb *: resc)
|
|
|
| While (cond, body, ann) ->
|
|
|
- While (trav cond, trav body, ann)
|
|
|
+ let (cond, resc) = trav cond in
|
|
|
+ let (body, resb) = trav body in
|
|
|
+ (While (cond, body, ann), resc *: resb)
|
|
|
| DoWhile (cond, body, ann) ->
|
|
|
- DoWhile (trav cond, trav body, ann)
|
|
|
+ let (cond, resc) = trav cond in
|
|
|
+ let (body, resb) = trav body in
|
|
|
+ (DoWhile (cond, body, ann), resc *: resb)
|
|
|
| For (counter, start, stop, step, body, ann) ->
|
|
|
- For (counter, trav start, trav stop, trav step, trav body, ann)
|
|
|
+ let (start, resa) = trav start in
|
|
|
+ let (stop, resb) = trav stop in
|
|
|
+ let (step, resc) = trav step in
|
|
|
+ let (body, resd) = trav body in
|
|
|
+ let res = resa *: resb *: resc *: resd in
|
|
|
+ (For (counter, start, stop, step, body, ann), res)
|
|
|
| Allocate (dec, dims, ann) ->
|
|
|
- Allocate (dec, trav_all dims, ann)
|
|
|
+ let (dims, res_dims) = trav_all dims in
|
|
|
+ (Allocate (dec, dims, ann), res_dims)
|
|
|
| Expr value ->
|
|
|
- Expr (trav value)
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (Expr value, res_value)
|
|
|
| Block (body) ->
|
|
|
- Block (trav_all body)
|
|
|
+ let (body, res_body) = trav_all body in
|
|
|
+ (Block body, res_body)
|
|
|
|
|
|
| Monop (op, value, ann) ->
|
|
|
- Monop (op, trav value, ann)
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (Monop (op, value, ann), res_value)
|
|
|
| Binop (op, left, right, ann) ->
|
|
|
- Binop (op, trav left, trav right, ann)
|
|
|
- | Cond (cond, true_expr, false_expr, ann) ->
|
|
|
- Cond (trav cond, trav true_expr, trav false_expr, ann)
|
|
|
+ let (left, res_left) = trav left in
|
|
|
+ let (right, res_right) = trav right in
|
|
|
+ (Binop (op, left, right, ann), res_left *: res_right)
|
|
|
+ | Cond (cond, texpr, fexpr, ann) ->
|
|
|
+ let (cond, resa) = trav cond in
|
|
|
+ let (texpr, resb) = trav texpr in
|
|
|
+ let (fexpr, resc) = trav fexpr in
|
|
|
+ (Cond (cond, texpr, fexpr, ann), resa *: resb *: resc)
|
|
|
| TypeCast (ctype, value, ann) ->
|
|
|
- TypeCast (ctype, trav value, ann)
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (TypeCast (ctype, value, ann), res_value)
|
|
|
| FunCall (name, args, ann) ->
|
|
|
- FunCall (name, trav_all args, ann)
|
|
|
+ let (args, res_args) = trav_all args in
|
|
|
+ (FunCall (name, args, ann), res_args)
|
|
|
| Arg value ->
|
|
|
- Arg (trav value)
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (Arg value, res_value)
|
|
|
|
|
|
| ArrayInit (value, dims) ->
|
|
|
- ArrayInit (trav value, dims)
|
|
|
+ let (value, res_value) = trav value in
|
|
|
+ (ArrayInit (value, dims), res_value)
|
|
|
| Var (dec, Some dims, ann) ->
|
|
|
- Var (dec, Some (trav_all dims), ann)
|
|
|
+ let (dims, res_dims) = trav_all dims in
|
|
|
+ (Var (dec, Some dims, ann), res_dims)
|
|
|
| VarUse (dec, Some dims, ann) ->
|
|
|
- VarUse (dec, Some (trav_all dims), ann)
|
|
|
+ let (dims, res_dims) = trav_all dims in
|
|
|
+ (VarUse (dec, Some dims, ann), res_dims)
|
|
|
| FunUse (dec, params, ann) ->
|
|
|
- FunUse (dec, trav_all params, ann)
|
|
|
+ let (params, res_params) = trav_all params in
|
|
|
+ (FunUse (dec, params, ann), res_params)
|
|
|
+
|
|
|
+ | _ -> (node, u)
|
|
|
+
|
|
|
+let traverse_unit visit node =
|
|
|
+ let (node, _) = traverse () (fun () () -> ()) (fun n -> (visit n, ())) node in
|
|
|
+ node
|
|
|
|
|
|
- | _ -> node
|
|
|
+let traverse_list visit = traverse [] (@) visit
|
|
|
|
|
|
let annotate a = function
|
|
|
| Program (decls, ann) ->
|