|
|
@@ -1,5 +1,9 @@
|
|
|
+open Printf
|
|
|
open Types
|
|
|
open Util
|
|
|
+open Stringify
|
|
|
+
|
|
|
+let comline comment = InlineComment (EmptyLine, comment)
|
|
|
|
|
|
let assemble program =
|
|
|
let labcounter = ref 0 in
|
|
|
@@ -10,28 +14,30 @@ let assemble program =
|
|
|
|
|
|
let consts = Hashtbl.create 20 in
|
|
|
|
|
|
- let rec trav_args callstack localfuns node =
|
|
|
- let trav = trav_args callstack localfuns in
|
|
|
+ let rec trav_args callstack node =
|
|
|
+ let trav = trav_args callstack 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)
|
|
|
+ let rec traverse_localfuns callstack = function
|
|
|
+ | LocalFuns body -> List.concat (List.map (trav_args callstack) body)
|
|
|
+ | Block body -> List.concat (List.map (traverse_localfuns callstack) body)
|
|
|
| _ -> []
|
|
|
in
|
|
|
match node with
|
|
|
+ (* Global *)
|
|
|
| Program (decls, _) ->
|
|
|
trav_all decls
|
|
|
|
|
|
+ | GlobalDef (_, ctype, _, _, _) ->
|
|
|
+ [Global ctype]
|
|
|
+
|
|
|
| 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
|
|
|
@@ -42,29 +48,34 @@ let assemble program =
|
|
|
Label label;
|
|
|
RtnEnter (indexof node);
|
|
|
] @
|
|
|
- (trav_args callstack localfuns body) @
|
|
|
+ (trav_args callstack body) @
|
|
|
(match ret_type with Void -> [Ret Void] | _ -> []) @
|
|
|
[EmptyLine] @
|
|
|
- (traverse_localfuns body)
|
|
|
+ (traverse_localfuns callstack body)
|
|
|
+
|
|
|
+ | VarDec (ctype, name, _, _) ->
|
|
|
+ [comline (sprintf "index %d: %s %s" (indexof node) (type2str ctype) name)]
|
|
|
|
|
|
- (* Local fucntions are traversed elsewhere *)
|
|
|
| LocalFuns _ -> []
|
|
|
|
|
|
- | Block body -> trav_all body
|
|
|
+ | Block body | VarDecs body -> trav_all body
|
|
|
|
|
|
+ (* Statements *)
|
|
|
| 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]
|
|
|
+ trav value @ [InlineComment (store, node2str node)]
|
|
|
|
|
|
| Return (value, _) ->
|
|
|
- trav value @ [Ret (typeof value)]
|
|
|
+ trav value @ [InlineComment (Ret (typeof value), node2str node)]
|
|
|
|
|
|
+ (* Expressions *)
|
|
|
| Const (BoolVal _, _) ->
|
|
|
[LoadImm node]
|
|
|
+
|
|
|
| Const (value, _) ->
|
|
|
let def = if Hashtbl.mem consts value then [] else (
|
|
|
Hashtbl.add consts value true;
|
|
|
@@ -72,13 +83,35 @@ let assemble program =
|
|
|
) in
|
|
|
def @ [LoadConst (typeof node, indexof node)]
|
|
|
|
|
|
- | _ -> []
|
|
|
+ | VarUse (dec, None, _) ->
|
|
|
+ let load = match (depthof dec, depthof node) with
|
|
|
+ | (0, _) -> LoadGlob (typeof dec, indexof dec)
|
|
|
+ | (a, b) when a = b -> LoadLoc (typeof dec, indexof dec)
|
|
|
+ | (a, b) -> LoadRel (typeof dec, b - a, indexof dec)
|
|
|
+ in
|
|
|
+ [InlineComment (load, node2str node)]
|
|
|
+
|
|
|
+ | Monop (op, value, _) ->
|
|
|
+ trav value @ [Op (op, typeof node)]
|
|
|
+
|
|
|
+ | Binop (op, left, right, _) ->
|
|
|
+ trav left @ (trav right) @ [Op (op, typeof node)]
|
|
|
+
|
|
|
+ | TypeCast (ctype, value, _) ->
|
|
|
+ let vtype = typeof value in
|
|
|
+ (match (ctype, vtype) with
|
|
|
+ | (Float, Int) | (Int, Float) -> ()
|
|
|
+ | _ -> raise (NodeError (node, "invalid typecast"))
|
|
|
+ );
|
|
|
+ trav value @ [Convert (vtype, ctype)]
|
|
|
+
|
|
|
+ | _ -> [Comment ("FIXME: " ^ Stringify.node2str node)]
|
|
|
(*| _ -> raise InvalidNode*)
|
|
|
in
|
|
|
- trav_args [] (ref []) program
|
|
|
+ trav_args [] program
|
|
|
|
|
|
let rec phase input =
|
|
|
- log_line 2 "- Assembly";
|
|
|
+ log_line 1 "- Assembly";
|
|
|
match input with
|
|
|
| Ast node -> Assembly (assemble node)
|
|
|
| _ -> raise (InvalidInput "assembly")
|