diff options
Diffstat (limited to 'src/eurm.ml')
-rw-r--r-- | src/eurm.ml | 46 |
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 | ||
40 | let 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 | |||
40 | let rec apply_transform transform_func state = function | 45 | let 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 | |||
116 | let 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 | ||
111 | let compile_stage3 eurmcmds state = eurmcmds, state | 126 | let compile_stage4 eurmcmds state = |
112 | let 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 | ||
114 | let urm_from_eurm eurmcmds = | 140 | let 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 |