forked from Firemoon777/forth-interpreter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
interpreter.asm
146 lines (129 loc) · 2.58 KB
/
interpreter.asm
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
%define pc r15
%define w r14
%define rstack r13
%define here rbx
%include 'lib.inc'
%include 'macro.asm'
%include 'dict.asm'
section .data
program_stub: dq 0
xt_interpreter: dq .interpreter
.interpreter: dq interpreter_loop
xt_compiler: dq .compiler
.compiler: dq compiler_loop
undefined: db 'Word is undefined', 10, 0
underflow: db 'Stack underflow exception', 10, 0
interpreter_msg db 'forth > ', 0
compiler_msg db 'Switch to compiler mode', 10, 0
section .bss
retstack: resq 65536
userstack: resq 65536
dictionary resq 65536
stackHead: resq 1
ustackHead: resq 1
state: resq 1
branch: resq 1
section .text
global _start
_start:
; Инициализация интерпретатора
mov [stackHead], rsp
mov rstack, retstack + 65536*word_size
mov qword[ustackHead], userstack + 65536*word_size
mov here, dictionary
mov pc, xt_interpreter
jmp next
; Цикл интерпретатора
interpreter_loop:
mov al, byte[state]
test al, al
jnz compiler_loop
mov rdi, interpreter_msg
call print_string
call read_word
mov rdi, rax
call find_word
cmp rax, branch
je unknown
test rax, rax
jnz execute
call parse_int
test rdx, rdx
jz unknown
push rax
jmp interpreter_loop
; Цикл компилятора
compiler_loop:
;mov rdi, compiler_msg
;call print_string
mov al, byte[state]
test al, al
jz interpreter_loop
call read_word
mov rdi, rax
call find_word
test rax, rax
jz .check_number
mov rdi, rax
call cfa
mov dil, byte[rax-1]
and dil, 0x01
test dil, dil
jz .compile ; Прыжок, если нужна компиляция
mov w, rax
mov [program_stub], rax
mov pc, program_stub
jmp next
.compile:
mov [here], rax
add here, word_size
mov dil, byte[rax-1]
and dil, 0x02
test dil, dil
jnz .branch_write
jmp compiler_loop
.branch_write:
mov byte[branch], 1
jmp compiler_loop
.check_number:
call parse_int
test rdx, rdx
jz unknown
mov cl, byte[branch]
test cl, cl
jnz .branch
mov qword[here], xt_lit
add here, word_size
mov [here], rax
add here, word_size
jmp compiler_loop
.branch:
mov byte[branch], 0
mov [here], rax
add here, word_size
jmp compiler_loop
unknown:
mov rdi, undefined
call print_string
mov pc, xt_interpreter
jmp next
execute:
mov rdi, rax
call cfa
mov dil, byte[rax-1]
and dil, 0x02
test dil, dil
jnz unknown
mov w, rax
mov [program_stub], rax
mov pc, program_stub
jmp next
next:
mov w, pc
add pc, 8
mov w, [w]
jmp [w]
close:
mov rax, 60
xor rdi, rdi
syscall