desug.ml 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. open Ast
  2. open Util
  3. let rec flatten = function
  4. | [] -> []
  5. | Statements nodes :: t -> (flatten nodes) @ (flatten t)
  6. | h :: t -> h :: (flatten t)
  7. let rec var_init = function
  8. (* Split local variable initialisations in declaration and assignment *)
  9. | FunDef (export, ret_type, name, params, body) ->
  10. let move_inits body =
  11. let rec trav inits = function
  12. (* translate scalar array initialisation to ArrayScalar node,
  13. * for easy replacement later on *)
  14. | VarDec (ArrayDef (_, _) as vtype, name, Some (BoolConst _ as v)) :: t
  15. | VarDec (ArrayDef (_, _) as vtype, name, Some (FloatConst _ as v)) :: t
  16. | VarDec (ArrayDef (_, _) as vtype, name, Some (IntConst _ as v)) :: t ->
  17. trav inits (VarDec (vtype, name, Some (ArrayScalar v)) :: t)
  18. | VarDec (ctype, name, init) :: t ->
  19. (* array definition: create __allocate statement *)
  20. let alloc = match ctype with
  21. | ArrayDef (_, dims) -> [Allocate (name, dims)]
  22. | _ -> []
  23. in
  24. (* variable initialisation: create assign statement *)
  25. let stats = match init with
  26. | Some value -> alloc @ [Assign (name, value)]
  27. | None -> alloc
  28. in
  29. VarDec (ctype, name, None) :: (trav (inits @ stats) t)
  30. (* initialisations need to be placed after local functions *)
  31. | (FunDef (_, _, _, _, _) as h) :: t ->
  32. (var_init h) :: (trav inits t)
  33. (* rest of function body: recurse *)
  34. | rest -> inits @ (List.map var_init rest)
  35. in trav [] body
  36. in
  37. FunDef (export, ret_type, name, params, move_inits body)
  38. (* Move global variable initialisations to exported __init function *)
  39. | GlobalDef (export, ctype, name, Some init) ->
  40. Statements [GlobalDef (export, ctype, name, None); Assign (name, init)]
  41. | Program (decls, l) ->
  42. let decls = flatten (List.map var_init decls) in
  43. let rec trav assigns = function
  44. | [] -> (assigns, [])
  45. | (Assign (_, _) as h) :: t -> trav (assigns @ [h]) t
  46. | h :: t ->
  47. let (assigns, decls) = trav assigns t in
  48. (assigns, (h :: decls))
  49. in
  50. let (assigns, decls) = trav [] decls in
  51. (match assigns with
  52. | [] -> Program (decls, l)
  53. | assigns ->
  54. let init_func = FunDef (true, Void, "__init", [], assigns) in
  55. Program (init_func :: decls, l)
  56. )
  57. | node -> transform var_init node
  58. (*
  59. let rec array_init = function
  60. (* transform scalar assignment into nested for loops *)
  61. | Assign (name, ArrayScalar (value)) ->
  62. let rec add_loop indices = function
  63. | [] ->
  64. Assign (Deref (name, indices), value)
  65. | dim :: rest ->
  66. let counter = fresh_var "counter" in
  67. let ind = (indices @ [Var counter]) in
  68. For (counter, IntConst 0, dim, IntConst 1, add_loop ind rest)
  69. in
  70. add_loop [] dims
  71. | Assign (name, ArrayConst (dims)) -> Statements []
  72. | node -> transform array_init node
  73. *)
  74. let rec phase repr =
  75. let _ = print_endline "- Var init" in
  76. match repr with
  77. | Node (node, verbose) ->
  78. Node (var_init node, verbose)
  79. | _ -> failwith "invalid input for this phase"