aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eurm.ml46
1 files changed, 38 insertions, 8 deletions
diff --git a/src/eurm.ml b/src/eurm.ml
index 99a5d5e..0caabf0 100644
--- a/src/eurm.ml
+++ b/src/eurm.ml
@@ -37,7 +37,14 @@ 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 rec compile_stage1 eurmcmds state = 40let rec apply_transform transform_func state = function
41 | [] -> [], state
42 | cmd :: tail ->
43 let substitution, new_state = transform_func cmd
44 in let prgm_tail, end_state = apply_transform transform_func new_state tail
45 in substitution @ prgm_tail, end_state
46
47let compile_stage1 eurmcmds state =
41 let transform = function 48 let transform = function
42 | Dec(r) -> 49 | Dec(r) ->
43 let new_reg = state.max_reg + 1 50 let new_reg = state.max_reg + 1
@@ -69,15 +76,38 @@ let rec compile_stage1 eurmcmds state =
69 | LTPredicate(r1, r2, l) -> [ GTPredicate(r2, r1, l) ], state 76 | LTPredicate(r1, r2, l) -> [ GTPredicate(r2, r1, l) ], state
70 | any -> [ any ], state 77 | any -> [ any ], state
71 78
72 in match eurmcmds with 79 in apply_transform (transform) state eurmcmds
73 | [] -> [], state 80
74 | cmd :: tail -> 81let compile_stage2 eurmcmds state =
75 let substitution, new_state = transform cmd 82 let transform = function
76 in let prgm_tail, end_state = compile_stage1 tail new_state 83 | Add(r1, r2) ->
77 in substitution @ prgm_tail, end_state 84 let ctr_reg = state.max_reg + 1
85 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);
87 Inc(r1); Inc(ctr_reg); Goto(start_label); Label(end_label) ],
88 { max_reg = state.label_count + 1; label_count = state.label_count + 2 }
89
90 | GTPredicate(r1, r2, l) ->
91 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)
93 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) ],
95 { max_reg = state.label_count + 1; label_count = state.label_count + 2 }
96
97 | 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
99 and start_label = string_of_int (state.label_count + 1) and end_label = string_of_int (state.label_count + 2)
100 and error_label = string_of_int (state.label_count + 3)
101 in [ Zero(diff_reg); Copy(aux1_reg, r1); Copy(aux2_reg, r2); Label(start_label);
102 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);
104 Label(error_label); Quit; Label(end_label); Copy(r1, diff_reg) ],
105 { max_reg = state.label_count + 3; label_count = state.label_count + 3 }
106
107 | any -> [ any ], state
78 108
109 in apply_transform (transform) state eurmcmds
79 110
80let compile_stage2 eurmcmds state = eurmcmds, state
81let compile_stage3 eurmcmds state = eurmcmds, state 111let compile_stage3 eurmcmds state = eurmcmds, state
82let compile_stage4 eurmcmds state = [URMZero(0)], state 112let compile_stage4 eurmcmds state = [URMZero(0)], state
83 113