#!/bin/sh
------------------------------------------------------------
rm -f tags
touch tags
find . -name '.retro' -print0 | xargs -0 -n 1 retro $0 >>tags
find . -name '.forth' -print0 | xargs -0 -n 1 retro $0 >>tags
cat tags | sort | uniq >tags2
mv tags2 tags
exit
This will scan a source file and create output for a tags
file in the minimal ctags format. In this, the tags file
will contain one line per tag, with a tab separated structure:
tag-name<tab>tag-file<tab>tag-address
I am using the line number as the tag address.
To generate a tags file:
retro-tags
Tags for variables, constants, and data structures are not
always identified correctly. Specifically:
'foo d:create .... <- not identified
#1 'foo const #2 'bar const <- only the last is identified
'foo var 'bar var <- only the last is identified
For these, this assumes one name defined per line, with nothing
following. Better detection and handling of this is left open
for a future project.
To start, I bring in the retro-unu tool to locate the code
blocks and call a combinator for each line in the code block.
This one is extended to keep track of the tag address and
file name as well.
~~~'TagAddress var
'TagFile var
{{
'Fenced var
:toggle-fence @Fenced not !Fenced ;
:fenced? (-f) @Fenced ;
:handle-line (s-)
fenced? [ over call ] [ drop ] choose ;
:prepare
#0 !TagAddress over s:keep !TagFile ;
---reveal---
:unu (sq-)
prepare
swap [ &TagAddress v:inc
dup '~~~ s:eq?
[ drop toggle-fence ]
[ handle-line ] choose
] file:for-each-line drop ;
}}
~~~
Next, identification of things to tag begins. This will use
multiple passes of the source file.
First, colon definitions.
~~~:colon-definition?
dup ': s:begins-with? ;
:output-location
tab @TagFile #2 + s:put tab @TagAddress n:put nl ;
:output-name
ASCII:SPACE s:tokenize #0 a:fetch n:inc s:put ;
#0 script:get-argument [ s:trim colon-definition? &drop -if; output-name output-location ] unu
~~~
Then variables.
~~~:variable?
dup 'var s:ends-with? over 'var-n s:ends-with? or ;
:output-name
ASCII:SPACE s:tokenize dup a:length #2 - a:fetch n:inc s:put ;
#0 script:get-argument [ s:trim variable? &drop -if; output-name output-location ] unu
~~~
Constants.
~~~:constant?
dup 'const s:ends-with? ;
:output-name
ASCII:SPACE s:tokenize dup a:length #2 - a:fetch n:inc s:put ;
#0 script:get-argument [ s:trim constant? &drop -if; output-name output-location ] unu
~~~
And finally, words made with d:create:
~~~:created?
dup 'd:create s:ends-with? ;
:output-name
ASCII:SPACE s:tokenize dup a:length #2 - a:fetch n:inc s:put ;
#0 script:get-argument [ s:trim created? &drop -if; output-name output-location ] unu
~~~