| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- open Types
- open Util
- let assemble program =
- let labcounter = ref 0 in
- let genlabel suffix =
- labcounter := !labcounter + 1;
- string_of_int !labcounter ^ "_" ^ suffix
- in
- let consts = Hashtbl.create 20 in
- let rec trav_args callstack localfuns node =
- let trav = trav_args callstack localfuns in
- let rec trav_all = function
- | [] -> []
- | hd :: tl -> trav hd @ (trav_all tl)
- in
- let rec traverse_localfuns = function
- | LocalFuns funs -> trav_all funs
- | Block body -> List.concat (List.map traverse_localfuns body)
- | _ -> []
- in
- match node with
- | Program (decls, _) ->
- trav_all decls
- | FunDec (ret_type, name, params, _) ->
- [Import (name, ret_type, List.map typeof params)]
- | FunDef (export, ret_type, name, params, body, _) ->
- localfuns := node :: !localfuns;
- let callstack = name :: callstack in
- let localfuns = ref [] in
- let label = String.concat "$" (List.rev callstack) in
- (if export then
- let param_types = List.map typeof params in
- [Export (name, ret_type, param_types, label)]
- else []) @
- [
- Comment ("function \"" ^ label ^ "\":");
- Label label;
- RtnEnter (indexof node);
- ] @
- (trav_args callstack localfuns body) @
- (match ret_type with Void -> [Ret Void] | _ -> []) @
- [EmptyLine] @
- (traverse_localfuns body)
- (* Local fucntions are traversed elsewhere *)
- | LocalFuns _ -> []
- | Block body -> trav_all body
- | VarLet (dec, None, value, _) ->
- let store = match (depthof dec, depthof node) with
- | (0, _) -> StoreGlob (typeof dec, indexof dec)
- | (a, b) when a = b -> StoreLoc (typeof dec, indexof dec)
- | (a, b) -> StoreRel (typeof dec, b - a, indexof dec)
- in
- trav value @ [store]
- | Return (value, _) ->
- trav value @ [Ret (typeof value)]
- | Const (BoolVal _, _) ->
- [LoadImm node]
- | Const (value, _) ->
- let def = if Hashtbl.mem consts value then [] else (
- Hashtbl.add consts value true;
- [ConstDef value]
- ) in
- def @ [LoadConst (typeof node, indexof node)]
- | _ -> []
- (*| _ -> raise InvalidNode*)
- in
- trav_args [] (ref []) program
- let rec phase input =
- log_line 2 "- Assembly";
- match input with
- | Ast node -> Assembly (assemble node)
- | _ -> raise (InvalidInput "assembly")
|