work on refactoring/cleaning up takawiri

FossilOrigin-Name: 2d99dd7dcdcdc565490188cccb0649e82077e5b2a87cd543db6df7d31f0479dc
This commit is contained in:
crc 2024-04-18 14:04:19 +00:00
parent 8b8e037680
commit 5e7e174e0d

View file

@ -9,15 +9,67 @@
================================================================
# Terminal Configuration
# Background
Setup the local terminal dimensions. This requires the current
development build of Retro to gain access to the `ioctl:` words.
(If not using this, hard code the terminal constraints for your
system).
The current generation of RetroForth did not start off as a
traditional, interactive Forth. A minimal (and lightly expanded)
REPL simply called the listener has existed, but it is not a
user friendly system.
Takawiri is a new listener. I've been slowly working on it,
with a goal of growing it into something useful. At present it
is functional, but many pieces remain. (See the end of this
document for a partial list).
# The Interface
Takawiri presents a fullscreen interface. This has a large area
for the display (the "text output buffer", or TOB) with a set
of introspection views on the right. At the bottom is the text
input area.
+-----------------------------------------+----------------+
| Text Output Buffer | Introspection |
| | |
| | |
| +----------------+
| | Stack Display |
| | |
| | |
| +----------------+
| | String Preview |
| | |
| | |
| +----------------+
| | Watched Vars |
| | |
| | |
+-----------------------------------------+----------------+
| input area |
+----------------------------------------------------------+
# Startup & Dependencies
Takawiri requires RetroForth 2024.9 or newer, with the ioctl
device enabled. It also requires a terminal with 100 or more
columns and at least 27 rows.
I do the initial configuration, and check these, reporting any
errors and exiting if necessary.
~~~
@Version #202409 lt?
[ 'Requires_RetroForth_2024.9_or_newer s:put nl bye ] if
~~~
Setup the local terminal dimensions. This uses the `ioctl:`
words added in RetroForth 2024.9.
~~~
ioctl:term-size (rows,cols) 'LT:W const 'LT:H const
LT:W #100 lt? [ 'Terminal_too_narrow! s:put nl bye ] if
LT:H #27 lt? [ 'Terminal_too_short! s:put nl bye ] if
~~~
Setup the text output buffer dimensions. The width is currently
@ -29,16 +81,6 @@ height.
LT:H #2 - 'TOB:H const
~~~
Check to make sure the terminal is large enough to display
everything.
~~~
LT:W #100 lt? [ 'Terminal_too_narrow! s:put nl bye ] if
LT:H #27 lt? [ 'Terminal_too_short! s:put nl bye ] if
~~~
# Dependencies
Load dependencies from the library.
~~~
@ -67,6 +109,104 @@ This word provides access to retro-describe(1).
[ dup file:read dup c:put n:zero? ] until unix:pclose ;
~~~
# UI
First are words to display the text output buffer.
~~~
:bar:right (-) dss:sep TOB:H n:inc [ I n:inc TOB:W #2 n:add vt:row,col $| c:put ] indexed-times vt:reset ;
:bar:bottom (-) dss:sep TOB:H n:inc #1 vt:row,col TOB:W n:inc [ $= c:put ] times $+ c:put vt:reset ;
:display:tob (-) tob:display bar:right bar:bottom ;
~~~
Draw the section separators.
~~~
:length (-n) LT:W TOB:W #4 n:add n:sub ;
:--- (n-) [ $- c:put ] times sp ;
:sections (-)
dss:sep
#3 [ I n:inc #6 n:mul TOB:W #4 n:add vt:row,col length --- ]
indexed-times
vt:reset ;
~~~
~~~
'Items d:create #0 comma #32 allot
:tos? over n:zero? ;
:dss
[ depth #5 n:min !Items
&Items fetch-next &store-next times drop
&Items a:reverse [ ] a:for-each
#0 &Items [
over n:inc #6 n:add #84 vt:row,col
dss:label
tos? [ 'TOS:___ s:put ] [ '_______ s:put ] choose
vt:reset
n:put
n:inc ] a:for-each
drop ] gc ;
~~~
## String Preview
This is the start of code to display temporary strings on the
data stack. The plan is to have it show below the stack values,
in a format like:
<depth> <first XX characters>
The <depth> data will match up to the values in the stack disp.
Note: this won't be useful until after the alternate `s:evaluate`
is done.
~~~
{{
:string? (v-vf) dup STRINGS gt? ;
:display
over n:inc #12 n:add #84 vt:row,col
fg:red
tos? [ 'TOS:___ s:put ] [ '_______ s:put ] choose
vt:reset
s:put ;
:not-string
over n:inc #12 n:add #84 vt:row,col
fg:blue '_______n/a s:put drop vt:reset ;
---reveal---
:strings (-)
#0 &Items [ string? &display &not-string choose n:inc ]
a:for-each drop ;
}}
~~~
~~~
:layout:stat,col (-n) #84 ;
:layout:stat (sn-) layout:stat,col vt:row,col dss:label s:put dss:value ;
:stats
'HERE:__ #1 layout:stat here n:put
'FREE:__ #2 layout:stat FREE n:put
'DEPTH:_ #3 layout:stat depth n:put
'ROW:___ #4 layout:stat @TY n:put
'COL:___ #5 layout:stat @TX n:put
vt:reset
;
:prompt (-)
dss:prompt
LT:H #1 vt:row,col LT:W [ sp ] times
LT:H #1 vt:row,col '>>_ s:put ;
~~~
~~~
:quit ioctl:set-lbreak vt:reset bye ;
:bye quit ;
~~~
# Watchlist
The watchlist will allow monitoring a small number of addresses
@ -109,98 +249,6 @@ do something like:
n:put n:inc vt:reset ] times drop ;
~~~
# UI
First are words to display the text output buffer.
~~~
:bar:right (-) dss:sep TOB:H n:inc [ I n:inc TOB:W #2 n:add vt:row,col $| c:put ] indexed-times vt:reset ;
:bar:bottom (-) dss:sep TOB:H n:inc #1 vt:row,col TOB:W n:inc [ $= c:put ] times $+ c:put vt:reset ;
:display:tob (-) tob:display bar:right bar:bottom ;
~~~
Draw the section separators.
~~~
:length (-n) LT:W TOB:W #4 n:add n:sub ;
:--- (n-) [ $- c:put ] times sp ;
:sections (-)
dss:sep
#3 [ I n:inc #6 n:mul TOB:W #4 n:add vt:row,col length --- ]
indexed-times
vt:reset ;
~~~
~~~
'Items d:create #0 comma #32 allot
:tos? over n:zero? ;
:dss
[ depth #5 n:min !Items
&Items fetch-next &store-next times drop
&Items a:reverse [ ] a:for-each
#0 &Items [
over n:inc #6 n:add #84 vt:row,col
dss:label
tos? [ 'TOS:___ s:put ] [ '_______ s:put ] choose
vt:reset
n:put
n:inc ] a:for-each
drop ] gc ;
~~~
This is the start of code to display temporary strings on the
data stack. The plan is to have it show below the stack values,
in a format like:
<depth> <first XX characters>
The <depth> data will match up to the values in the stack disp.
Note: this won't be useful until after the alternate `s:evaluate`
is done.
~~~
:string? (v-vf) dup STRINGS gt? ;
:ss:display
over n:inc #12 n:add #84 vt:row,col
fg:red
tos? [ 'TOS:___ s:put ] [ '_______ s:put ] choose
vt:reset
s:put ;
:ss:not-string
over n:inc #12 n:add #84 vt:row,col fg:blue '_______n/a s:put drop vt:reset ;
:ss/later (-)
#0 &Items [ string? &ss:display &ss:not-string choose n:inc ] a:for-each drop
;
~~~
~~~
:layout:stat,col (-n) #84 ;
:layout:stat (sn-) layout:stat,col vt:row,col dss:label s:put dss:value ;
:stats
'HERE:__ #1 layout:stat here n:put
'FREE:__ #2 layout:stat FREE n:put
'DEPTH:_ #3 layout:stat depth n:put
'ROW:___ #4 layout:stat @TY n:put
'COL:___ #5 layout:stat @TX n:put
vt:reset
;
:prompt (-)
dss:prompt
LT:H #1 vt:row,col LT:W [ sp ] times
LT:H #1 vt:row,col '>>_ s:put ;
~~~
~~~
:quit ioctl:set-lbreak vt:reset bye ;
:bye quit ;
~~~
~~~
:ui
&err:notfound unhook
@ -209,7 +257,7 @@ is done.
[ vt:reset vt:clear vt:home
display:tob
sections
stats dss ss/later watchlist
stats dss strings watchlist
prompt s:get-word vt:reset
[ dup s:put sp interpret ] tob:with
] forever ;
@ -224,5 +272,6 @@ Things needed:
- termios device & words (or add termios to unix device?)
- colors for interface elements
- refactor & document everything
- line editing
================================================================