source: project/wiki/eggref/5/premodules @ 38715

Last change on this file since 38715 was 38715, checked in by juergen, 8 months ago

premodules docu fixed

File size: 8.3 KB
Line 
1[[tags: egg]]
2[[toc:]]
3
4== Rationale
5
6Writing code is fun, writing documentation is not. Since comments are
7obligatory in the code, it would be nice, if documentation could be
8generated automatically from these comments. This is exactly what this
9module does: It creates modules, documentation and tests from so called
10premodules, which differ from modules insofar, that there is
11
12- no license
13- no export-clause
14- no documentation routine
15
16Instead, those texts are inserted automatically into the final module,
17as well as into the final documentation, using special comment clauses
18#|[ and ]|# each on a line by itself
19
20Note, that #| and |# delimit multiline comments in Chicken, so the
21spezial clauses above are consistent with chicken syntax.
22
23A standardized routine comment looks like this
24
25  #|[
26  (name . args)
27  ...
28  --- type ---
29  doc
30  ...
31  ]|#
32
33where type is one of procedure, macro or parameter and is enclosed in at
34least three hyphens on each side
35
36Note, that this comment is placed immediately before the routine's
37implemenatation, so if the implementation changes signature, the documentation
38will probably change too. Hence the procedurally created documenation
39will always be up to date.
40
41Note also, that only exported routines will be commented like this, so
42the export clause can be generated automatically.
43
44Other standardized comments begin with at least three semicolons and end
45with at least three semicolons. For example, the body of a premodule starts
46with
47
48;;;;;;;;;;;; module loops ;;;;;;;;;;;
49
50and ends with the start of the internal and exported tests
51
52;;;;;;;;;;;;;;;;;;;; tests ;;;;;;;;;;;;;;;;;;;;
53
54Everything before the module-line is a global Scheme comment and should
55be encoded as a comment, it will be extended with a copyright notice.
56
57Everything after the test-line with the closing parenthesis is test code,
58some of it internal, some exported.
59
60Exported tests are implemented with define-checks, internal tests with
61one of the ppp macros or check frome the simple-tests egg. The former go
62into the automatically generated run.scm and the documentation files,
63the latter are only invoked in the process of coding and ignored in the
64generated code.
65
66=== API
67
68Besides the documentation procedure, premodules, there are only three
69exported procedures, premodule->module, premodule->tests and
70premodule->docs.
71
72==== premodules
73
74<procedure>(premodules)</procedure>
75<procedure>(premodules sym)</procedure>
76
77the former returns the list of the two exported symbols,
78and the latter documentation of such a symbol.
79
80==== premodule->module
81
82<procedure>(premodule->module pre-file module-file)</procedure>
83
84writes the module file from the premodule file.
85
86==== premodule->tests
87
88<procedure>(premodule->tests pre-file test-file)</procedure>
89
90writes the test file from the premodule file.
91
92==== premodule->docs
93
94<procedure>(premodule->docs pre-file doc-file)</procedure>
95
96writes the documentation file from the premodule file.
97
98=== Example
99
100The following is a premodule version of my simple-loops egg.
101It's called preloops.scm
102
103<enscript highlight=scheme>
104
105#|[
106some simple loop macros
107]|#
108
109;;;;;;;;;;;; module loops ;;;;;;;;;;;
110
111(import scheme
112        (chicken base))
113
114#|[
115(do-times i upto xpr ....)
116--- macro ---
117loops a fixed number of times
118execute xpr .... for i from 0 to upto
119]|#
120(define-syntax do-times
121  (syntax-rules ()
122    ((_ i upto xpr0 xpr1 ...)
123     (let ((n upto))
124         (let loop ((i 0))
125           (unless (>= i n)
126             xpr0 xpr1 ...
127             (loop (+ i 1))))))))
128
129#|[
130(do-list i lst xpr ....)
131--- macro ---
132execute xpr .... for i in lst
133]|#
134(define-syntax do-list
135  (syntax-rules ()
136    ((_ i lst xpr xpr1 ...)
137    (let loop ((sublst lst))
138      (if (not (null? sublst))
139        (let ((i (car sublst)))
140          xpr xpr1 ...
141          (loop (cdr sublst))))))))
142
143#|[
144(do-for var (start stop step) xpr ....)
145--- macro ---
146do xpr .... for var in [start stop[ with steps (default 1)
147]|#
148(define-syntax do-for
149  (syntax-rules ()
150    ((_ var (start stop step) xpr xpr1 ...)
151       (let ((%stop stop))
152         (let loop ((var start))
153           (unless (>= var %stop)
154             xpr xpr1 ...
155             (loop (+ step var))))))
156    ((_ var (start stop) xpr . xprs)
157     (do-for var (start stop 1) xpr . xprs))))
158
159#|[
160(do-while test? xpr ....)
161--- macro ---
162execute xpr .... while test? is true
163]|#
164(define-syntax do-while
165  (syntax-rules ()
166    ((_ test? xpr xpr1 ...)
167     (let loop ()
168       (if test?
169         (begin
170           xpr xpr1 ...
171           (loop)))))))
172
173#|[
174(do-until test? xpr ....)
175--- macro ---
176execute xpr .... while test? is false
177]|#
178(define-syntax do-until
179  (syntax-rules ()
180    ((_ test? xpr xpr1 ...)
181     (let loop ()
182       (if (not test?)
183         (begin
184           xpr xpr1 ...
185           (loop)))))))
186
187#|[
188(do-forever xpr ....)
189--- macro ---
190executes body xpr .... until exit is called.
191The macro is unhygienic on purpose,
192it exports the exit symbol behind the scene.
193So it can not be defined with syntax-rules
194]|#
195(define-syntax do-forever
196  (ir-macro-transformer
197    (lambda (form inject compare?)
198      (let ((xpr (cadr form)) (xprs (cddr form)))
199        `(call-with-current-continuation
200           (lambda (,(inject 'exit))
201             (let loop ()
202               ,xpr
203               ,@xprs
204               (loop))))))))
205
206;;;;;;;;;;;;;;;;;;;; tests ;;;;;;;;;;;;;;;;;;;;
207
208;; to be exported
209(import simple-tests)
210
211;; to be skipped
212(ppp
213  (car '(0 1 2 3))
214  )
215
216;; to be skipped
217(check ((lst '(0 1 2 3)))
218  lst
219  '(0 1 2 3)
220  (car lst)
221  0
222  (cadr lst)
223  1
224  (cddr lst)
225  '(2 3)
226  )
227
228;; to be exported
229(define-checks (dos verbose?)
230
231  (let ((lst '()))
232    (do-for i (1 65 i) (set! lst (cons i lst)))
233    (reverse lst))
234  '(1 2 4 8 16 32 64)
235
236  (let ((n 3) (lst '()))
237    (do-forever
238      (if (zero? n) (exit lst))
239      (set! lst (cons 'a lst))
240      (set! n (- n 1))))
241  '(a a a)
242
243  (let ((lst '()))
244    (do-list i '(1 2 3)
245      (set! lst (cons i lst)))
246    lst)
247  '(3 2 1)
248
249  (let ((lst '()))
250    (do-times i (+ 2 3)
251      (set! lst (cons i lst)))
252    lst)
253  '(4 3 2 1 0)
254
255  (let ((n 4) (lst '()))
256    (do-until (> 0 n)
257      (set! lst (cons n lst))
258      (set! n (- n 1)))
259    lst)
260  '(0 1 2 3 4)
261
262  (let ((n 4) (lst '()))
263    (do-while (<= 0 n)
264      (set! lst (cons n lst))
265      (set! n (- n 1)))
266    lst)
267  '(0 1 2 3 4)
268  )
269
270</enscript>
271
272Note, that this is a normal Scheme file, you can run it and look at the
273result of the internal and exported tests.
274
275The following three calls will write the desired files, loops.scm, run.scm and
276loops. The only thing you have to do is to copy the files to the
277appropriate positions. Of course, you can edit these files, if the need
278arises.
279
280<enscript highligth=scheme>
281
282(premodule->module "preloops.scm" "loops.scm")
283(premodule->tests "preloops.scm" "run.scm")
284(premodule->docs "preloops.scm" "loops")
285
286</enscript>
287
288== Requirements
289
290simple-tests
291
292== Last update
293
294May 26, 2020
295
296== Author
297
298Juergen Lorenz
299
300== License
301
302Copyright (c) 2020 , Juergen Lorenz, ju (at) jugilo (dot) de
303All rights reserved.
304
305Redistribution and use in source and binary forms, with or without
306modification, are permitted provided that the following conditions are
307met:
308
309Redistributions of source code must retain the above copyright
310notice, this list of conditions and the following disclaimer.
311
312Redistributions in binary form must reproduce the above copyright
313notice, this list of conditions and the following disclaimer in the
314documentation and/or other materials provided with the distribution.
315Neither the name of the author nor the names of its contributors may be
316used to endorse or promote products derived from this software without
317specific prior written permission.
318 
319THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
320IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
321TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
322PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
323HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
324SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
325TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
326PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
327LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
328NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
329SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
330
331== Version history
332; 0.1 : Initial check in
Note: See TracBrowser for help on using the repository browser.