-
Notifications
You must be signed in to change notification settings - Fork 0
/
dict.inc
583 lines (504 loc) · 8.45 KB
/
dict.inc
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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
; ( -- buf )
; loads the predefined buffer address
native 'buf', buf
push qword user_buf
jmp next
; ( buf -- len )
; reads word to buffer
native 'read', read
pop rdi
call read_word
push rdx
jmp next
; ( a -- )
; drops the topmost element from the stack
native 'drop', drop
add rsp, 8
jmp next
; ( addr -- )
; prints string
native 'prints', prints
pop rdi
call print_string
jmp next
; prints new line
native 'printnl', printnl
call print_newline
jmp next
; ( a -- )
; prints integer number
native '.', dot
pop rdi
call print_int
jmp next
; ( arg2 arg1 -- answer )
; check strings to equality
native 'compare', compare
pop rdi
pop rsi
call string_equals
push rax
jmp next
; ( a -- a a )
native 'dup', dup
push qword [rsp]
jmp next
; ( b a -- [ b + a ] )
native '+', plus
pop rdx
pop rax
add rax, rdx
push rax
jmp next
; ( b a -- [ b - a ] )
native '-', minus
pop rdx
pop rax
sub rax, rdx
push rax
jmp next
; ( b a -- [ b * a ] )
native '*', mul
pop rdx
pop rax
imul rdx
push rax
jmp next
; ( b a -- [ b / a ] )
native '/', div
pop rcx
pop rax
cqo
idiv rcx
push rax
jmp next
; ( b a -- [a < b] )
native '<', less
pop rdx
pop rax
cmp rax, rdx
setl al
movzx rax, al
push rax
jmp next
; ( a b -- b a )
; swap two cells on top of the stack
native 'swap', swap
pop rdx
pop rax
push rdx
push rax
jmp next
; print all stack elements
native '.S', show_stack
mov rcx, rsp
.loop:
cmp rcx, [stack_start]
jae next
mov rdi, [rcx]
push rcx
call print_int
call print_newline
pop rcx
add rcx, 8
jmp .loop
; ( b a -- [ b = a ] )
native '=', equals
pop rdx
pop rax
cmp rax, rdx
jne .nequals
xor rax, rax
mov rax, 1
push rax
jmp next
.nequals:
xor rax, rax
push rax
jmp next
; ( b a -- [ b mod a ] )
native "%", mod
pop rcx
pop rax
cqo
idiv rcx
push rdx
jmp next
; ( b a -- [ b & a ] )
; bitwise and
native 'and', and
pop rdx
pop rax
and rax, rdx
push rax
jmp next
; ( b a -- [ b | a ] )
; bitwise or
native 'or', or
pop rax
or [rsp], rax
jmp next
; ( a -- !a )
native 'not', not
pop rax
test rax, rax
jz .setone
xor rax, rax
push rax
jmp next
.setone:
xor rax, rax
mov rax, 1
push rax
jmp next
; ( c b a -- b a c )
native 'rot', rot
pop rax
pop rdx
pop rcx
push rdx
push rax
push rcx
jmp next
; ( -- c )
; read a single character from stdin
native 'key', key
call read_char
push rax
jmp next
; ( c -- )
; output a single character to stdout
native 'emit', emit
pop rdi
call print_char
jmp next
; ( val addr -- )
; store value by address
native '!', write
pop rax
pop rdx
mov [rax], rdx
jmp next
; ( addr -- value )
; fetch value from address
native '@', fetch
pop rax
push qword[rax]
jmp next
; ( val addr -- )
; store value by address
native 'c!', write_char
pop rax
pop rdx
mov [rax], dl
jmp next
; ( addr -- char )
; read one byte starting at addr
native 'c@', fetch_char
pop rax
movzx rax, byte [rax]
push rax
jmp next
native '>r', to_r
pop rax
rpush rax
jmp next
native 'r>', from_r
rpop rax
push rax
jmp next
native "r@", r_fetch
push qword [rstack]
jmp next
; logic or
native 'lor', lor
pop rax
pop rdx
test rax, rax
jnz .yes
push rdx
jmp next
.yes:
push rax
jmp next
; logic and
native "land", land
pop rax
pop rdx
test rax, rax
jz .no
push rdx
jmp next
.no:
push rax
jmp next
; ( user_word_addr -- dict_word_addr )
; find word in dictionary
native 'find', find
pop rdi ; rdi - user's word
call find_word
push rax
jmp next
; ( addr -- xt_addr )
; jump pointer to execution_point place
native 'cfa', cfa
pop rdi
call call_from_address
push rax
jmp next
; ( xt_addr -- )
native 'initcmd', initcmd
pop rax
mov w, rax
jmp [w]
; terminate the program
native 'bye', bye
mov rax, 60
xor rdi, rdi
syscall
native 'warn', warn
mov rdi, warning_message
call print_string
call print_newline
jmp next
; ( xt_addr -- xt_addr answer )
native 'isimmediate', isimmediate
pop rax
push rax
xor rdx, rdx
mov dl, byte[rax - 1]
push rdx
jmp next
; ( addr -- num len )
native 'parsei', parsei
pop rdi
call parse_int ; rax - number ; rdx - length of number
push rax ; save number to stack
push rdx
jmp next
; ( -- mode )
native 'pushmode', pushmode
xor eax, eax
mov rax, [mode]
push rax
jmp next
; ( -- addr )
native 'pushmode_addr', pushmode_addr
xor eax, eax
mov rax, mode
push rax
jmp next
; ( a -- )
; add element from stack to the word
native ',', comma
mov rax, [here]
pop qword [rax]
add qword [here], 8
jmp next
; ( xt_addr -- xt_addr )
native 'isbranch', isbranch
pop rax
push rax
cmp byte[rax - 1], 2
jne .continue
mov byte[was_branch], 1
.continue:
jmp next
; ( -- )
native 'unsetbranch', unsetbranch
mov byte[was_branch], 0
jmp next
; ( -- answer )
native 'wasbranch', wasbranch
xor rdx, rdx
mov dl, byte[was_branch]
push rdx
jmp next
native 'pushlit', pushlit
push xt_lit
jmp next
native 'push_lastword', push_lastword
push last_word
jmp next
; push a value immediately following this XT
native 'lit', lit
push qword [pc]
add pc, 8
jmp next
; ( xt_addr -- )
native 'saveword', saveword
pop rax
mov qword[here], rax
; add here, word_size
xor eax, eax
mov rax, here
add rax, word_size
add qword[here], rax
jmp next
; ( xt_addr -- )
native 'savenum', savenum
pop rax
mov [here], rax
; add here, word_size
xor eax, eax
mov rax, here
add rax, word_size
mov qword[here], rax
jmp next
; Initializes registers
native 'init', init
mov rstack, rstack_start
mov stack, stack_start
xor eax, eax
mov rax, [in_fd]
rpush rax
xor eax, eax
pop rax
mov [in_fd], rax
mov qword[mode], 0
mov pc, xt_run
cmp qword [stack_start], 0
je .first
mov rsp, [stack_start]
jmp next
.first:
mov [stack_start], rsp
jmp next
; ( -- buf_addr )
; load the predefined buffer address
native 'buffer', buffer
push qword input_buf
jmp next
; save PC when the colon word starts
native 'docol', docol
sub rstack, 8
mov qword [rstack], pc
add w, 8
mov pc, w
jmp next
; return from the colon word
native 'exit', exit
mov pc, [rstack]
add rstack, 8
jmp next
; ( answer -- )
; jump to a location if answer is 0
native 'branchifz', branchifz
pop rax
test rax, rax
jnz .skip
mov pc, [pc]
jmp next
.skip:
add pc, 8
jmp next
; ( -- )
; jump to a location
native 'branch', branch
mov pc, [pc]
jmp next
; ( flags name -- )
; create an entry in the dictionary
native 'create', create
; link
mov rcx, [last_word]
mov rsi, [here]
mov [rsi], rcx
mov [last_word], rsi
add rsi, 8
; name
pop rdi
push rsi
call string_copy
pop rsi
push rsi
mov rdi, rsi
call string_length
pop rsi
add rsi, rax
; flags
inc rsi ; null-terminator
pop rax
mov [rsi], al
inc rsi
mov [here], rsi
jmp next
const dp, dp
const here, [here]
const in_fd, in_fd
const state, state
const mem, user_mem
native 'comp_m', comp_m
mov rdi, cmode_message
call print_string
call print_newline
jmp next
native 'inte_m', inte_m
mov rdi, imode_message
call print_string
call print_newline
jmp next
; ( call_num a1 a2 a3 a4 a5 a6 -- new_rax new_rdx )
; execute syscall
native "syscall", syscall
pop r9
pop r8
pop r10
pop rdx
pop rsi
pop rdi
pop rax
syscall
push rax
push rdx
jmp next
; ( a -- [ a + a ] )
colon 'double', double
dq xt_dup
dq xt_plus
dq xt_exit
; ( b a -- [b>a] )
colon '>', greater
dq xt_swap
dq xt_less
dq xt_exit
; Read word from stdin and define it
colon ':', colon
.restart:
dq xt_buffer
dq xt_read
branchif0 .restart
dq xt_lit, 0 ; interpreter mode flag
dq xt_buffer
dq xt_create
dq xt_lit, 1, xt_pushmode_addr
dq xt_write
dq xt_lit, docol_impl
dq xt_comma
dq xt_exit
colon ';', semicolon, 1
dq xt_lit, 0, xt_pushmode_addr
dq xt_write
dq xt_lit, xt_exit
dq xt_comma
dq xt_exit
; ( -- xt_addr )
; read word and place its xt_address on the stack
colon "'", tick, 1
dq xt_buffer
dq xt_read
dq xt_drop
dq xt_buffer
dq xt_find, xt_dup
branchif0 .no_such_word
dq xt_cfa
dq xt_pushmode
branchif0 .interpret
dq xt_lit, xt_lit
dq xt_comma
dq xt_comma
.interpret:
dq xt_exit
.no_such_word:
dq xt_warn
dq xt_exit