-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathboot.rpl
97 lines (85 loc) · 3.29 KB
/
boot.rpl
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
( CODSWALLOP RPL, a zen garden
#####################################################
Bootstrap )
(This is the file the interpreter is hard-coded to load.
It tries to load files from a list in modules.rpl in sequence,
then either runs a file from the commandline or starts the REPL.
The first part of it is not dependent upon builtins, which is why
it's funny lookin'. It also includes very basic single stepping
and error reporting, though errors often aren't very meaningful
until later in the boot sequence.)
(-2nd, we need some semblance of error handling.)
'::
"Alas--" `I*.disp
#0
'::
trace `I*.len
':: (`I*.sst)
"In object " trace idx `I*.get #1 `I*.get `I*.+str `I*.dispn
" of :: " `I*.dispn
trace idx `I*.get #0 `I*.get `I*.dup `I*.len
':: 'obj `I*.rcl idx `I*.get `I*.>str `I*.dispn " " `I*.dispn
idx #1 `I*.+int `I*.dup 'idx `I*.sto len `I*.<
`I*.self `I*.swap '`I*.eval '`I*.drop `I*.ifte ;
{ len obj :idx:#0 } `I*.local
" ;" `I*.disp
idx #1 `I*.+int `I*.dup 'idx `I*.sto trace `I*.len `I*.<
`I*.self `I*.swap ':: `I*.eval ; ':: `I*.drop ; `I*.ifte ;
':: "." `I*.disp ;
`I*.ifte
"" `I*.disp
caller " opines: " `I*.+str reason `I*.+str `I*.disp ;
{ idx trace reason caller } `I*.local ;
'ERRTRACE `I*.sto
(-1st, a rudimentary single stepper.)
':: `I*.>str
':: "Single step: " obj `I*.+str ", call depth " `I*.+str depth
`I*.+str `I*.disp
`I*.stack "Stack: " `I*.swap `I*.+str `I*.disp
"(enter or break) " `I*.prompt `I*.drop ;
{ obj depth } `I*.local `I*.sst ;
'STEP `I*.sto
(Zeroth, we hang onto our commandline arguments.)
'ARGS I*.sto
(First, we try to open modules.rpl.)
#1 I*.dedcont BASDIR "modules.rpl" I*.+str I*.dsk>
(Did it work?)
I*.isded
':: `I*.drop "The lack of a modules.rpl suggests you may not have the best time" I*.disp ;
':: (And is it actually a list?)
`I*.dup `I*.type Types.List I*.==
':: #-1
':: (SST) idx #1 `I*.+int `I*.dup 'idx `I*.sto modules `I*.len `I*.<
':: (Fetch a list entry and try to load it if it's a string.)
modules idx `I*.get `I*.dup `I*.type Types.String `I*.==
':: BASDIR `I*.swap `I*.+str ".rpl" `I*.+str `I*.dsk> `I*.isded
':: "Module " modules idx `I*.get `I*.+str " is unhappy"
`I*.+str `I*.disp "" `I*.disp `I*.unded ;
`I*.ift ;
':: `I*.drop ;
`I*.ifte ;
':: `I*.bail ;
`I*.ifte `I*.self `I*.eval ;
{ idx modules } `I*.local
(This comment keeps us from inadvertently hanging onto those locals.) ;
':: "You may have a modules.rpl but it's not a great one" `I*.disp ;
`I*.ifte ;
`I*.ifte
(By the time we get here, we should be ready to go with builtins, and if
we aren't, it's probably best we fail here anyhow.)
(Turn error reporting back on.)
#0 DEDCONT
(It's really easy to crash the interpreter if we leave all the internals
lying around. 'SAFE' will erase the I* directory and itself. It's then
immediately called, but you can comment out the call to keep the juicy
bits to hand.)
':: 'I* RM 'SAFE RM ; 'SAFE STO
(This is what you'd comment out: ) SAFE
(And hand off to a commandline program or to the user.)
ARGS LEN
':: ARGS DSK> ;
':: 'REPL EXISTS
':: #1 TRACE "Codswallop RPL" DISP REPL ;
':: "Successfully failed to find REPL" DISP ;
IFTE ;
IFTE