summaryrefslogtreecommitdiff
path: root/boot/symbol.s
blob: fe88aefce98bec79d38d309b65956b596bac7765 (plain)
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
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.

.global symbol_table
.global symbol_table_build, symbol_table_find, symbol_table_insert, symbol_table_dump
.global symbol_table_make_pointer, symbol_table_make_parameter, symbol_table_make_local

.include "boot/definitions.inc"

.equ SYMBOL_PRIME, 1543

.section .rodata

.type symbol_builtin_name_int, @object
symbol_builtin_name_int: .ascii "Int"
.type symbol_builtin_name_word, @object
symbol_builtin_name_word: .ascii "Word"
.type symbol_builtin_name_byte, @object
symbol_builtin_name_byte: .ascii "Byte"
.type symbol_builtin_name_char, @object
symbol_builtin_name_char: .ascii "Char"
.type symbol_builtin_name_bool, @object
symbol_builtin_name_bool: .ascii "Bool"

# Every type info starts with a word describing what type it is.

# Primitive types have only type size.
.type symbol_builtin_type_int, @object
symbol_builtin_type_int: .word TYPE_PRIMITIVE
	.word 4
.type symbol_builtin_type_word, @object
symbol_builtin_type_word: .word TYPE_PRIMITIVE
	.word 4
.type symbol_builtin_type_byte, @object
symbol_builtin_type_byte: .word TYPE_PRIMITIVE
	.word 1
.type symbol_builtin_type_char, @object
symbol_builtin_type_char: .word TYPE_PRIMITIVE
	.word 1
.type symbol_builtin_type_bool, @object
symbol_builtin_type_bool: .word TYPE_PRIMITIVE
	.word 1

.section .bss

# The first word of the symbol table is its length.
# Then a list of type infos follows:
#
# record
#   name: String
#   info: ^TypeInfo
# end
.type symbol_table, @object
symbol_table: .zero SYMBOL_PRIME

.section .text

# Prints the list of symbols in the table.
.type symbol_table_dump, @function
symbol_table_dump:
	# Prologue.
	addi sp, sp, -32
	sw ra, 28(sp)
	sw s0, 24(sp)
	addi s0, sp, 32

	sw s1, 20(sp) # Current symbol in the table.
	sw s2, 16(sp) # Symbol table length.

	la s1, symbol_table
	lw s2, 0(s1)
	addi s1, s1, 4 # Advance to the first symbol in the table.

.Lsymbol_table_dump_loop:
	beqz s2, .Lsymbol_table_dump_end

	# Compare string lengths.
	lw a0, 4(s1)
	lw a1, 0(s1)
	call _write_error

	addi s1, s1, 12
	addi s2, s2, -1
	j .Lsymbol_table_dump_loop

.Lsymbol_table_dump_end:
	lw s1, 20(sp)
	lw s2, 16(sp)

	# Epilogue.
	lw ra, 28(sp)
	lw s0, 24(sp)
	addi sp, sp, 32
	ret

# Searches for a symbol by name.
#
# Parameters:
# a0 - Length of the symbol to search.
# a1 - Pointer to the symbol name.
#
# Sets a0 to the symbol info pointer or 0 if the symbol has not been found.
.type symbol_table_find, @function
symbol_table_find:
	# Prologue.
	addi sp, sp, -32
	sw ra, 28(sp)
	sw s0, 24(sp)
	addi s0, sp, 32

	sw s1, 20(sp) # Current symbol in the table.
	sw s2, 16(sp) # Symbol table length.
	sw s3, 12(sp) # Length of the symbol to search.
	sw s4, 8(sp) # Pointer to the symbol to search.

	mv s3, a0
	mv s4, a1

	la s1, symbol_table
	lw s2, 0(s1)
	addi s1, s1, 4 # Advance to the first symbol in the table.

.Lsymbol_table_find_loop:
	beqz s2, .Lsymbol_table_find_not_found

	# Compare string lengths.
	mv a0, s3
	mv a1, s4
	lw a2, 0(s1)
	lw a3, 4(s1)
	call _string_equal

	beqz a0, .Lsymbol_table_find_continue

	lw a0, 8(s1) # Pointer to the symbol.
	j .Lsymbol_table_find_end

.Lsymbol_table_find_continue:
	addi s1, s1, 12
	addi s2, s2, -1
	j .Lsymbol_table_find_loop

.Lsymbol_table_find_not_found:
	li a0, 0

.Lsymbol_table_find_end:
	lw s1, 20(sp)
	lw s2, 16(sp)
	lw s3, 12(sp)
	lw s4, 8(sp)

	# Epilogue.
	lw ra, 28(sp)
	lw s0, 24(sp)
	addi sp, sp, 32
	ret

# Creates a pointer type.
#
# Parameters:
# a0 - Pointer to the base type.
# a1 - Output memory.
#
# Sets a0 to the size of newly created type in bytes.
.type symbol_table_make_pointer, @function
symbol_table_make_pointer:
	li t0, TYPE_POINTER
	sw t0, 0(a1)
	sw a0, 4(a1)

	li a0, 8
	ret

# Creates a parameter info.
#
# Parameters:
# a0 - Pointer to the parameter type.
# a1 - Parameter offset.
# a2 - Output memory.
#
# Sets a0 to the size of newly created info object in bytes.
.type symbol_table_make_parameter, @function
symbol_table_make_parameter:
	li t0, INFO_PARAMETER
	sw t0, 0(a2)
	sw a0, 4(a2)
	sw a1, 8(a2)

	li a0, 12
	ret

# Creates a local variable info.
#
# Parameters:
# a0 - Pointer to the variable type.
# a1 - Variable stack offset.
# a2 - Output memory.
#
# Sets a0 to the size of newly created info object in bytes.
.type symbol_table_make_local, @function
symbol_table_make_local:
	li t0, INFO_LOCAL
	sw t0, 0(a2)
	sw a0, 4(a2)
	sw a1, 8(a2)

	li a0, 12
	ret

# Inserts a symbol into the table.
#
# Parameters:
# a0 - Symbol name length.
# a1 - Symbol name pointer.
# a2 - Symbol pointer.
.type symbol_table_insert, @function
symbol_table_insert:
	la t0, symbol_table

	lw t1, 0(t0) # Current table length.
	li t2, 12 # Calculate the offset to the next entry.
	mul t2, t1, t2
	addi t2, t2, 4
	add t2, t0, t2

	sw a0, 0(t2)
	sw a1, 4(t2)
	sw a2, 8(t2)

	addi t1, t1, 1 # Save the new length.
	sw t1, 0(t0)

	ret

# Build the initial symbols.
#
# Sets a0 to the pointer to the global symbol table.
.type symbol_build, @function
symbol_table_build:
	# Prologue.
	addi sp, sp, -16
	sw ra, 12(sp)
	sw s0, 8(sp)
	addi s0, sp, 16

	la a0, symbol_table
	addi t0, a0, 4

	li a0, 3 # Length of the word "Int".
	la a1, symbol_builtin_name_int
	la a2, symbol_builtin_type_int
	call symbol_table_insert

	li a0, 4 # Length of the word "Word".
	la a1, symbol_builtin_name_word
	la a2, symbol_builtin_type_word
	call symbol_table_insert

	li a0, 4 # Length of the word "Byte".
	la a1, symbol_builtin_name_byte
	la a2, symbol_builtin_type_byte
	call symbol_table_insert

	li a0, 4 # Length of the word "Char".
	la a1, symbol_builtin_name_char
	la a2, symbol_builtin_type_char
	call symbol_table_insert

	li a0, 4 # Length of the word "Bool".
	la a1, symbol_builtin_name_bool
	la a2, symbol_builtin_type_bool
	call symbol_table_insert

	# Epilogue.
	lw ra, 12(sp)
	lw s0, 8(sp)
	addi sp, sp, 16
	ret