forked from tomhea/flip-jump
-
Notifications
You must be signed in to change notification settings - Fork 0
/
calc.fj
254 lines (204 loc) · 4.85 KB
/
calc.fj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
startup
loop:
bit.zero hex_used
bit.print 3, prompt_string
getch
remove_spaces
check_quit should_quit, before_start
should_quit:
getch
remove_spaces
line_ended finish, finish, before_start
before_start:
line_ended loop_new_line, finish, start
loop_new_line:
output '\n'
;loop
start:
insert_number a
remove_spaces
bit.mov 8, op, ascii
line_ended do_print, do_print, advance
advance:
getch
remove_spaces
insert_number b
remove_spaces
bit.zero should_finish
line_ended do_calc, mark_finish, err_loop
mark_finish:
bit.not should_finish
do_calc:
calc a, op, b
bit.if1 error, err_loop
do_print:
output '\n'
print_int a
output '\n'
bit.if should_finish, loop, finish
err_getch:
getch
err_loop:
line_ended print_err, print_err, err_getch
print_err:
bit.print 8, err_string
line_ended loop, finish, finish
finish:
output '\n'
loop
def remove_spaces @ main_loop, try2, next_ascii, end < space1, ascii, space2 {
main_loop:
bit.cmp 8, ascii, space1, try2, next_ascii, try2
try2:
bit.cmp 8, ascii, space2, end, next_ascii, end
next_ascii:
getch
;main_loop
end:
}
def insert_number x @ check1, set_minus, check2, before_hex, hex_loop, before_dec, dec_loop, minus_flag, end, after_minus < dec, hex_prefix1, hex_prefix2, t, hex, minus, ascii, error, hex_used {
bit.zero w, x
bit.zero minus_flag
bit.cmp 8, ascii, minus, check1, set_minus, check1
set_minus:
getch
bit.not minus_flag
check1:
bit.cmp 8, ascii, hex_prefix1, check2, before_hex, check2
check2:
bit.cmp 8, ascii, hex_prefix2, before_dec, before_hex, before_dec
before_hex:
getch
bit.one hex_used
hex_loop:
bit.ascii2hex error, hex, ascii
bit.if1 error, end
bit.shl w, 4, x
bit.xor 4, x, hex
getch
;hex_loop
before_dec:
bit.zero w-4, t+4*dw
dec_loop:
bit.ascii2dec error, dec, ascii
bit.if1 error, end
bit.mov 4, t, dec
bit.mul10 w, x
bit.add w, x, t
getch
;dec_loop
minus_flag:
bit
end:
bit.if0 minus_flag, after_minus
bit.neg w, x
after_minus:
bit.zero error
}
def calc a, op, b @ try_add, try_sub, try_mul, try_mul_loop, try_div, try_mod, add, sub, mul, mul_loop, div_mod, div, mod, bad, div_mod_flag, r, q, end < minus, asterisk, error, percentage, roof, slash, plus {
bit.zero error
try_add:
bit.cmp 8, op, plus, try_sub, add, try_sub
try_sub:
bit.cmp 8, op, minus, try_mul, sub, try_mul
try_mul:
bit.cmp 8, op, asterisk, try_mul_loop, mul, try_mul_loop
try_mul_loop:
bit.cmp 8, op, roof, try_div, mul_loop, try_div
try_div:
bit.zero div_mod_flag
bit.cmp 8, op, slash, try_mod, div_mod, try_mod
try_mod:
bit.not div_mod_flag
bit.cmp 8, op, percentage, bad, div_mod, bad
add:
bit.add w, a, b
;end
sub:
bit.sub w, a, b
;end
mul:
// bit.mul w, a, b
// ;end
mul_loop:
bit.mul_loop w, a, b
;end
div_mod:
// bit.idiv w, a, b, q, r
bit.idiv_loop w, a, b, q, r
bit.if div_mod_flag, div, mod
div:
bit.mov w, a, q
;end
mod:
bit.mov w, a, r
;end
bad:
bit.one error
;end
div_mod_flag:
bit
r:
bit.vec w
q:
bit.vec w
end:
}
def line_ended true, end, false @ try_end_line_n < end_line_r, end_line_n, ascii {
bit.if0 8, ascii, end
bit.cmp 8, ascii, end_line_r, try_end_line_n, true, try_end_line_n
try_end_line_n:
bit.cmp 8, ascii, end_line_n, false, true, false
}
def check_quit true, false @ try_quit1 < ascii, quit1, quit2 {
bit.cmp 8, ascii, quit2, try_quit1, true, false
try_quit1:
bit.cmp 8, ascii, quit1, false, true, false
}
// does not print new-line
def getch @ check_n, do_print, end < end_line_r, end_line_n, ascii {
bit.input ascii
bit.cmp 8, ascii, end_line_r, check_n, end, check_n
check_n:
bit.cmp 8, ascii, end_line_n, do_print, end, do_print
do_print:
bit.print ascii
end:
}
def print_int x @ print_hex, end < hex_used {
bit.if1 hex_used, print_hex
bit.print_dec_int w, x
;end
print_hex:
bit.print_hex_int w, x, 1
end:
}
op: bit.vec 8, 0
ascii: bit.vec 8, 0
error: bit 0
hex: bit.vec 4, 0
dec: bit.vec 4, 0
should_finish: bit 0
hex_used: bit 0
a: bit.vec w, 0
b: bit.vec w, 0
t: bit.vec w, 0
plus: bit.vec 8, '+'
minus: bit.vec 8, '-'
asterisk: bit.vec 8, '*'
roof: bit.vec 8, '^'
slash: bit.vec 8, '/'
percentage: bit.vec 8, '%'
hex_prefix1:bit.vec 8, 'x'
hex_prefix2:bit.vec 8, 'X'
eof: bit.vec 8, '\0'
end_line_r: bit.vec 8, '\r'
end_line_n: bit.vec 8, '\n'
space1: bit.vec 8, ' '
space2: bit.vec 8, '\t'
quit1: bit.vec 8, 'Q'
quit2: bit.vec 8, 'q'
err_string: bit.str "\nError!\n"
prompt_string: bit.str "> "
// bit.ptr_init
// bit.stack 20