mirror of
https://git.sr.ht/~crc_/retroforth
synced 2024-11-16 19:48:56 +01:00
128f9d12e8
FossilOrigin-Name: 304f338ed52f543c55cfe47798d89efda3ea1cfb24c7dd401105c3b76bc0d731
166 lines
4.3 KiB
Forth
Executable file
166 lines
4.3 KiB
Forth
Executable file
#!/usr/bin/env retro
|
|
|
|
# retro-describe
|
|
|
|
This is a small tool to display some helpful information
|
|
about a word.
|
|
|
|
# Usage
|
|
|
|
retro-describe wordname
|
|
|
|
# Notes
|
|
|
|
This is based on the `glossary.forth` tool included with
|
|
Retro. It's basically just the `describe` functionality,
|
|
but is a little more streamlined to use and abandons the
|
|
editing and export functionality of the full tool.
|
|
|
|
# The Code
|
|
|
|
First, gather the command line arguments. If no word name
|
|
was passed, just exit.
|
|
|
|
~~~
|
|
script:arguments n:zero? [ #0 unix:exit ] if
|
|
~~~
|
|
|
|
~~~
|
|
#166 'DATA-START const
|
|
~~~
|
|
|
|
# Data File
|
|
|
|
/usr/local/share/RETRO12/words.tsv
|
|
|
|
I like plain text formats, so the data is stored as a plain text
|
|
file, with one line per word. Each line has a number of fields.
|
|
These are tab separated. The fields are:
|
|
|
|
| name | 0
|
|
| data stack | 1
|
|
| address stack | 2
|
|
| float stack | 3
|
|
| general description | 4
|
|
| interpret time description | 5
|
|
| compile time description | 6
|
|
| class handler | 7
|
|
| example 1 | 8
|
|
| example 2 | 9
|
|
| namespace | 10
|
|
| interface | 11
|
|
|
|
I use a variable named `SourceLine` to point to the current line
|
|
contents.
|
|
|
|
~~~
|
|
'SourceLine var
|
|
~~~
|
|
|
|
I next define words to access each field. This involves helpers
|
|
to skip over fields I'm not intersted in, a word to return a
|
|
specific field, and the top level wrappers over these.
|
|
|
|
Rather than manually enter each of the field accessors, I am
|
|
just listing them in a set and constructing the words via some
|
|
simple code.
|
|
|
|
~~~
|
|
{{
|
|
|
|
:select @SourceLine ASCII:HT s:tokenize swap a:fetch ;
|
|
|
|
---reveal---
|
|
|
|
#0 { 'name 'dstack 'astack 'fstack
|
|
'descr 'itime 'ctime 'class
|
|
'ex1 'ex2 'namespace 'interface }
|
|
|
|
[ 'field: s:prepend d:create
|
|
dup compile:lit &select compile:call compile:ret
|
|
&class:word reclass n:inc ] a:for-each drop
|
|
}}
|
|
~~~
|
|
|
|
# Display an Entry
|
|
|
|
I implement a word to display an entry. This will use a
|
|
format like:
|
|
|
|
name
|
|
|
|
Data: -
|
|
Addr: -
|
|
Float: -
|
|
|
|
A description of the word.
|
|
|
|
Class Handler: class:word | Namespace: global | Interface Layer: all
|
|
|
|
If there are specific notes on interpret or compile time
|
|
actions, or any examples, they will be displayed after
|
|
the description.
|
|
|
|
~~~
|
|
{{
|
|
:s:putfmt (s-) s:format s:put ;
|
|
:name field:name '%s\n\n s:putfmt ;
|
|
:data field:dstack '__Data:__%s\n s:putfmt ;
|
|
:address field:astack '__Addr:__%s\n s:putfmt ;
|
|
:float field:fstack '__Float:_%s\n\n s:putfmt ;
|
|
:description field:descr '%s\n\n s:putfmt ;
|
|
:interpret-time field:itime s:length 0; drop
|
|
field:itime 'Interpret_Time:\n__%s\n\n s:putfmt ;
|
|
:compile-time field:ctime s:length 0; drop
|
|
field:ctime 'Compile_Time:\n__%s\n\n s:putfmt ;
|
|
:| '_|_ s:put ;
|
|
:class field:class 'Class:_%s s:putfmt ;
|
|
:namespace field:namespace 'Namespace:_%s s:putfmt ;
|
|
:interface field:interface 'Interface_Layer:_%s s:putfmt ;
|
|
:example1 field:ex1 '{n/a} s:eq? not 0; drop
|
|
field:ex1 s:format '\nExample_#1:\n\n%s\n\n s:putfmt ;
|
|
:example2 field:ex2 '{n/a} s:eq? not 0; drop
|
|
field:ex2 s:format '\nExample_#2:\n\n%s\n\n s:putfmt ;
|
|
---reveal---
|
|
:display-result
|
|
name
|
|
data (stack)
|
|
address (stack)
|
|
float (stack)
|
|
description
|
|
interpret-time
|
|
compile-time
|
|
class | namespace | interface nl
|
|
example1
|
|
example2
|
|
;
|
|
}}
|
|
~~~
|
|
|
|
## Describe a Word
|
|
|
|
~~~
|
|
{{
|
|
'Target var
|
|
'Len var
|
|
'LineNumber var
|
|
:matched? (-f) @SourceLine @Len s:left s:hash @Target eq? ;
|
|
:entry? (-f) @LineNumber DATA-START gteq? &LineNumber v:inc ;
|
|
:process (-) &Heap [ s:keep !SourceLine matched? &display-result if ] v:preserve ;
|
|
---reveal---
|
|
:find-and-display-entry
|
|
#0 !LineNumber dup s:length !Len s:hash !Target
|
|
script:name [ entry? &process &drop choose ] file:for-each-line nl ;
|
|
}}
|
|
~~~
|
|
|
|
# Finish
|
|
|
|
This checks the command line arguments and calls the proper words to
|
|
handle each case.
|
|
|
|
~~~
|
|
script:arguments [ I script:get-argument find-and-display-entry ] indexed-times
|
|
~~~
|
|
|
|
# Glossary Data
|