diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/eurm.ml | 46 |
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 | ||
40 | let rec compile_stage1 eurmcmds state = | 40 | let 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 | |||
47 | let 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 -> | 81 | let 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 | ||
80 | let compile_stage2 eurmcmds state = eurmcmds, state | ||
81 | let compile_stage3 eurmcmds state = eurmcmds, state | 111 | let compile_stage3 eurmcmds state = eurmcmds, state |
82 | let compile_stage4 eurmcmds state = [URMZero(0)], state | 112 | let compile_stage4 eurmcmds state = [URMZero(0)], state |
83 | 113 | ||