1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; UrForth level
1: self
-hosting
32-bit Forth compiler
3 ;; Copyright
(C
) 2020 Ketmar Dark
// Invisible Vector
5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7 ;; "TIB" and
"#TIB" will be set by the startup code
8 $uservar
"TIB" ua_ofs_tib
0
9 $uservar
"#TIB" ua_ofs_tib_size
0
10 $uservar
">IN" ua_ofs_in
0
11 $uservar
"TIB-LINE#" ua_ofs_tibline
0
13 ;; "TIB-GETCH" will set this
if last
read char is not EOL
14 ;; parsing words will set this too
, as
if they
're using "TIB-GETCH"
15 $uservar "(TIB-LAST-READ-CHAR)" ua_ofs_tiblastchar 0
17 ;; $uservar "(TIB-ERROR-LINE-C4S)" ua_ofa_tib_errline_c4s 0
18 $variable "(TIB-ERROR-LINE-C4S)" 0
19 $variable "(TIB-ERROR-LINE->IN)" 0
21 ;; current file we are interpreting
23 $value "(TIB-CURR-FNAME)" 0
26 $value "(TIB-ERROR-FNAME)" 0
28 $value "(TIB-ERROR-LINE#)" 0
31 $value "(TIB-CURR-FNAME-DEFAULT)" 0
34 $constant "(#TIB-CURR-FNAME)" 260
37 ;; size of TIB save buffer
38 $constant "#TIB-SAVE-BUFFER" 5*4
41 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
42 : TIB-CURR-LINE ( -- linenum )
43 tib-line# @ (tib-last-read-char@) nl = - \ FIXME: WARNING! assumes that `true` is `1`!
47 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
48 ..: (startup-init) ( -- )
49 (#tib-curr-fname) brk-alloc dup to (tib-curr-fname) to (tib-curr-fname-default)
50 (#tib-curr-fname) brk-alloc dup to (tib-error-fname) 0! (tib-curr-fname) 0!
54 : (tib-free-errline) ( -- )
55 (tib-error-line-c4s) @ ?dup if
56 4096 os:munmap drop (tib-error-line-c4s) 0!
57 (tib-error-line->in) 0!
61 : (tib-clear-error) ( -- )
62 (tib-error-fname) 0! 0 to (tib-error-line#)
66 : (tib-set-fname) ( addr count -- )
67 0 (#tib-curr-fname) clamp (tib-curr-fname) c4s:copy-counted
71 : (tib-pos>bol) ( pos -- pos )
74 dup 1- tib @ + c@ nl <> while
78 : (tib-pos>eol) ( pos -- pos )
80 begin dup #tib @ < while
81 dup tib @ + c@ dup nl <> swap 0<> and while
85 ;; copy current TIB line to error buffer
86 : (tib-line>errline) ( -- )
88 >in @ (tib-last-read-char@) nl = if 1- endif 0 #tib @ clamp
89 dup (tib-pos>bol) >in @ over - (tib-error-line->in) !
90 swap (tib-pos>eol) over - 0 4090 clamp
91 (tib-error-line-c4s) @ ?dup ifnot
92 4096 os:prot-r/w os:mmap ifnot drop exit endif
93 dup (tib-error-line-c4s) !
95 rot tib @ + nrot c4s:copy-counted
102 : (tib-fname>error-fname) ( -- )
104 (tib-curr-fname) ?dup ifnot (tib-error-fname) ?dup if 0! endif exit endif
105 (tib-error-fname) ?dup ifnot drop exit endif
107 tib-line# @ dup if (tib-last-read-char@) nl = if 1- 1 max endif endif
112 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
113 : (tib-type-highlighted-line) ( addr count hipos -- )
116 >r over r> + nrot bounds do
117 dup i = if ." \x1b[7m" endif
118 i c@ safe-emit-printable
119 dup i = if ." \x1b[27m" endif
128 : (tib-type-error-line) ( -- )
129 (tib-error-line-c4s) @ ?dup if count (tib-error-line->in) @ (tib-type-highlighted-line) endif
132 : (tib-type-curr-line) ( -- )
133 #tib @ ifnot exit endif
134 >in @ (tib-last-read-char@) nl = if 1- endif
136 dup (tib-pos>bol) >in @ over - >r
137 swap (tib-pos>eol) over - 0 4090 clamp
138 swap tib @ + swap r> (tib-type-highlighted-line)
142 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
143 ;; by default, threads has no allocated tib
144 ;; call this to ensure that the tib is allocated
145 : tib-allocate-default ( -- )
146 (default-tib) @ ifnot
147 (default-#tib) cell+ brk-alloc (default-tib) !
148 tib @ ifnot (default-#tib) #tib ! (default-tib) @ tib ! endif
149 tib @ dup 0! (default-#tib) + 0!
153 ;; this doesn't reset line
154 : (tib
-set
-to) ( addr count
-- )
155 #tib
! tib
! >in
0! bl
(tib
-last
-read-char
) !
159 : tib
-set
-to ( addr count
-- )
160 (tib
-set
-to) tib
-line#
0!
163 : TIBSTATE
-SAVE
( bufaddr
-- )
167 tib
-line# @ over
! cell
+
168 (tib
-last
-read-char@
) swap
!
171 : TIBSTATE
-RESTORE
( bufaddr
-- )
175 dup @ tib
-line#
! cell
+
176 @
(tib
-last
-read-char
) !
180 : TIBSTATE
>R
( -- |
-- savedtibstate
)
181 r
> #tib
-save
-buffer ralloca tibstate
-save
>r
184 : R
>TIBSTATE
( -- | savedtibstate
-- )
185 r
> rp@ tibstate
-restore #tib
-save
-buffer rdealloca
>r
188 : RDROP
-TIBSTATE
( -- | savedtibstate
-- )
189 r
> #tib
-save
-buffer rdealloca
>r
192 : SAVE
-INPUT
( -- ... n
)
193 tib @ #tib @
>in @ tib
-line# @
(tib
-last
-read-char@
) 5
196 : RESTORE
-INPUT
( ... 5 -- )
197 5 <> ERR
-INVALID
-INPUT
-SIZE ?error
198 (tib
-last
-read-char
) ! tib
-line#
! >in
! #tib
! tib
!
201 : DROP
-SAVED
-INPUT
( ... 5 -- )
202 5 <> ERR
-INVALID
-INPUT
-SIZE ?error
207 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
208 : TIB
-DEFAULT?
( -- bool
)
209 tib @
(default-tib
) @
=
212 ;; reset TIB
to the
default one
214 (default-tib
) @ dup tib
!
215 if (default-#tib
) else 0 endif #tib
!
218 bl
(tib
-last
-read-char
) !
219 ;;k8
: no
, don
't clear it; it will be cleared by tloader in abort sequence
220 ;; 0 to tloader:last-include-dir-c4s
221 (tib-curr-fname-default) to (tib-curr-fname)
225 code: tib-in^ ( -- addr )
227 ld TOS,ts:[ua_ofs_tib]
228 add TOS,ts:[ua_ofs_in]
233 code: (tib-last-read-char@) ( -- ch )
235 ld TOS,ts:[ua_ofs_tiblastchar]
239 ;; will never be negative
240 ;; 0 means "END-OF-TIB"
241 code: TIB-PEEKCH ( -- ch-or-0 )
244 ld eax,ts:[ua_ofs_in]
245 cp eax,ts:[ua_ofs_tib_size]
247 add eax,ts:[ua_ofs_tib]
253 ;; will never be negative
254 ;; 0 means "END-OF-TIB"
255 code: TIB-PEEKCH-N ( chofs -- ch-or-0 )
258 add eax,ts:[ua_ofs_in]
260 cp eax,ts:[ua_ofs_tib_size]
262 add eax,ts:[ua_ofs_tib]
268 ;; will never be negative
269 ;; 0 means "END-OF-TIB" (and doesn't advance
>IN
)
270 code: TIB-GETCH ( -- ch-or-0 )
273 ld eax
,ts
:[ua_ofs_in
]
274 cp eax
,ts
:[ua_ofs_tib_size
]
278 add eax
,ts
:[ua_ofs_tib
]
280 ;; zero always ends the input
282 ld ts
:[ua_ofs_tiblastchar
],TOS
283 ld ts
:[ua_ofs_in
],edx
284 ;; update current line
287 ld eax
,ts
:[ua_ofs_tibline
]
291 ld ts
:[ua_ofs_tibline
],eax
296 : tib
-skipch
( -- ) tib
-getch drop
;
298 ;; -1 means
"buffer overflow"
299 : (STD
-ACCEPT
) ( addr maxlen fromrefill
-- readlen
// -1 )
300 drop
;; we can
't do anything with "fromrefill" flag here
301 0 ;; ( addr maxlen currcount )
305 dup -1 = over 10 = or over 13 = or
307 ;; ( addr maxlen currcount char )
311 ;; yep, store -- ( addr maxlen currcount | char )
312 rot r> over c! 1+ nrot 1+
315 rdrop ;; drop char, we have no room for it
317 2dup = if bell 1+ ( no more bells ) endif
320 ;; ( addr maxlen currcount char )
321 -1 <> if reset-emitcol ( because OS did cr -- i hope ) endif
322 ;; check for overflow
323 2dup < if 2drop drop -1 ( oops, overflow ) else nrot 2drop endif
326 ;; -1 means "buffer overflow"
327 ( addr maxlen fromrefill -- readlen // -1 )
328 $defer "(ACCEPT)" cfa "(STD-ACCEPT)"
331 ;; -1 means "buffer overflow"
332 : ACCEPT ( addr maxlen -- readlen // -1 )
333 dup 0 <= err-input-too-long ?error
337 ;; either refills TIB and sets flag to true, or does nothing and sets flag to false
343 tib @ #tib @ 1- true (accept)
347 endcr ." ERROR: ACCEPT buffer overflow\n"
349 ;;tib @ over type 124 emit dup . cr