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

Last change on this file since 39537 was 39537, checked in by juergen, 5 months ago

premodules 0.6 docu

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