index.ml 2.4 KB

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