diff options
Diffstat (limited to 'src/eurm.ml')
-rw-r--r-- | src/eurm.ml | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/src/eurm.ml b/src/eurm.ml index cc81aef..5cb487b 100644 --- a/src/eurm.ml +++ b/src/eurm.ml | |||
@@ -34,15 +34,16 @@ let build_initial_state eurmcmds = | |||
34 | | EqPredicate(r1, r2, _) | GEqPredicate(r1, r2, _) | GTPredicate(r1, r2, _) | 34 | | EqPredicate(r1, r2, _) | GEqPredicate(r1, r2, _) | GTPredicate(r1, r2, _) |
35 | | LEqPredicate(r1, r2, _) | LTPredicate(r1, r2, _) -> max r1 r2 | 35 | | LEqPredicate(r1, r2, _) | LTPredicate(r1, r2, _) -> max r1 r2 |
36 | | _ -> 0 | 36 | | _ -> 0 |
37 | in { | 37 | in |
38 | max_reg = List.fold_left (fun acc instr -> max acc (max_reg_of_instr instr)) 0 eurmcmds; | 38 | { max_reg = List.fold_left (fun acc instr -> max acc (max_reg_of_instr instr)) 0 eurmcmds; |
39 | label_count = List.fold_left (fun acc instr -> acc + (match instr with | Label(_) -> 1 | _ -> 0)) 0 eurmcmds | 39 | label_count = List.fold_left (fun acc instr -> acc + (match instr with | Label(_) -> 1 | _ -> 0)) 0 eurmcmds } |
40 | } | ||
41 | 40 | ||
42 | let add_reg_label state new_regs new_labels = { | 41 | let add_reg_label state new_regs new_labels = |
43 | max_reg = state.max_reg + new_regs; | 42 | { max_reg = state.max_reg + new_regs; |
44 | label_count = state.label_count + new_labels | 43 | label_count = state.label_count + new_labels } |
45 | } | 44 | |
45 | let make_reg state offset = state.max_reg + offset | ||
46 | let make_label state offset = string_of_int (state.label_count + offset) | ||
46 | 47 | ||
47 | let rec apply_transform transform_func state = function | 48 | let rec apply_transform transform_func state = function |
48 | | [] -> [], state | 49 | | [] -> [], state |
@@ -54,29 +55,29 @@ let rec apply_transform transform_func state = function | |||
54 | let compile_stage1 eurmcmds state = | 55 | let compile_stage1 eurmcmds state = |
55 | let transform state = function | 56 | let transform state = function |
56 | | Dec(r) -> | 57 | | Dec(r) -> |
57 | let new_reg = state.max_reg + 1 | 58 | let new_reg = make_reg state 1 |
58 | in [ Zero(new_reg); Inc(new_reg); Sub(r, new_reg) ], | 59 | in [ Zero(new_reg); Inc(new_reg); Sub(r, new_reg) ], |
59 | add_reg_label state 1 0 | 60 | add_reg_label state 1 0 |
60 | 61 | ||
61 | | GEqPredicate(r1, r2, l) -> | 62 | | GEqPredicate(r1, r2, l) -> |
62 | let new_reg = state.max_reg + 1 | 63 | let new_reg = make_reg state 1 |
63 | in [ Copy(new_reg, r1); Inc(new_reg); GTPredicate(new_reg, r2, l) ], | 64 | in [ Copy(new_reg, r1); Inc(new_reg); GTPredicate(new_reg, r2, l) ], |
64 | add_reg_label state 1 0 | 65 | add_reg_label state 1 0 |
65 | 66 | ||
66 | | LEqPredicate(r1, r2, l) -> | 67 | | LEqPredicate(r1, r2, l) -> |
67 | let new_reg = state.max_reg + 1 | 68 | let new_reg = make_reg state 1 |
68 | in [ Copy(new_reg, r2); Inc(new_reg); GTPredicate(new_reg, r1, l) ], | 69 | in [ Copy(new_reg, r2); Inc(new_reg); GTPredicate(new_reg, r1, l) ], |
69 | add_reg_label state 1 0 | 70 | add_reg_label state 1 0 |
70 | 71 | ||
71 | | Mult(r1, r2) -> | 72 | | Mult(r1, r2) -> |
72 | let ctr_reg = state.max_reg + 1 and res_reg = state.max_reg + 2 | 73 | let ctr_reg = make_reg state 1 and res_reg = make_reg state 2 |
73 | and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2) | 74 | and start_label = make_label state 1 and end_label = make_label state 2 |
74 | in [ Zero(ctr_reg); Zero(res_reg); Label(start_label); EqPredicate(ctr_reg, r2, end_label); | 75 | in [ Zero(ctr_reg); Zero(res_reg); Label(start_label); EqPredicate(ctr_reg, r2, end_label); |
75 | Add(res_reg, r1); Inc(ctr_reg); Goto(start_label); Label(end_label); Copy(r1, res_reg) ], | 76 | Add(res_reg, r1); Inc(ctr_reg); Goto(start_label); Label(end_label); Copy(r1, res_reg) ], |
76 | add_reg_label state 2 2 | 77 | add_reg_label state 2 2 |
77 | 78 | ||
78 | | ZeroPredicate(r, l) -> | 79 | | ZeroPredicate(r, l) -> |
79 | let new_reg = state.max_reg + 1 | 80 | let new_reg = make_reg state 1 |
80 | in [ Zero(new_reg); EqPredicate(r, new_reg, l) ], | 81 | in [ Zero(new_reg); EqPredicate(r, new_reg, l) ], |
81 | add_reg_label state 1 0 | 82 | add_reg_label state 1 0 |
82 | 83 | ||
@@ -88,23 +89,23 @@ let compile_stage1 eurmcmds state = | |||
88 | let compile_stage2 eurmcmds state = | 89 | let compile_stage2 eurmcmds state = |
89 | let transform state = function | 90 | let transform state = function |
90 | | Add(r1, r2) -> | 91 | | Add(r1, r2) -> |
91 | let ctr_reg = state.max_reg + 1 | 92 | let ctr_reg = make_reg state 1 |
92 | and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2) | 93 | and start_label = make_label state 1 and end_label = make_label state 2 |
93 | in [ Zero(ctr_reg); Label(start_label); EqPredicate(ctr_reg, r2, end_label); | 94 | in [ Zero(ctr_reg); Label(start_label); EqPredicate(ctr_reg, r2, end_label); |
94 | Inc(r1); Inc(ctr_reg); Goto(start_label); Label(end_label) ], | 95 | Inc(r1); Inc(ctr_reg); Goto(start_label); Label(end_label) ], |
95 | add_reg_label state 1 2 | 96 | add_reg_label state 1 2 |
96 | 97 | ||
97 | | GTPredicate(r1, r2, l) -> | 98 | | GTPredicate(r1, r2, l) -> |
98 | let aux_reg = state.max_reg + 1 | 99 | let aux_reg = make_reg state 1 |
99 | and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2) | 100 | and start_label = make_label state 1 and end_label = make_label state 2 |
100 | in [ Zero(aux_reg); Label(start_label); EqPredicate(aux_reg, r1, end_label); EqPredicate(aux_reg, r2, l); | 101 | in [ Zero(aux_reg); Label(start_label); EqPredicate(aux_reg, r1, end_label); EqPredicate(aux_reg, r2, l); |
101 | Inc(aux_reg); Goto(start_label); Label(end_label) ], | 102 | Inc(aux_reg); Goto(start_label); Label(end_label) ], |
102 | add_reg_label state 1 2 | 103 | add_reg_label state 1 2 |
103 | 104 | ||
104 | | Sub(r1, r2) -> | 105 | | Sub(r1, r2) -> |
105 | let diff_reg = state.max_reg + 1 and aux1_reg = state.max_reg + 2 and aux2_reg = state.max_reg + 3 | 106 | let diff_reg = make_reg state 1 and aux1_reg = make_reg state 2 and aux2_reg = make_reg state 3 |
106 | and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2) | 107 | and start_label = make_label state 1 and end_label = make_label state 2 |
107 | and error_label = string_of_int (state.label_count + 3) | 108 | and error_label = make_label state 3 |
108 | in [ Zero(diff_reg); Copy(aux1_reg, r1); Copy(aux2_reg, r2); Label(start_label); | 109 | in [ Zero(diff_reg); Copy(aux1_reg, r1); Copy(aux2_reg, r2); Label(start_label); |
109 | EqPredicate(aux1_reg, r2, error_label); EqPredicate(aux2_reg, r1, end_label); | 110 | EqPredicate(aux1_reg, r2, error_label); EqPredicate(aux2_reg, r1, end_label); |
110 | Inc(diff_reg); Inc(aux1_reg); Inc(aux2_reg); Goto(start_label); | 111 | Inc(diff_reg); Inc(aux1_reg); Inc(aux2_reg); Goto(start_label); |
@@ -119,7 +120,7 @@ let compile_stage2 eurmcmds state = | |||
119 | let compile_stage3 eurmcmds state = | 120 | let compile_stage3 eurmcmds state = |
120 | let transform state = function | 121 | let transform state = function |
121 | | Goto(lbl) -> | 122 | | Goto(lbl) -> |
122 | let dummy_reg = state.max_reg + 1 | 123 | let dummy_reg = make_reg state 1 |
123 | in [ Zero(dummy_reg); EqPredicate(dummy_reg, dummy_reg, lbl) ], | 124 | in [ Zero(dummy_reg); EqPredicate(dummy_reg, dummy_reg, lbl) ], |
124 | add_reg_label state 1 0 | 125 | add_reg_label state 1 0 |
125 | | any -> [ any ], state | 126 | | any -> [ any ], state |
@@ -131,14 +132,14 @@ let compile_stage4 eurmcmds state = | |||
131 | in let build_label_table = | 132 | in let build_label_table = |
132 | List.iteri (fun lineo cmd -> match cmd with | Label(lbl) -> Hashtbl.add label_table lbl lineo | _ -> ()) | 133 | List.iteri (fun lineo cmd -> match cmd with | Label(lbl) -> Hashtbl.add label_table lbl lineo | _ -> ()) |
133 | in let transform state = function | 134 | in let transform state = function |
134 | | Inc(r) -> [ URMSucc(r) ], state | 135 | | Inc(r) -> [ URMSucc(r) ], state |
135 | | Zero(r) -> [ URMZero(r) ], state | 136 | | Zero(r) -> [ URMZero(r) ], state |
136 | | Copy(r1, r2) -> [ URMCopy(r1, r2) ], state | 137 | | Copy(r1, r2) -> [ URMCopy(r1, r2) ], state |
137 | | EqPredicate(r1, r2, lbl) -> [ URMJump(r1, r2, Hashtbl.find label_table lbl) ], state | 138 | | EqPredicate(r1, r2, lbl) -> [ URMJump(r1, r2, Hashtbl.find label_table lbl) ], state |
138 | | Label(_) -> | 139 | | Label(_) -> |
139 | let dummy_reg = state.max_reg + 1 | 140 | let dummy_reg = make_reg state 1 |
140 | in [ URMZero(dummy_reg) ], add_reg_label state 1 0 | 141 | in [ URMZero(dummy_reg) ], add_reg_label state 1 0 |
141 | | _ -> failwith "Invalid_argument" | 142 | | _ -> failwith "Invalid_argument" |
142 | in build_label_table eurmcmds; apply_transform (transform) state eurmcmds | 143 | in build_label_table eurmcmds; apply_transform (transform) state eurmcmds |
143 | 144 | ||
144 | let urm_from_eurm eurmcmds = | 145 | let urm_from_eurm eurmcmds = |