assemble.ml 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. open Types
  2. open Util
  3. let assemble program =
  4. let labcounter = ref 0 in
  5. let genlabel suffix =
  6. labcounter := !labcounter + 1;
  7. string_of_int !labcounter ^ "_" ^ suffix
  8. in
  9. let consts = Hashtbl.create 20 in
  10. let rec trav_args callstack localfuns node =
  11. let trav = trav_args callstack localfuns in
  12. let rec trav_all = function
  13. | [] -> []
  14. | hd :: tl -> trav hd @ (trav_all tl)
  15. in
  16. let rec traverse_localfuns = function
  17. | LocalFuns funs -> trav_all funs
  18. | Block body -> List.concat (List.map traverse_localfuns body)
  19. | _ -> []
  20. in
  21. match node with
  22. | Program (decls, _) ->
  23. trav_all decls
  24. | FunDec (ret_type, name, params, _) ->
  25. [Import (name, ret_type, List.map typeof params)]
  26. | FunDef (export, ret_type, name, params, body, _) ->
  27. localfuns := node :: !localfuns;
  28. let callstack = name :: callstack in
  29. let localfuns = ref [] in
  30. let label = String.concat "$" (List.rev callstack) in
  31. (if export then
  32. let param_types = List.map typeof params in
  33. [Export (name, ret_type, param_types, label)]
  34. else []) @
  35. [
  36. Comment ("function \"" ^ label ^ "\":");
  37. Label label;
  38. RtnEnter (indexof node);
  39. ] @
  40. (trav_args callstack localfuns body) @
  41. (match ret_type with Void -> [Ret Void] | _ -> []) @
  42. [EmptyLine] @
  43. (traverse_localfuns body)
  44. (* Local fucntions are traversed elsewhere *)
  45. | LocalFuns _ -> []
  46. | Block body -> trav_all body
  47. | VarLet (dec, None, value, _) ->
  48. let store = match (depthof dec, depthof node) with
  49. | (0, _) -> StoreGlob (typeof dec, indexof dec)
  50. | (a, b) when a = b -> StoreLoc (typeof dec, indexof dec)
  51. | (a, b) -> StoreRel (typeof dec, b - a, indexof dec)
  52. in
  53. trav value @ [store]
  54. | Return (value, _) ->
  55. trav value @ [Ret (typeof value)]
  56. | Const (BoolVal _, _) ->
  57. [LoadImm node]
  58. | Const (value, _) ->
  59. let def = if Hashtbl.mem consts value then [] else (
  60. Hashtbl.add consts value true;
  61. [ConstDef value]
  62. ) in
  63. def @ [LoadConst (typeof node, indexof node)]
  64. | _ -> []
  65. (*| _ -> raise InvalidNode*)
  66. in
  67. trav_args [] (ref []) program
  68. let rec phase input =
  69. log_line 2 "- Assembly";
  70. match input with
  71. | Ast node -> Assembly (assemble node)
  72. | _ -> raise (InvalidInput "assembly")