index.ml 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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 = 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")