|
@@ -26,6 +26,7 @@ let assemble program =
|
|
|
in
|
|
in
|
|
|
match node with
|
|
match node with
|
|
|
(* Global *)
|
|
(* Global *)
|
|
|
|
|
+
|
|
|
| Program (decls, _) ->
|
|
| Program (decls, _) ->
|
|
|
trav_all decls
|
|
trav_all decls
|
|
|
|
|
|
|
@@ -39,10 +40,12 @@ let assemble program =
|
|
|
|
|
|
|
|
| FunDef (export, ret_type, name, params, body, _) ->
|
|
| FunDef (export, ret_type, name, params, body, _) ->
|
|
|
let label = labelof node in
|
|
let label = labelof node in
|
|
|
- (if export then
|
|
|
|
|
|
|
+ begin
|
|
|
|
|
+ if export then
|
|
|
let param_types = List.map typeof params in
|
|
let param_types = List.map typeof params in
|
|
|
[Export (name, ret_type, param_types, label)]
|
|
[Export (name, ret_type, param_types, label)]
|
|
|
- else []) @
|
|
|
|
|
|
|
+ else []
|
|
|
|
|
+ end @
|
|
|
[Comment (sprintf "fun \"%s\" with %d local vars" label (indexof node));
|
|
[Comment (sprintf "fun \"%s\" with %d local vars" label (indexof node));
|
|
|
Label label;
|
|
Label label;
|
|
|
RtnEnter (indexof node)] @
|
|
RtnEnter (indexof node)] @
|
|
@@ -59,6 +62,7 @@ let assemble program =
|
|
|
| Block body | VarDecs body -> trav_all body
|
|
| Block body | VarDecs body -> trav_all body
|
|
|
|
|
|
|
|
(* Statements *)
|
|
(* Statements *)
|
|
|
|
|
+
|
|
|
| VarLet (dec, None, value, _) ->
|
|
| VarLet (dec, None, value, _) ->
|
|
|
let store = match (depthof dec, depthof node) with
|
|
let store = match (depthof dec, depthof node) with
|
|
|
| (0, _) -> Store (typeof dec, Glob, indexof dec)
|
|
| (0, _) -> Store (typeof dec, Glob, indexof dec)
|
|
@@ -74,7 +78,7 @@ let assemble program =
|
|
|
let endlabel = genlabel "end" in
|
|
let endlabel = genlabel "end" in
|
|
|
(trav cond) @
|
|
(trav cond) @
|
|
|
[Branch (false, endlabel);
|
|
[Branch (false, endlabel);
|
|
|
- comline ("if (" ^ (node2str cond) ^ ") {")] @
|
|
|
|
|
|
|
+ comline ("if (" ^ (node2str cond) ^ ") {")] @
|
|
|
(trav body) @
|
|
(trav body) @
|
|
|
[comline "}";
|
|
[comline "}";
|
|
|
Label endlabel]
|
|
Label endlabel]
|
|
@@ -84,10 +88,10 @@ let assemble program =
|
|
|
let endlabel = genlabel "end" in
|
|
let endlabel = genlabel "end" in
|
|
|
(trav cond) @
|
|
(trav cond) @
|
|
|
[Branch (false, elselabel);
|
|
[Branch (false, elselabel);
|
|
|
- comline ("if (" ^ (node2str cond) ^ ") {")] @
|
|
|
|
|
|
|
+ comline ("if (" ^ (node2str cond) ^ ") {")] @
|
|
|
(trav true_body) @
|
|
(trav true_body) @
|
|
|
[Jump endlabel;
|
|
[Jump endlabel;
|
|
|
- comline "} else {";
|
|
|
|
|
|
|
+ comline "} else {";
|
|
|
Label elselabel] @
|
|
Label elselabel] @
|
|
|
(trav false_body) @
|
|
(trav false_body) @
|
|
|
[comline "}";
|
|
[comline "}";
|
|
@@ -103,7 +107,7 @@ let assemble program =
|
|
|
(trav body) @
|
|
(trav body) @
|
|
|
[Jump startlabel;
|
|
[Jump startlabel;
|
|
|
Label endlabel;
|
|
Label endlabel;
|
|
|
- comline "}"]
|
|
|
|
|
|
|
+ comline "}"]
|
|
|
|
|
|
|
|
| DoWhile (cond, body, _) ->
|
|
| DoWhile (cond, body, _) ->
|
|
|
let startlabel = genlabel "dowhile" in
|
|
let startlabel = genlabel "dowhile" in
|
|
@@ -115,19 +119,20 @@ let assemble program =
|
|
|
[InlineComment (Branch (true, startlabel), com)]
|
|
[InlineComment (Branch (true, startlabel), com)]
|
|
|
|
|
|
|
|
(* Expression statement pops the disregarded expression value from the
|
|
(* Expression statement pops the disregarded expression value from the
|
|
|
- * stack, if any *)
|
|
|
|
|
|
|
+ * stack, if any *)
|
|
|
| Expr value ->
|
|
| Expr value ->
|
|
|
let pop = match typeof value with
|
|
let pop = match typeof value with
|
|
|
- | Void -> [comline (node2str node)]
|
|
|
|
|
- | ctype -> [InlineComment (Pop ctype, node2str node)]
|
|
|
|
|
|
|
+ | Void -> [comline (node2str node)]
|
|
|
|
|
+ | ctype -> [InlineComment (Pop ctype, node2str node)]
|
|
|
in
|
|
in
|
|
|
- (trav value) @ pop
|
|
|
|
|
|
|
+ trav value @ pop
|
|
|
|
|
|
|
|
(* Expressions *)
|
|
(* Expressions *)
|
|
|
- (* Immediate values are handled here, and not in the peephole optimizer,
|
|
|
|
|
- * for convenience: the indices in the constant table would be altered,
|
|
|
|
|
- * so entries cannot be removed. By this early detection (also during
|
|
|
|
|
- * index analysis), they are not added in the first place *)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ (* Immediate values are handled here, and not in the peephole optimizer, for
|
|
|
|
|
+ * convenience: the indices in the constant table would be altered, so
|
|
|
|
|
+ * entries cannot be removed. By this early detection (also during index
|
|
|
|
|
+ * analysis), they are not added in the first place *)
|
|
|
| Const (value, _) when is_immediate_const value ->
|
|
| Const (value, _) when is_immediate_const value ->
|
|
|
[InlineComment (LoadImm value, node2str node)]
|
|
[InlineComment (LoadImm value, node2str node)]
|
|
|
|
|
|
|
@@ -243,8 +248,8 @@ let assemble program =
|
|
|
* cumbersome right now... *)
|
|
* cumbersome right now... *)
|
|
|
let pairs = ref [] in
|
|
let pairs = ref [] in
|
|
|
let add_pair value index =
|
|
let add_pair value index =
|
|
|
- let com = sprintf "index %d" index in
|
|
|
|
|
- pairs := (InlineComment (ConstDef value, com), index) :: !pairs;
|
|
|
|
|
|
|
+ let com = sprintf "index %d" index in
|
|
|
|
|
+ pairs := (InlineComment (ConstDef value, com), index) :: !pairs
|
|
|
in
|
|
in
|
|
|
Hashtbl.iter add_pair consts;
|
|
Hashtbl.iter add_pair consts;
|
|
|
let cmp (_, i) (_, j) = compare i j in
|
|
let cmp (_, i) (_, j) = compare i j in
|