-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdocgen.fs
143 lines (115 loc) · 3.39 KB
/
docgen.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
0 warnings !
( argv0 ) constant input-file-len
( count ) constant input-file
require string.fs
require list.fs
require fp.fs
also list.fs
also string.fs
also fp.fs
0
dup constant doc:word cell +
dup constant doc:comment cell +
dup constant doc:stack-effect cell +
constant doc:struct
variable fd
variable src
variable #src
: read begin here 4096 fd @ read-file throw dup allot 0= until ;
: open input-file input-file-len r/o open-file throw fd ! ;
: close fd @ close-file throw ;
: start here src ! ;
: finish here src @ - #src ! ;
: load-file open start read finish close src @ #src @ ;
\ returns a string marking the beginning of a docgen item; newline followed by a "\" character.
: docgen-marker s\" \n\\ " string:create ;
: doc-allot here doc:struct allot ;
\ Make a doc:struct from the provided word-name, comment and stack-effect
: doc-make ( word-name comment stack-effect -- doc )
doc-allot dup >r doc:stack-effect + ! r@ doc:comment + ! r@ doc:word + ! r> ;
: doc-render-title ( caddr u -- )
." ## require " input-file input-file-len 2dup type ." also " type cr cr ;
\ Takes a doc:struct and prints it in markdown
: doc-render-item ( doc -- )
." ### `" dup doc:word + @ string:print space
dup doc:stack-effect + @ string:print ." `" cr
doc:comment + @ string:print cr cr
;
\ return the index of docgen marker from the given source string
: find-docgen-marker ( src -- index ) docgen-marker string:index-of ;
variable src
variable index
: parse-comment
index ! src !
src @ index @ src @ string:length + @ string:substring src !
\ find index of char after newline
src @ 10 string:from-char string:index-of 1+ index !
src @ index @
src @ 0 index @ string:substring
;
variable src
variable index
variable index1
variable index2
: parse-word-name
index ! src !
\ skip newline and comma after comment line
index @ 2 + index !
src @ index @ src @ string:length + @ string:substring src !
\ find index of space or newline
src @ 32 string:from-char string:index-of index1 !
src @ 10 string:from-char string:index-of index2 !
\ use nearest
index1 @ index2 @ min index !
src @ index @
src @ 0 index @ 1+ string:substring
;
variable src
variable index
: parse-stack-effect
index ! src !
index @ 1+ index !
\ if not "(" then exit early
src @ index @ string:nth 40 <> if src @ index @ s" " string:create exit then
src @ index @ src @ string:length + @ string:substring src !
src @ 41 string:from-char string:index-of 2 + index !
src @ index @
src @ 0 index @ string:substring
;
: doc-render
doc-render-title
['] doc-render-item over list:for-each ;
variable src
variable word-list
variable index
variable comment
variable word-name
variable stack-effect
variable doc
: parse-words
word-list ! src !
begin
src @ find-docgen-marker index !
index @ -1 <>
while
\ skip over the marker
index @ docgen-marker string:length + @ + index !
src @ index @ parse-comment comment ! index ! src !
src @ index @ parse-word-name word-name ! index ! src !
src @ index @ parse-stack-effect stack-effect ! index ! src !
word-name @ comment @ stack-effect @ doc-make doc !
word-list @ doc @ list:append
repeat
;
variable src
variable #src
variable word-list
: docgen
load-file #src ! src !
src @ #src @ string:create src !
list:create word-list !
src @ word-list @ parse-words
word-list @ doc-render @
;
docgen
bye