aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eurm.ml46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/eurm.ml b/src/eurm.ml
index 0caabf0..2b8cc5b 100644
--- a/src/eurm.ml
+++ b/src/eurm.ml
@@ -37,6 +37,11 @@ let build_initial_state eurmcmds =
37 label_count = List.fold_left (fun acc instr -> acc + (match instr with | Label(_) -> 1 | _ -> 0)) 0 eurmcmds 37 label_count = List.fold_left (fun acc instr -> acc + (match instr with | Label(_) -> 1 | _ -> 0)) 0 eurmcmds
38 } 38 }
39 39
40let add_reg_label state new_regs new_labels = {
41 max_reg = state.max_reg + new_regs;
42 label_count = state.label_count + new_labels
43}
44
40let rec apply_transform transform_func state = function 45let rec apply_transform transform_func state = function
41 | [] -> [], state 46 | [] -> [], state
42 | cmd :: tail -> 47 | cmd :: tail ->
@@ -49,29 +54,29 @@ let compile_stage1 eurmcmds state =
49 | Dec(r) -> 54 | Dec(r) ->
50 let new_reg = state.max_reg + 1 55 let new_reg = state.max_reg + 1
51 in [ Zero(new_reg); Inc(new_reg); Sub(r, new_reg) ], 56 in [ Zero(new_reg); Inc(new_reg); Sub(r, new_reg) ],
52 { max_reg = new_reg; label_count = state.label_count } 57 add_reg_label state 1 0
53 58
54 | GEqPredicate(r1, r2, l) -> 59 | GEqPredicate(r1, r2, l) ->
55 let new_reg = state.max_reg + 1 60 let new_reg = state.max_reg + 1
56 in [ Copy(new_reg, r1); Inc(new_reg); GTPredicate(new_reg, r2, l) ], 61 in [ Copy(new_reg, r1); Inc(new_reg); GTPredicate(new_reg, r2, l) ],
57 { max_reg = new_reg; label_count = state.label_count } 62 add_reg_label state 1 0
58 63
59 | LEqPredicate(r1, r2, l) -> 64 | LEqPredicate(r1, r2, l) ->
60 let new_reg = state.max_reg + 1 65 let new_reg = state.max_reg + 1
61 in [ Copy(new_reg, r2); Inc(new_reg); GTPredicate(new_reg, r1, l) ], 66 in [ Copy(new_reg, r2); Inc(new_reg); GTPredicate(new_reg, r1, l) ],
62 { max_reg = new_reg; label_count = state.label_count } 67 add_reg_label state 1 0
63 68
64 | Mult(r1, r2) -> 69 | Mult(r1, r2) ->
65 let ctr_reg = state.max_reg + 1 and res_reg = state.max_reg + 2 70 let ctr_reg = state.max_reg + 1 and res_reg = state.max_reg + 2
66 and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2) 71 and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2)
67 in [ Zero(ctr_reg); Zero(res_reg); Label(start_label); EqPredicate(ctr_reg, r2, end_label); 72 in [ Zero(ctr_reg); Zero(res_reg); Label(start_label); EqPredicate(ctr_reg, r2, end_label);
68 Add(res_reg, r1); Inc(ctr_reg); Goto(start_label); Label(end_label) ], 73 Add(res_reg, r1); Inc(ctr_reg); Goto(start_label); Label(end_label) ],
69 { max_reg = state.max_reg + 2; label_count = state.label_count + 2} 74 add_reg_label state 2 2
70 75
71 | ZeroPredicate(r, l) -> 76 | ZeroPredicate(r, l) ->
72 let new_reg = state.max_reg + 1 77 let new_reg = state.max_reg + 1
73 in [ Zero(new_reg); EqPredicate(r, new_reg, l) ], 78 in [ Zero(new_reg); EqPredicate(r, new_reg, l) ],
74 { max_reg = new_reg; label_count = state.label_count } 79 add_reg_label state 1 0
75 80
76 | LTPredicate(r1, r2, l) -> [ GTPredicate(r2, r1, l) ], state 81 | LTPredicate(r1, r2, l) -> [ GTPredicate(r2, r1, l) ], state
77 | any -> [ any ], state 82 | any -> [ any ], state
@@ -85,14 +90,14 @@ let compile_stage2 eurmcmds state =
85 and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2) 90 and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2)
86 in [ Zero(ctr_reg); Label(start_label); EqPredicate(ctr_reg, r2, end_label); 91 in [ Zero(ctr_reg); Label(start_label); EqPredicate(ctr_reg, r2, end_label);
87 Inc(r1); Inc(ctr_reg); Goto(start_label); Label(end_label) ], 92 Inc(r1); Inc(ctr_reg); Goto(start_label); Label(end_label) ],
88 { max_reg = state.label_count + 1; label_count = state.label_count + 2 } 93 add_reg_label state 1 2
89 94
90 | GTPredicate(r1, r2, l) -> 95 | GTPredicate(r1, r2, l) ->
91 let aux_reg = state.max_reg + 1 96 let aux_reg = state.max_reg + 1
92 and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2) 97 and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2)
93 in [ Zero(aux_reg); Label(start_label); EqPredicate(aux_reg, r1, end_label); EqPredicate(aux_reg, r2, l); 98 in [ Zero(aux_reg); Label(start_label); EqPredicate(aux_reg, r1, end_label); EqPredicate(aux_reg, r2, l);
94 Inc(aux_reg); Goto(start_label); Label(end_label) ], 99 Inc(aux_reg); Goto(start_label); Label(end_label) ],
95 { max_reg = state.label_count + 1; label_count = state.label_count + 2 } 100 add_reg_label state 1 2
96 101
97 | Sub(r1, r2) -> 102 | Sub(r1, r2) ->
98 let diff_reg = state.max_reg + 1 and aux1_reg = state.max_reg + 2 and aux2_reg = state.max_reg + 3 103 let diff_reg = state.max_reg + 1 and aux1_reg = state.max_reg + 2 and aux2_reg = state.max_reg + 3
@@ -102,14 +107,35 @@ let compile_stage2 eurmcmds state =
102 EqPredicate(aux1_reg, r2, error_label); EqPredicate(aux2_reg, r1, end_label); 107 EqPredicate(aux1_reg, r2, error_label); EqPredicate(aux2_reg, r1, end_label);
103 Inc(diff_reg); Inc(aux1_reg); Inc(aux2_reg); Goto(start_label); 108 Inc(diff_reg); Inc(aux1_reg); Inc(aux2_reg); Goto(start_label);
104 Label(error_label); Quit; Label(end_label); Copy(r1, diff_reg) ], 109 Label(error_label); Quit; Label(end_label); Copy(r1, diff_reg) ],
105 { max_reg = state.label_count + 3; label_count = state.label_count + 3 } 110 add_reg_label state 3 3
111
112 | any -> [ any ], state
106 113
114 in apply_transform (transform) state eurmcmds
115
116let compile_stage3 eurmcmds state =
117 let transform = function
118 | Goto(lbl) ->
119 let dummy_reg = state.max_reg + 1
120 in [ Zero(dummy_reg); EqPredicate(dummy_reg, dummy_reg, lbl) ],
121 add_reg_label state 1 0
107 | any -> [ any ], state 122 | any -> [ any ], state
108 123
109 in apply_transform (transform) state eurmcmds 124 in apply_transform (transform) state eurmcmds
110 125
111let compile_stage3 eurmcmds state = eurmcmds, state 126let compile_stage4 eurmcmds state =
112let compile_stage4 eurmcmds state = [URMZero(0)], state 127 let label_table = Hashtbl.create 100
128 in let build_label_table =
129 List.iteri (fun lineo cmd -> match cmd with | Label(lbl) -> Hashtbl.add label_table lbl lineo | _ -> ())
130 in let transform = function
131 | Inc(r) -> [ URMSucc(r) ], state
132 | Zero(r) -> [ URMZero(r) ], state
133 | EqPredicate(r1, r2, lbl) -> [ URMJump(r1, r2, Hashtbl.find label_table lbl) ], state
134 | Label(_) ->
135 let dummy_reg = state.max_reg + 1
136 in [ URMZero(dummy_reg) ], add_reg_label state 1 0
137 | _ -> failwith "Invalid_argument"
138 in build_label_table eurmcmds; apply_transform (transform) state eurmcmds
113 139
114let urm_from_eurm eurmcmds = 140let urm_from_eurm eurmcmds =
115 let chain transform (eurmcmds, compile_state) = transform eurmcmds compile_state 141 let chain transform (eurmcmds, compile_state) = transform eurmcmds compile_state