-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlistwords.S
563 lines (544 loc) · 13.4 KB
/
listwords.S
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
#Run through the dictionary listing all words flagged for use
CODEHEADER WORDS, DUP, 0x01
la t0, dictionary
wordlist_fetch:
ld t1, 0(t0)
ld t2, 0(t1)
li t3, 1
and t2, t2, t3
beqz t2, wordlist_get_next #flag is zero, not for printing
ld t2, 24(t1) #length of name
addi t1, t1, 32 #address of characters for name
PUSH t0
WRITESTRINGR t1, t2
WRITECHAR 0x20
WRITECHAR 0x20
POP t0
wordlist_get_next:
ld t1, 0(t0)
ld t1, 16(t1) #next pointer
beq t1, zero, wordlist_finished
ld t1, 0(t0)
addi t1, t1, 16
mv t0, t1
j wordlist_fetch
wordlist_finished:
tail NEXT
CODEHEADER _MARKER, WORDS, 0x0
#("<spaces>name" ---)
#compiled version of marker
ld t0, 0(s7) #length
mv a0, s7
addi a0, a0, ADDRWIDTH
mv a1, a0
add a1, a1, t0
mv s7, a1 #now move s7 on to next aligned address
addi s7, s7, 1
li t1, 7
and t2, s7, t1
beqz t2, _marker_ready_to_join
li t3, 8
sub t4, t3, t2
add s7, t4, s7
_marker_ready_to_join:
bnez t0, marker_join_here
tail NEXT
CODEHEADER MARKER, _MARKER, 0x01
#("<spaces>name" ---)
ld a0, INPUT_START
ld a1, INPUT_END
addi t0, a0, 1
bltu t0, a1, marker_have_data
tail NEXT
marker_have_data:
call utility_find_string
beq a2, zero, marker_done
addi t0, a1, 1
sd t0, INPUT_START, t1 #update interpretation point
marker_join_here:
call utility_sanitize_string
#a0 has start a1 has end
mv t0, a1
sub t1, t0, a0 #t1 has length
la t2, dictionary
ld t3, 0(t2)
marker_next_in_dictionary:
lb t4, 24(t3)
bne t4, t1, marker_tokens_do_not_match
add a3, t3, 32
mv a4, a0
mv a5, t1
marker_loop_through_token:
lb t5, 0(a3)
lb t6, 0(a4)
bne t5, t6, marker_tokens_do_not_match
addi a5, a5, -1
beq a5, zero, marker_tokens_matched
addi a3, a3, 1
addi a4, a4, 1
j marker_loop_through_token
marker_tokens_do_not_match:
ld t3, 16(t3)
beq t3, zero, marker_done
j marker_next_in_dictionary
marker_tokens_matched:
ld t3, 16(t3)
sd t3, 0(t2) #update dictionary
marker_done:
tail NEXT
CODEHEADER EVALUATE, MARKER, 0x01
#(i * x addr u -- j * x)
li t0, 1 #mark we are in an evaluation
sd t0, INEVAL, t2
la t0, SOURCEID
li t1, -1
sd t1, 0(t0) #set SOURCE-ID
sd s7, RESUME_AFTER_EVAL, t0
ld t0, 0(sp)
ld t1, 8(sp)
addi sp, sp, 16
#set the INPUT and OUTPUT and pass control
la a0, INPUT_START # get restart point
ld a1, 0(a0)
sd a1, INPUT_START_RESTART, t3 # save for future reuse
la a3, INPUT_DISPLACE
ld a4, 0(a3)
sd a4, INPUT_DISPLACE_RESTART, t3 # save for reuse
sd t1, INPUT_BUFFER_STRING, t3
sd t1, INPUT_START, t3
add t0, t0, t1
sd t0, INPUT_END, t3
sd zero, INPUT_DISPLACE, t3
la s7, outer_loop_tokenize
tail NEXT
CODEHEADERZ ENVIROQ, ENVIRONMENT?, EVALUATE, 0x01
#(c-addr u -- false | i * x true)
ld t0, 0(sp)
ld t1, 8(sp)
addi sp, sp, 16
li t2, eq_csLen
bne t2, t0, enviroq_hold
mv a0, t1
la a1, eq_countedstrings
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_hold
tail utility_enviroq_countedstrings
enviroq_hold:
li t2, eq_holdLen
bne t2, t0, enviroq_pad
mv a0, t1
la a1, eq_hold
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_pad
tail utility_enviroq_hold
enviroq_pad:
li t2, eq_padLen
bne t2, t0, enviroq_aub
mv a0, t1
la a1, eq_pad
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_aub
tail utility_enviroq_pad
enviroq_aub:
li t2, eq_aubLen
bne t2, t0, enviroq_floored
mv a0, t1
la a1, eq_addressunitbits
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_floored
tail utility_enviroq_aub
enviroq_floored:
li t2, eq_flooredLen
bne t2, t0, enviroq_maxchar
mv a0, t1
la a1, eq_floored
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_maxchar
tail utility_enviroq_floored
enviroq_maxchar:
li t2, eq_maxcharLen
bne t2, t0, enviroq_maxd
mv a0, t1
la a1, eq_maxchar
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_maxd
tail utility_enviroq_maxchar
enviroq_maxd:
li t2, eq_maxdLen
bne t2, t0, enviroq_maxn
mv a0, t1
la a1, eq_maxd
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_maxn
tail utility_enviroq_maxd
enviroq_maxn:
li t2, eq_maxnLen
bne t2, t0, enviroq_maxu
mv a0, t1
la a1, eq_maxn
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_maxu
tail utility_enviroq_maxn
enviroq_maxu:
li t2, eq_maxuLen
bne t2, t0, enviroq_maxud
mv a0, t1
la a1, eq_maxu
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_maxud
tail utility_enviroq_maxu
enviroq_maxud:
li t2, eq_maxudLen
bne t2, t0, enviroq_rsc
mv a0, t1
la a1, eq_maxud
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_rsc
tail utility_enviroq_maxud
enviroq_rsc:
li t2, eq_rscLen
bne t2, t0, enviroq_sc
mv a0, t1
la a1, eq_returnstackcells
mv a2, t0
call utility_stringsmatch
mv t0, a2
mv t1, a0
bnez a3, enviroq_sc
tail utility_enviroq_rsc
enviroq_sc:
li t2, eq_scLen
bne t2, t0, enviroq_false
mv a0, t1
la a1, eq_stackcells
mv a2, t0
call utility_stringsmatch
#mv t0, a2 unneeded at present
#mv t1, a0
bnez a3, enviroq_false
tail utility_enviroq_stackcells
enviroq_false:
addi sp, sp, -8
sd zero, 0(sp)
enviroq_next:
tail NEXT
CODEHEADER LITERAL, ENVIROQ, 0x01
#does nothing in interpretation mode
#(x --) : compile time - compiler will take number from stack via literalnumb
tail NEXT
CODEHEADER LITERALNUMB, LITERAL, 0x0
#read in a number - next in the secondary
#store it on the stack and move on
ld t0, 0(s7)
addi sp, sp, -8
sd t0, 0(sp)
addi s7, s7, ADDRWIDTH
tail NEXT
CODEHEADER LITERALADDR, LITERALNUMB, 0x0
#read in an address from the secondary
#then get the contents of that address
#and place those on the stack
ld t0, 0(s7)
ld t1, 0(t0)
addi sp, sp, -8
sd t1, 0(sp)
addi s7, s7, ADDRWIDTH
tail NEXT
CODEHEADER TYPE, LITERALADDR, 0x01
ld t0, 0(sp)
bnez t0, type_continue
addi sp, sp, 16
tail NEXT
type_continue:
ld t1, 8(sp)
WRITESTRINGR t1, t0
addi sp, sp, 16
tail NEXT
CODEHEADER TIB, TYPE, 0x01
#return address of input buffer
la t0, INPUT_BUFFER
PUSH t0
tail NEXT
CODEHEADERZ DOTS, .S, TIB, 0x01
# display contents of stack (tools word)
# ( -- )
# from DEPTH
la t0, STACKTOP
ld t1, 0(t0)
sub t2, t1, sp
srai t3, t2, 3
#t3 now has the depth of the stack
#display as number
blez t3, dots_done
#copy the stack
mv t0, t3
mv t1, sp
dots_copying_stack:
addi sp, sp, -8
ld t2, 0(t1)
sd t2, 0(sp)
addi t0, t0, -1
beqz t0, dots_display
addi t1, t1, 8
j dots_copying_stack
dots_display:
addi s10, s10, -8
sd t3, 0(s10)
dots_output:
ld t0, CURRENT_BASE
POP a2 #get item on stack
la a0, SCRATCH_PAD #sprintf uses this
addi t1, zero, 16
beq t0, t1, dots_ps_format_hex
addi t1, zero, 8
beq t0, t1, dots_ps_format_octal
addi t1, zero, 2
beq t0, t1, dots_ps_format_binary
la a1, decimalout
j dots_dot_output
dots_ps_format_hex:
la a1, hexout
j dots_dot_output
dots_ps_format_octal:
la a1, octalout
j dots_dot_output
dots_dot_output:
addi a3, zero, 3
call sprintf
la t0, SCRATCH_PAD
mv t1, a0
WRITESTRINGR t0, t1
j dots_loop_output
dots_ps_format_binary: #binary output not supported by sprintf, so do it ourselves
li t0, 1
li t1, 63
dots_dot_test_against_shift:
sll t3, t0, t1
and a0, a2, t3
bne a0, zero, dots_dot_start_binary #past any trailing zeros - so start output
sub t1, t1, t0
beq t1, zero, dots_dot_last_and_out
j dots_dot_test_against_shift
dots_dot_start_binary:
addi sp, sp, -32
sd a2, 24(sp)
sd t0, 16(sp)
sd t1, 8(sp)
sd t3, 0(sp)
WRITECHAR 0x31 #output 1
dots_dot_start_pop:
ld t3, 0(sp)
ld t1, 8(sp)
ld t0, 16(sp)
ld a2, 24(sp)
addi sp, sp, 32
dots_dot_shift_and_test:
sub t1, t1, t0
beq t1, zero, dots_dot_last_and_out
sll t3, t0, t1
and a0, a2, t3
bne a0, zero, dots_dot_start_binary
addi sp, sp, -32
sd a2, 24(sp)
sd t0, 16(sp)
sd t1, 8(sp)
sd t3, 0(sp)
WRITECHAR 0x030 #output 0
j dots_dot_start_pop
dots_dot_last_and_out:
and a0, a2, t0
beq a0, zero, dots_dot_zero_and_out
WRITECHAR 0x31
j dots_dot_output_b_and_space
dots_dot_zero_and_out:
WRITECHAR 0x30
dots_dot_output_b_and_space:
WRITECHAR 0x62 #b
WRITECHAR 0x20
dots_loop_output:
ld a7, 0(s10)
addi a7, a7, -1
beqz a7, dots_cr_out
sd a7, 0(s10)
WRITECHAR 0x2C
WRITECHAR 0x20
j dots_output
dots_cr_out:
addi s10, s10, 8
WRITECHAR 0x0A
dots_done:
tail NEXT
CODEHEADER IOCTL, DOTS, 0x01
#(fd, request, mem -- errno ret)
ld a0, 16(sp)
ld a1, 8(sp)
ld a2, 0(sp)
add sp, sp, 8
call ioctl
li t0, -1
beq t0, a0, ioctl_real_err_no
sd zero, 8(sp)
j ioctl_set_ret
ioctl_real_err_no:
sd a7, 8(sp)
ioctl_set_ret:
sd a0, 0(sp)
tail NEXT
CODEHEADER DISPLAY, IOCTL, 0x01
la t0, SCRATCH_PAD
mv t1, zero
mv t3, sp
li t4, 0x80
display_fetch_from_stack:
lb t5, 0(t3)
addi t3, t3, STACKOFFSET
and t6, t5, t4
bne t6, zero, display_data_collected
sb t5, 0(t0)
addi t0, t0, 1
addi t1, t1, 1
j display_fetch_from_stack
display_data_collected:
mv sp, t3
la t0, SCRATCH_PAD
WRITESTRINGR t0, t1
tail NEXT
CODEHEADERZ BUFFERCOLON, BUFFER:, DISPLAY, 0x01
#(u "<spaces>name" --)
ld a1, INPUT_END
ld a0, INPUT_START
addi t0, a0, 1
bltu t0, a1, buffercolon_have_data
tail NEXT #nothing to parse
buffercolon_have_data:
#now test we are aligned
call utility_find_string
beqz a0, variable_gone_bad
#now have a0 with start, a1 with end+1, a2 with length
sd a1, INPUT_START, t5 #update read in point
call utility_sanitize_string
#now check this is not a keyword or a number
call utility_check_dictionary_match
bnez a3, variable_gone_bad
#write out a word with the variable name that will return the address
#get the address we'll return
mv a1, a2
li a5, 0x08 #8 for a variable
call utility_write_function_header
la a3, dataspaceptr
ld a1, 0(a3)
#check alignment
li t0, 0x07
li t2, 0x08
and t1, a1, t0
beqz t1, buffercolon_advance_alloc
sub t3, t2, t1
add a1, a1, t3
buffercolon_advance_alloc:
ld t2, 0(sp)
addi sp, sp, 8
j variable_advance_alloc
CODEHEADER VARIABLE, BUFFERCOLON, 0x01
ld a1, INPUT_END
ld a0, INPUT_START
addi t0, a0, 1
bltu t0, a1, variable_have_data
tail NEXT #nothing to parse
variable_have_data:
call utility_find_string
beqz a0, variable_gone_bad
#now have a0 with start, a1 with end+1, a2 with length
sd a1, INPUT_START, t5 #update read in point
call utility_sanitize_string
#now check this is not a keyword or a number
PUSH a2 # store length
call utility_check_dictionary_match
bnez a3, variable_gone_bad
POP t2 # get length back
addi t2, t2, 1
la t3, INPUT_DISPLACE
ld t4, 0(t3)
add t4, t4, t2
sd t4, 0(t3)
#write out a word with the variable name that will return the address
#get the address we'll return
mv a1, a2
li a5, 0x08 #8 for a variable
call utility_write_function_header
la a3, dataspaceptr
ld a1, 0(a3)
#check alignment
li t0, 0x07
li t2, 0x08
and t1, a1, t0
beqz t1, variable_advance_alloc
sub t3, t2, t1
add a1, a1, t3
variable_advance_alloc:
add a4, a1, t2
sd a4, 0(a3)
la a2, NEXT
call utility_constant_code
#now check if we are 8 bit aligned on writing address
li t0, 0x07
li t2, 0x08
and t1, a1, t0
and t1, a0, t0
beqz t1, variable_done
sub t3, t2, t1
add a0, a0, t3
variable_done:
la t4, createwritepoint
sd a0, 0(t4)
la t0, newdictionary
la t1, dictionary
ld t2, 0(t0)
sd t2, 0(t1)
sd a0, 0(t0) #update address we will writenext word to
tail NEXT #and out
variable_gone_bad:
addi sp, sp, 8 # clear stack
la t0, NotOk_msg
addi t1, zero, 24 #error message is 24 chars long
WRITESTRINGR t0, t1
li a0, 1
la t0, TOKEN_START
ld a1, 0(t0)
la t1, TOKEN_END
ld a2, 0(t1)
sub a2, a2, a1
addi a2, a2, 1
call write #output error message
addi t0, zero, 1
sd t0, OKSTATUS, t1
tail NEXT