depth_analysis.ml 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. open Types
  2. open Util
  3. let tag_index program =
  4. let nglobs = ref 0 in
  5. let nimport = ref 0 in
  6. let consts = Hashtbl.create 32 in
  7. let rec trav_localfuns trav = function
  8. | LocalFuns body -> LocalFuns (List.map trav body)
  9. | node -> transform_children (trav_localfuns trav) node
  10. in
  11. let rec tag stacklen callstack node =
  12. let trav = tag stacklen callstack in
  13. match node with
  14. | GlobalDef _ ->
  15. let index = !nglobs in
  16. nglobs := !nglobs + 1;
  17. annotate (Index index) (transform_children trav node)
  18. | FunDef (export, rtype, name, params, body, ann) ->
  19. (* label name for local function is "<parent_label>$<name>" *)
  20. let callstack = name :: callstack in
  21. let label = String.concat "$" (List.rev callstack) in
  22. let stacklen = ref 0 in
  23. let trav = tag stacklen callstack in
  24. (* Traverse own function body first *)
  25. let params = List.map trav params in
  26. let body = trav body in
  27. let ann = Index !stacklen :: ann in
  28. (* Traverse local functions after the function body *)
  29. let body = trav_localfuns trav body in
  30. FunDef (export, rtype, name, params, body, LabelName label :: ann)
  31. | LocalFuns _ -> node
  32. | VarDec _ | Dim _ ->
  33. let index = !stacklen in
  34. stacklen := !stacklen + 1;
  35. annotate (Index index) (transform_children trav node)
  36. | FunDec (_, name, _, _) ->
  37. let index = !nimport in
  38. nimport := !nimport + 1;
  39. annotate (LabelName name) (annotate (Index index) node)
  40. | Const (value, _) ->
  41. let index = if Hashtbl.mem consts value then (
  42. Hashtbl.find consts value
  43. ) else (
  44. let index = Hashtbl.length consts in
  45. Hashtbl.add consts value index;
  46. index
  47. ) in
  48. annotate (Index index) node
  49. | _ -> transform_children trav node
  50. in tag (ref 0) [] program
  51. let rec strip_context = function
  52. | VarUse (dec, dims, ann) ->
  53. Var (nameof dec, optmap strip_context dims, ann)
  54. | VarLet (dec, dims, value, ann) ->
  55. Assign (nameof dec, optmap strip_context dims, strip_context value, ann)
  56. | FunUse (dec, args, ann) ->
  57. FunCall (nameof dec, List.map strip_context args, ann)
  58. | node -> transform_children strip_context node
  59. let rec phase input =
  60. log_line 1 "- Depth analysis";
  61. match input with
  62. | Ast node ->
  63. let tagged = tag_index (strip_context node) in
  64. Ast (Context_analysis.analyse_context tagged)
  65. | _ -> raise (InvalidInput "depth analysis")