mirror of
https://git.sr.ht/~crc_/retroforth
synced 2024-11-16 19:48:56 +01:00
660e52bdcb
FossilOrigin-Name: 1a43743f43076eb087ee4dd7fbfa96b8dfda2aa4ddcff41e6a5a9634ba6e239c
110 lines
3.2 KiB
Text
110 lines
3.2 KiB
Text
# RRE Listener and Extensions
|
|
|
|
In this file I am implementing the interactive listener that
|
|
RRE will run when started with `-i`, `-i,c`, or `-i,fs`.
|
|
|
|
The basic image has a space allocated for input at the end of
|
|
the kernel. This is at address 1024 (the kernel space is fixed
|
|
at addresses 0 to 1023).
|
|
|
|
~~~
|
|
#1024 'TIB const
|
|
~~~
|
|
|
|
~~~
|
|
:image:save (s-) #1000 io:scan-for io:invoke ;
|
|
~~~
|
|
|
|
## Console Input
|
|
|
|
The RRE interface provides a keyboard device. This exposes it
|
|
via `c:get`.
|
|
|
|
~~~
|
|
{{
|
|
'Keyboard var
|
|
:identify
|
|
@Keyboard n:zero? [
|
|
#1 io:scan-for dup n:negative?
|
|
[ drop 'IO_DEVICE_TYPE_0001_NOT_FOUND s:put nl ]
|
|
[ !Keyboard ] choose ] if ;
|
|
---reveal---
|
|
:c:get (-c) identify @Keyboard io:invoke ;
|
|
}}
|
|
~~~
|
|
|
|
Now that I can read characters, it's time to support reading
|
|
strings. I do this via two words. The first is `parse-until`.
|
|
This will setup a temporary string as an input buffer, then
|
|
read input, passing each character ot a provided quote. When
|
|
the quote returns `TRUE`, it ends and returns the string. When
|
|
not `TRUE` it will add the character to the buffer.
|
|
|
|
~~~
|
|
{{
|
|
:gather (c-)
|
|
dup [ ASCII:BS eq? ] [ ASCII:DEL eq? ] bi or &drop &buffer:add choose ;
|
|
:cycle (q-qc) repeat c:get dup-pair swap call not 0; drop gather again ;
|
|
---reveal---
|
|
:parse-until (q-s)
|
|
[ s:empty buffer:set cycle drop-pair buffer:start ] buffer:preserve ;
|
|
}}
|
|
~~~
|
|
|
|
Using this, a simple `s:get` can be implemented very easily as
|
|
a quote which looks for an end of line character.
|
|
|
|
~~~
|
|
:s:get (-s) [ [ ASCII:LF eq? ] [ ASCII:CR eq? ] bi or ] parse-until ;
|
|
:s:get-word (-s) &c:whitespace? parse-until ;
|
|
~~~
|
|
|
|
~~~
|
|
:clear ASCII:ESC c:put '[2J s:put ASCII:ESC c:put '[0;0H s:put ;
|
|
~~~
|
|
|
|
Hide the support words.
|
|
|
|
# Standard Interactive Listener
|
|
|
|
The main part of this file is the *listener*, an interactive
|
|
read-eval-print loop.
|
|
|
|
RRE's C part will access a couple parts of this, based on the
|
|
startup flags passed.
|
|
|
|
~~~
|
|
'NoEcho var
|
|
|
|
:bye #0 unix:exit ;
|
|
|
|
{{
|
|
'EOT var
|
|
FALSE 'Ignoring var-n
|
|
(-f) :ignoring? @Ignoring ;
|
|
(-nn) :version @Version #100 /mod ;
|
|
(c-f) :done? dup !EOT
|
|
[ ASCII:CR eq? ]
|
|
[ ASCII:LF eq? ]
|
|
[ ASCII:SPACE eq? ] tri or or ;
|
|
(c-f) :eol? @EOT [ ASCII:CR eq? ] [ ASCII:LF eq? ] bi or ;
|
|
(s-sf) :valid? dup s:length n:strictly-positive? ;
|
|
(c-c) :check-eof dup [ #-1 eq? ] [ ASCII:EOT eq? ] bi or &bye if ;
|
|
:bs buffer:get buffer:get drop-pair ;
|
|
(c-c) :check-bs dup [ ASCII:BS eq? ] [ ASCII:DEL eq? ] bi or &bs if ;
|
|
(c-c) :check check-eof check-bs ;
|
|
(-c) :character c:get dup buffer:add ;
|
|
(q-) :buffer [ TIB buffer:set call buffer:start ] buffer:preserve ;
|
|
(-s) :read-token [ [ character check done? ] until ] buffer s:chop ;
|
|
(-sf) :input read-token valid? ;
|
|
(sf-) :process ignoring? [ drop-pair eol? [ &Ignoring v:off ] if ] if;
|
|
&interpret &drop choose ;
|
|
---reveal---
|
|
:// script:ignore-to-eol &Ignoring v:on ; immediate
|
|
:banner version 'RETRO_12_(%n.%n)\n s:format s:put
|
|
EOM here - here EOM '%n_Max,_%n_Used,_%n_Free\n s:format s:put ;
|
|
:listen @NoEcho [ banner ] -if repeat input process again ;
|
|
}}
|
|
|
|
&listen #1 store
|
|
~~~
|