index.ml 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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 - List.length params) :: 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 _ | Param _ | 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, _) when not (is_immediate_const value) ->
  41. let index =
  42. if Hashtbl.mem consts value then
  43. Hashtbl.find consts value
  44. else
  45. let index = Hashtbl.length consts in
  46. Hashtbl.add consts value index;
  47. index
  48. in
  49. annotate (Index index) node
  50. | _ -> transform_children trav node
  51. in tag (ref 0) [] program
  52. let rec strip_context = function
  53. | VarUse (dec, dims, ann) ->
  54. Var (nameof dec, optmap strip_context dims, ann)
  55. | VarLet (dec, dims, value, ann) ->
  56. Assign (nameof dec, optmap strip_context dims, strip_context value, ann)
  57. | FunUse (dec, args, ann) ->
  58. FunCall (nameof dec, List.map strip_context args, ann)
  59. | node -> transform_children strip_context node
  60. let phase = function
  61. | Ast node ->
  62. let tagged = tag_index (strip_context node) in
  63. Ast (Context.analyse_context tagged)
  64. | _ -> raise (InvalidInput "index analysis")