mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-20 14:19:18 +02:00
Parsing literal docs for FFI files, generating docs for all core modules (mostly stubs).
This commit is contained in:
parent
541d7f4550
commit
2b86320652
8 changed files with 364 additions and 152 deletions
8
Makefile
8
Makefile
|
@ -169,11 +169,13 @@ lib/%$(SO): lib/%.c $(INCLUDES)
|
||||||
$(CHIBI) tools/chibi-doc $< > $@
|
$(CHIBI) tools/chibi-doc $< > $@
|
||||||
|
|
||||||
doc/lib/chibi/%.html: lib/chibi/%.module tools/chibi-doc chibi-scheme$(EXE)
|
doc/lib/chibi/%.html: lib/chibi/%.module tools/chibi-doc chibi-scheme$(EXE)
|
||||||
$(CHIBI) tools/chibi-doc $< > $@
|
$(CHIBI) tools/chibi-doc chibi.$* > $@
|
||||||
|
|
||||||
MODULE_DOCS := doc/lib/chibi/match.html
|
MODULE_DOCS := ast disasm equiv filesystem generic heap-stats io loop \
|
||||||
|
match mime modules net pathname process repl scribble stty \
|
||||||
|
system test time type-inference uri weak
|
||||||
|
|
||||||
doc: doc/chibi.html $(MODULE_DOCS)
|
doc: doc/chibi.html $(MODULE_DOCS:%=doc/lib/chibi/%.html)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.i *.s *.8
|
rm -f *.o *.i *.s *.8
|
||||||
|
|
115
doc/chibi.scrbl
115
doc/chibi.scrbl
|
@ -963,117 +963,52 @@ SRFIs used in standard Chibi modules
|
||||||
Additional non-standard modules are put in the @scheme{(chibi)} module
|
Additional non-standard modules are put in the @scheme{(chibi)} module
|
||||||
namespace.
|
namespace.
|
||||||
|
|
||||||
@subsection{Internals Interface}
|
@itemlist[
|
||||||
|
|
||||||
The @scheme{(chibi ast)} module provides access to the Abstract Syntax Tree and
|
@item{@hyperlink["lib/chibi/ast.html"]{(chibi ast) - Abstract Syntax Tree and other internal data types}}
|
||||||
other internal data structures not typically needed for everyday programs.
|
|
||||||
|
|
||||||
@subsection{Disassember}
|
@item{@hyperlink["lib/chibi/disasm.html"]{(chibi disasm) - Disassembler for the virtual machine}}
|
||||||
|
|
||||||
The @scheme{(chibi disasm)} module provides a disassembler for the virtual
|
@item{@hyperlink["lib/chibi/equiv.html"]{(chibi equiv) - A version of @scheme{equal?} which is guaranteed to terminate}}
|
||||||
machine.
|
|
||||||
|
|
||||||
@subsection{Printed Equivalence}
|
@item{@hyperlink["lib/chibi/filesystem.html"]{(chibi filesystem) - Interface to the filesystem and file descriptor objects}}
|
||||||
|
|
||||||
The @scheme{(chibi equiv)} module provides the @scheme{equiv?} procedure, which
|
@item{@hyperlink["lib/chibi/generic.html"]{(chibi generic) - Generic methods for CLOS-style object oriented programming}}
|
||||||
is similar to @scheme{equal?} but is guaranteed to terminate. It takes two
|
|
||||||
arguments and returns true iff they would print the same using SRFI-38 style
|
|
||||||
read/write syntax.
|
|
||||||
|
|
||||||
@subsection{Filesystem Interface}
|
@item{@hyperlink["lib/chibi/heap-stats.html"]{(chibi heap-stats) - Utilities for gathering statistics on the heap}}
|
||||||
|
|
||||||
The @scheme{(chibi filesystem)} module provides access to the filesystem and
|
@item{@hyperlink["lib/chibi/io.html"]{(chibi io) - Various I/O extensions and custom ports}}
|
||||||
file descriptor objects.
|
|
||||||
|
|
||||||
@subsection{Generic Functions}
|
@item{@hyperlink["lib/chibi/loop.html"]{(chibi loop) - Fast and extensible loop syntax}}
|
||||||
|
|
||||||
The @scheme{(chibi generic)} module provides generic methods for CLOS-style
|
@item{@hyperlink["lib/chibi/match.html"]{(chibi match) - Intuitive and widely supported pattern matching syntax}}
|
||||||
object oriented programming.
|
|
||||||
|
|
||||||
@subsection{Heap Introspection}
|
@item{@hyperlink["lib/chibi/mime.html"]{(chibi mime) - Parse MIME files into SXML}}
|
||||||
|
|
||||||
The @scheme{(chibi heap-stats)} module provides utilities for gathering
|
@item{@hyperlink["lib/chibi/modules.html"]{(chibi modules) - Introspection for the module system itself}}
|
||||||
statistics on the heap.
|
|
||||||
|
|
||||||
@subsection{Input/Output Extensions}
|
@item{@hyperlink["lib/chibi/net.html"]{(chibi net) - Simple networking interface}}
|
||||||
|
|
||||||
The @scheme{(chibi io)} module provides various I/O extensions, including
|
@item{@hyperlink["lib/chibi/pathname.html"]{(chibi pathname) - Utilities to decompose and manipulate pathnames}}
|
||||||
custom ports.
|
|
||||||
|
|
||||||
@subsection{Extensible Loop Syntax}
|
@item{@hyperlink["lib/chibi/process.html"]{(chibi process) - Interface to spawn processes and handle signals}}
|
||||||
|
|
||||||
The @scheme{(chibi loop)} module provides a fast and extensible loop syntax.
|
@item{@hyperlink["lib/chibi/repl.html"]{(chibi repl) - A full-featured Read/Eval/Print Loop}}
|
||||||
|
|
||||||
@subsection{Pattern-Matching}
|
@item{@hyperlink["lib/chibi/scribble.html"]{(chibi scribble) - A parser for the scribble syntax used to write this manual}}
|
||||||
|
|
||||||
The @scheme{(chibi match)} module provides an intuitive and widely supported
|
@item{@hyperlink["lib/chibi/stty.html"]{(chibi stty) - A high-level interface to ioctl}}
|
||||||
pattern matching syntax.
|
|
||||||
|
|
||||||
@subsection{RFC2045 MIME}
|
@item{@hyperlink["lib/chibi/system.html"]{(chibi system) - Access to the host system and current user information}}
|
||||||
|
|
||||||
The @scheme{(chibi mime)} module provides utilities for parsing MIME
|
@item{@hyperlink["lib/chibi/test.html"]{(chibi test) - A simple unit testing framework}}
|
||||||
files into an SXML format.
|
|
||||||
|
|
||||||
@subsection{Module Introspection}
|
@item{@hyperlink["lib/chibi/time.html"]{(chibi time) - An interface to the current system time}}
|
||||||
|
|
||||||
The @scheme{(chibi modules)} module provides introspection utilities for the
|
@item{@hyperlink["lib/chibi/type-inference.html"]{(chibi type-inference) - An easy-to-use type inference system}}
|
||||||
module system itself.
|
|
||||||
|
|
||||||
@subsection{Networking Interface}
|
@item{@hyperlink["lib/chibi/uri.html"]{(chibi uri) - Utilities to parse and construct URIs}}
|
||||||
|
|
||||||
The @scheme{(chibi net)} module provides a simple networking interface.
|
@item{@hyperlink["lib/chibi/weak.html"]{(chibi weak) - Data structures with weak references}}
|
||||||
|
|
||||||
@subsection{Pathname Utilities}
|
|
||||||
|
|
||||||
The @scheme{(chibi pathname)} module provides utilities to decompose and
|
|
||||||
manipulate pathnames.
|
|
||||||
|
|
||||||
@subsection{Processes and Signals}
|
|
||||||
|
|
||||||
The @scheme{(chibi process)} module provides utilities to spawn processes and
|
|
||||||
send and handle signals between processes.
|
|
||||||
|
|
||||||
@subsection{Read/Eval/Print Loop}
|
|
||||||
|
|
||||||
The @scheme{(chibi repl)} module provides a more full-featured repl than the
|
|
||||||
chibi-scheme executable.
|
|
||||||
|
|
||||||
@subsection{Scribble Syntax}
|
|
||||||
|
|
||||||
The @scheme{(chibi scribble)} module provides a parser for the scribble syntax
|
|
||||||
used to write this manual.
|
|
||||||
|
|
||||||
@subsection{Stty Interface}
|
|
||||||
|
|
||||||
The @scheme{(chibi stty)} provides a high-level interface to ioctl.
|
|
||||||
|
|
||||||
@subsection{System Information}
|
|
||||||
|
|
||||||
The @scheme{(chibi system)} module provides access to the host system and
|
|
||||||
current user information.
|
|
||||||
|
|
||||||
@subsection{Line Editing}
|
|
||||||
|
|
||||||
The @scheme{(chibi term edit-line)} provides an @scheme{edit-line} procedure
|
|
||||||
for interactive line editing.
|
|
||||||
|
|
||||||
@subsection{Testing}
|
|
||||||
|
|
||||||
The @scheme{(chibi test)} provides a simple unit testing framework.
|
|
||||||
|
|
||||||
@subsection{Times and Dates}
|
|
||||||
|
|
||||||
The @scheme{(chibi time)} provides an interface to the current system time.
|
|
||||||
|
|
||||||
@subsection{Type Inference}
|
|
||||||
|
|
||||||
The @scheme{(chibi type-inference)} is an easy-to-use type inference system.
|
|
||||||
|
|
||||||
@subsection{URI Utilities}
|
|
||||||
|
|
||||||
The @scheme{(chibi uri)} module provides utilities to parse and construct URIs.
|
|
||||||
|
|
||||||
@subsection{Weak References}
|
|
||||||
|
|
||||||
The @scheme{(chibi weak)} module provides data structures with weak references.
|
|
||||||
|
|
||||||
|
]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<html><head>
|
<html><head><title>(chibi match)</title>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {color: #000; background-color: #FFF}
|
body {color: #000; background-color: #FFF}
|
||||||
div#menu {font-size: smaller; position: absolute; top: 0; left: 0; width: 180px; height: 100%}
|
div#menu {font-size: smaller; position: absolute; top: 50px; left: 0; width: 180px; height: 100%}
|
||||||
div#menu ol {margin-left: 10px; padding-left: 10px}
|
|
||||||
div#main {position: absolute; top: 0; left: 200px; width: 520px; height: 100%}
|
div#main {position: absolute; top: 0; left: 200px; width: 520px; height: 100%}
|
||||||
div#notes {position: relative; top: 2em; left: 550px; max-width: 200px; height: 0px; font-size: smaller;}
|
div#notes {position: relative; top: 2em; left: 550px; max-width: 200px; height: 0px; font-size: smaller;}
|
||||||
|
div#footer {padding-bottom: 50px}
|
||||||
.result { color: #000; background-color: #FFEADF; width: 100%; padding: 3px}
|
.result { color: #000; background-color: #FFEADF; width: 100%; padding: 3px}
|
||||||
.command { color: #000; background-color: #FFEADF; width: 100%; padding: 5px}
|
.command { color: #000; background-color: #FFEADF; width: 100%; padding: 5px}
|
||||||
.keyword { color: #800080; background-color: inherit; }
|
.keyword { color: #800080; background-color: inherit; }
|
||||||
|
@ -27,8 +27,162 @@ span.paren4 { color: #444444; background-color: inherit; }
|
||||||
span.paren5 { color: #222222; background-color: inherit; }
|
span.paren5 { color: #222222; background-color: inherit; }
|
||||||
span.paren6 { color: #000000; background-color: inherit; }
|
span.paren6 { color: #000000; background-color: inherit; }
|
||||||
</style>
|
</style>
|
||||||
</head><body><div id="menu"></div><div id="main"><p>(module (chibi match)
|
</head><body><div id="menu"><ol><li><a href="#h3_Patterns">Patterns</a></li><li><a href="#h3_Syntax">Syntax</a><ol><li><a href="#h4_(matchexpr(pattern.body)...)(matchexpr(pattern(=>failure).body)...)">(match expr (pattern . body) ...)
|
||||||
(export match match-lambda match-lambda* match-let match-letrec match-let*)
|
(match expr (pattern (=> failure) . body) ...)</a></li><li><a href="#h4_match-lambda">(match-lambda (pattern . body) ...)</a></li><li><a href="#h4_match-lambda*">(match-lambda* (pattern . body) ...)</a></li><li><a href="#h4_match-let">(match-let ((var value) ...) . body)(match-let loop ((var init) ...) . body)</a></li><li><a href="#h4_match-letrec">(match-letrec ((var value) ...) . body)</a></li><li><a href="#h4_(match-let*((varvalue)...)body...)">(match-let* ((var value) ...) body ...)</a></li></ol></li></ol></div><div id="main"><h1>(chibi match)</h1><p>
|
||||||
(import-immutable (scheme))
|
This is a full superset of the popular <a href="http://www.cs.indiana.edu/scheme-repository/code.match.html">match</a>
|
||||||
(include "match/match.scm"))
|
package by Andrew Wright, written in fully portable <code><span>syntax-rules</span></code>
|
||||||
</p></div></body></html>
|
and thus preserving hygiene.
|
||||||
|
The most notable extensions are the ability to use <em>non-linear</em>
|
||||||
|
patterns - patterns in which the same identifier occurs multiple
|
||||||
|
times, tail patterns after ellipsis, and the experimental tree patterns.
|
||||||
|
</p><div><a name="h3_Patterns"></a><h3>Patterns</h3></div><p>
|
||||||
|
Patterns are written to look like the printed representation of
|
||||||
|
the objects they match. The basic usage is
|
||||||
|
<code>(<span class="keyword">match</span> <span>expr</span> (pat <span>body</span> <span>...</span>) <span>...</span>)</code>
|
||||||
|
where the result of <code>expr</code> is matched against each pattern in
|
||||||
|
turn, and the corresponding body is evaluated for the first to
|
||||||
|
succeed. Thus, a list of three elements matches a list of three
|
||||||
|
elements.
|
||||||
|
</p><div><pre><code>(<span class="keyword">let</span> ((ls (list <span>1</span> <span>2</span> <span>3</span>))) (<span class="keyword">match</span> <span>ls</span> ((1 <span>2</span> <span>3</span>) #)))</code></pre><code><div class="result">=> #t</div></code></div><p>
|
||||||
|
If no patterns match an error is signalled.
|
||||||
|
Identifiers will match anything, and make the corresponding
|
||||||
|
binding available in the body.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span>) ((a <span>b</span> <span>c</span>) <span>b</span>))</code></pre><code><div class="result">=> 2</div></code></div><p>
|
||||||
|
If the same identifier occurs multiple times, the first instance
|
||||||
|
will match anything, but subsequent instances must match a value
|
||||||
|
which is <code><span>equal?</span></code> to the first.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>1</span>) ((a <span>a</span> <span>b</span>) <span>1</span>) ((a <span>b</span> <span>a</span>) <span>2</span>))</code></pre><code><div class="result">=> 2</div></code></div><p>
|
||||||
|
The special identifier <code><span>_</span></code> matches anything, no matter how
|
||||||
|
many times it is used, and does not bind the result in the body.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>1</span>) ((_ <span>_</span> <span>b</span>) <span>1</span>) ((a <span>b</span> <span>a</span>) <span>2</span>))</code></pre><code><div class="result">=> 1</div></code></div><p>
|
||||||
|
To match a literal identifier (or list or any other literal), use
|
||||||
|
<code><span>quote</span></code>.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> '<span>a</span> ('<span>b</span> <span>1</span>) ('<span>a</span> <span>2</span>))</code></pre><code><div class="result">=> 2</div></code></div><p>
|
||||||
|
Analogous to its normal usage in scheme, <code><span>quasiquote</span></code> can
|
||||||
|
be used to quote a mostly literally matching object with selected
|
||||||
|
parts unquoted.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span>) (`(1 ,<span>b</span> ,<span>c</span>) (list <span>b</span> <span>c</span>)))</code></pre><code><div class="result">=> (2 3)</div></code></div><p>
|
||||||
|
Often you want to match any number of a repeated pattern. Inside
|
||||||
|
a list pattern you can append <code><span>...</span></code> after an element to
|
||||||
|
match zero or more of that pattern (like a regexp Kleene star).
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span>) ((1 <span>2</span> <span>3</span> <span>...</span>) #))</code></pre><code><div class="result">=> #t</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span>) ((1 <span>2</span> <span>3</span> <span>...</span>) #))</code></pre><code><div class="result">=> #t</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span> <span>3</span> <span>3</span>) ((1 <span>2</span> <span>3</span> <span>...</span>) #))</code></pre><code><div class="result">=> #t</div></code></div><p>
|
||||||
|
Pattern variables matched inside the repeated pattern are bound to
|
||||||
|
a list of each matching instance in the body.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span>) ((a <span>b</span> <span>c</span> <span>...</span>) <span>c</span>))</code></pre><code><div class="result">=> ()</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span>) ((a <span>b</span> <span>c</span> <span>...</span>) <span>c</span>))</code></pre><code><div class="result">=> (3)</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span>) ((a <span>b</span> <span>c</span> <span>...</span>) <span>c</span>))</code></pre><code><div class="result">=> (3 4 5)</div></code></div><p>
|
||||||
|
More than one <code><span>...</span></code> may not be used in the same list, since
|
||||||
|
this would require exponential backtracking in the general case.
|
||||||
|
However, <code><span>...</span></code> need not be the final element in the list,
|
||||||
|
and may be succeeded by a fixed number of patterns.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span> <span>4</span>) ((a <span>b</span> <span>c</span> <span>...</span> <span>d</span> <span>e</span>) <span>c</span>))</code></pre><code><div class="result">=> ()</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span>) ((a <span>b</span> <span>c</span> <span>...</span> <span>d</span> <span>e</span>) <span>c</span>))</code></pre><code><div class="result">=> (3)</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> <span>6</span> <span>7</span>) ((a <span>b</span> <span>c</span> <span>...</span> <span>d</span> <span>e</span>) <span>c</span>))</code></pre><code><div class="result">=> (3 4 5)</div></code></div><p>
|
||||||
|
<code><span>___</span></code> is provided as an alias for <code><span>...</span></code> when it is
|
||||||
|
inconvenient to use the ellipsis (as in a syntax-rules template).
|
||||||
|
The <code><span>..1</span></code> syntax is exactly like the <code><span>...</span></code> except
|
||||||
|
that it matches one or more repetitions (like a regexp "+").
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span>) ((a <span>b</span> <span>c</span> <span>..1</span>) <span>c</span>))</code></pre><code><div class="result">ERROR: match: "no matching pattern"
|
||||||
|
</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> (list <span>1</span> <span>2</span> <span>3</span>) ((a <span>b</span> <span>c</span> <span>..1</span>) <span>c</span>))</code></pre><code><div class="result">=> (3)</div></code></div><p>
|
||||||
|
The boolean operators <code><span>and</span></code>, <code><span>or</span></code> and <code><span>not</span></code>
|
||||||
|
can be used to group and negate patterns analogously to their
|
||||||
|
Scheme counterparts.
|
||||||
|
The <code><span>and</span></code> operator ensures that all subpatterns match.
|
||||||
|
This operator is often used with the idiom <code>(and <span>x</span> <span>pat</span>)</code> to
|
||||||
|
bind <code>x</code> to the entire value that matches <code>pat</code>
|
||||||
|
(c.f. "as-patterns" in ML or Haskell). Another common use is in
|
||||||
|
conjunction with <code><span>not</span></code> patterns to match a general case
|
||||||
|
with certain exceptions.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> <span>1</span> ((and) #))</code></pre><code><div class="result">=> #t</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> <span>1</span> ((and <span>x</span>) <span>x</span>))</code></pre><code><div class="result">=> 1</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> <span>1</span> ((and <span>x</span> <span>1</span>) <span>x</span>))</code></pre><code><div class="result">=> 1</div></code></div><p>
|
||||||
|
The <code><span>or</span></code> operator ensures that at least one subpattern
|
||||||
|
matches. If the same identifier occurs in different subpatterns,
|
||||||
|
it is matched independently. All identifiers from all subpatterns
|
||||||
|
are bound if the <code><span>or</span></code> operator matches, but the binding is
|
||||||
|
only defined for identifiers from the subpattern which matched.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> <span>1</span> ((or) #) (<span class="keyword">else</span> #))</code></pre><code><div class="result">=> #f</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> <span>1</span> ((or <span>x</span>) <span>x</span>))</code></pre><code><div class="result">=> 1</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> <span>1</span> ((or <span>x</span> <span>2</span>) <span>x</span>))</code></pre><code><div class="result">=> 1</div></code></div><p>
|
||||||
|
The <code><span>not</span></code> operator succeeds if the given pattern doesn't
|
||||||
|
match. None of the identifiers used are available in the body.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> <span>1</span> ((not <span>2</span>) #))</code></pre><code><div class="result">=> #t</div></code></div><p>
|
||||||
|
The more general operator <code><span>?</span></code> can be used to provide a
|
||||||
|
predicate. The usage is <code>(? <span>predicate</span> <span>pat</span> <span>...</span>)</code> where
|
||||||
|
<code>predicate</code> is a Scheme expression evaluating to a predicate
|
||||||
|
called on the value to match, and any optional patterns after the
|
||||||
|
predicate are then matched as in an <code><span>and</span></code> pattern.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> <span>1</span> ((? <span>odd?</span> <span>x</span>) <span>x</span>))</code></pre><code><div class="result">=> 1</div></code></div><p>
|
||||||
|
The field operator <code><span>=</span></code> is used to extract an arbitrary
|
||||||
|
field and match against it. It is useful for more complex or
|
||||||
|
conditional destructuring that can't be more directly expressed in
|
||||||
|
the pattern syntax. The usage is <code>(= <span>field</span> <span>pat</span>)</code>, where
|
||||||
|
<code>field</code> can be any expression, and should result in a
|
||||||
|
procedure of one argument, which is applied to the value to match
|
||||||
|
to generate a new value to match against <code>pat</code>.
|
||||||
|
Thus the pattern <code>(and (= <span>car</span> <span>x</span>) (= <span>cdr</span> <span>y</span>))</code> is equivalent
|
||||||
|
to <code>(x <span>.</span> <span>y</span>)</code>, except it will result in an immediate error
|
||||||
|
if the value isn't a pair.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> '(1 <span>.</span> <span>2</span>) ((= <span>car</span> <span>x</span>) <span>x</span>))</code></pre><code><div class="result">=> 1</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> <span>4</span> ((= <span>sqrt</span> <span>x</span>) <span>x</span>))</code></pre><code><div class="result">=> 2</div></code></div><p>
|
||||||
|
The record operator <code><span>$</span></code> is used as a concise way to match
|
||||||
|
records defined by SRFI-9 (or SRFI-99). The usage is
|
||||||
|
<code>($ <span>rtd</span> <span>field</span> <span>...</span>)</code>, where <code>rtd</code> should be the record
|
||||||
|
type descriptor specified as the first argument to
|
||||||
|
<code><span>define-record-type</span></code>, and each <code>field</code> is a subpattern
|
||||||
|
matched against the fields of the record in order. Not all fields
|
||||||
|
must be present.
|
||||||
|
</p><div><pre><code>(<span class="keyword">let</span> ()
|
||||||
|
(<span class="keyword">define-record-type</span> <span class="function">employee</span>
|
||||||
|
(make-employee <span>name</span> <span>title</span>)
|
||||||
|
<span>employee?</span>
|
||||||
|
(name <span>get-name</span>)
|
||||||
|
(title <span>get-title</span>))
|
||||||
|
(<span class="keyword">match</span> (make-employee <span class="string">"Bob"</span> <span class="string">"Doctor"</span>)
|
||||||
|
(($ <span>employee</span> <span>n</span> <span>t</span>) (list <span>t</span> <span>n</span>))))
|
||||||
|
</code></pre><code><div class="result">=> ("Doctor" "Bob")</div></code></div><p>
|
||||||
|
The <code><span>set!</span></code> and <code><span>get!</span></code> operators are used to bind an
|
||||||
|
identifier to the setter and getter of a field, respectively. The
|
||||||
|
setter is a procedure of one argument, which mutates the field to
|
||||||
|
that argument. The getter is a procedure of no arguments which
|
||||||
|
returns the current value of the field.
|
||||||
|
</p><div><pre><code>(<span class="keyword">let</span> ((x (cons <span>1</span> <span>2</span>))) (<span class="keyword">match</span> <span>x</span> ((1 <span>.</span> (<span class="keyword">set!</span> <span>s</span>)) (s <span>3</span>) <span>x</span>)))</code></pre><code><div class="result">=> (1 . 3)</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> '(1 <span>.</span> <span>2</span>) ((1 <span>.</span> (get! <span>g</span>)) (g)))</code></pre><code><div class="result">=> 2</div></code></div><p>
|
||||||
|
The new operator <code><span>***</span></code> can be used to search a tree for
|
||||||
|
subpatterns. A pattern of the form <code>(x <span>***</span> <span>y</span>)</code> represents
|
||||||
|
the subpattern <code>y</code> located somewhere in a tree where the path
|
||||||
|
from the current object to <code>y</code> can be seen as a list of the
|
||||||
|
form <code>(x <span>...</span>)</code>. <code>y</code> can immediately match the current
|
||||||
|
object in which case the path is the empty list. In a sense it's
|
||||||
|
a 2-dimensional version of the <code><span>...</span></code> pattern.
|
||||||
|
As a common case the pattern <code>(_ <span>***</span> <span>y</span>)</code> can be used to
|
||||||
|
search for <code>y</code> anywhere in a tree, regardless of the path
|
||||||
|
used.
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> '(a (a (a <span>b</span>))) ((x <span>***</span> '<span>b</span>) <span>x</span>))</code></pre><code><div class="result">=> (a a a)</div></code></div><p>
|
||||||
|
</p><div><pre><code>(<span class="keyword">match</span> '(a (b) (c (d <span>e</span>) (f <span>g</span>))) ((x <span>***</span> '<span>g</span>) <span>x</span>))</code></pre><code><div class="result">=> (a c f)</div></code></div><div><a name="h3_Syntax"></a><h3>Syntax</h3></div><p>
|
||||||
|
</p><div><a name="h4_(matchexpr(pattern.body)...)(matchexpr(pattern(=>failure).body)...)"></a><h4><code>(match expr (pattern . body) ...)<br></br>
|
||||||
|
(match expr (pattern (=> failure) . body) ...)</code></h4></div><p>
|
||||||
|
The result of <code>expr</code> is matched against each <code>pattern</code> in
|
||||||
|
turn, according to the pattern rules described in the previous
|
||||||
|
section, until the the first <code>pattern</code> matches. When a match is
|
||||||
|
found, the corresponding <code>body</code>s are evaluated in order,
|
||||||
|
and the result of the last expression is returned as the result
|
||||||
|
of the entire <code><span>match</span></code>. If a <code>failure</code> is provided,
|
||||||
|
then it is bound to a procedure of no arguments which continues,
|
||||||
|
processing at the next <code>pattern</code>. If no <code>pattern</code> matches,
|
||||||
|
an error is signalled.</p><div><a name="h4_match-lambda"></a><h4><code>(match-lambda (pattern . body) ...)</code></h4></div><p>Shortcut for <code><span>lambda</span></code> + <code><span>match</span></code>. Creates a
|
||||||
|
procedure of one argument, and matches that argument against each
|
||||||
|
clause.</p><div><a name="h4_match-lambda*"></a><h4><code>(match-lambda* (pattern . body) ...)</code></h4></div><p>Similar to <code><span>match-lambda</span></code>. Creates a procedure of any
|
||||||
|
number of arguments, and matches the argument list against each
|
||||||
|
clause.</p><div><a name="h4_match-let"></a><h4><code>(match-let ((var value) ...) . body)<br></br>(match-let loop ((var init) ...) . body)</code></h4></div><p>Matches each var to the corresponding expression, and evaluates
|
||||||
|
the body with all match variables in scope. Raises an error if
|
||||||
|
any of the expressions fail to match. Syntax analogous to named
|
||||||
|
let can also be used for recursive functions which match on their
|
||||||
|
arguments as in <code><span>match-lambda*</span></code>.</p><div><a name="h4_match-letrec"></a><h4><code>(match-letrec ((var value) ...) . body)</code></h4></div><p>Similar to <code><span>match-let</span></code>, but analogously to <code><span>letrec</span></code>
|
||||||
|
matches and binds the variables with all match variables in scope.</p><div><a name="h4_(match-let*((varvalue)...)body...)"></a><h4><code>(match-let* ((var value) ...) body ...)</code></h4></div><p>
|
||||||
|
Similar to <code><span>match-let</span></code>, but analogously to <code><span>let*</span></code>
|
||||||
|
matches and binds the variables in sequence, with preceding match
|
||||||
|
variables in scope.</p><div id="footer"></div></div></body></html>
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
(module (chibi modules)
|
(module (chibi modules)
|
||||||
(export module-name module-dir module-includes
|
(export module-name module-dir module-includes module-shared-includes
|
||||||
module-ast module-ast-set! module-ref module-contains?
|
module-ast module-ast-set! module-ref module-contains?
|
||||||
analyze-module containing-module load-module module-exports
|
analyze-module containing-module load-module module-exports
|
||||||
procedure-analysis)
|
procedure-analysis)
|
||||||
|
|
|
@ -30,19 +30,31 @@
|
||||||
""
|
""
|
||||||
(module-name-prefix name))))
|
(module-name-prefix name))))
|
||||||
|
|
||||||
|
(define (module-metas mod metas)
|
||||||
|
(let ((mod (if (module? mod) mod (find-module mod))))
|
||||||
|
(let lp ((ls (module-meta-data mod)) (res '()))
|
||||||
|
(cond
|
||||||
|
((not (pair? ls)) (reverse res))
|
||||||
|
((and (pair? (car ls)) (memq (caar ls) metas))
|
||||||
|
(lp (cdr ls) (append (reverse (cdar ls)) res)))
|
||||||
|
(else (lp (cdr ls) res))))))
|
||||||
|
|
||||||
(define (module-includes mod)
|
(define (module-includes mod)
|
||||||
(let* ((mod (if (module? mod) mod (find-module mod)))
|
(let* ((mod (if (module? mod) mod (find-module mod)))
|
||||||
(dir (module-dir mod)))
|
(dir (module-dir mod)))
|
||||||
(define (module-file f)
|
(define (module-file f)
|
||||||
(find-module-file (string-append dir f)))
|
(find-module-file (string-append dir f)))
|
||||||
(let lp ((ls (module-meta-data mod)) (res '()))
|
(map module-file (module-metas mod '(include)))))
|
||||||
(cond
|
|
||||||
((not (pair? ls))
|
(define (module-shared-includes mod)
|
||||||
(reverse res))
|
(let* ((mod (if (module? mod) mod (find-module mod)))
|
||||||
((and (pair? (car ls)) (eq? 'include (caar ls)))
|
(dir (module-dir mod)))
|
||||||
(lp (cdr ls) (append (map module-file (reverse (cdar ls))) res)))
|
(define (module-file f)
|
||||||
(else
|
(find-module-file (string-append dir f ".stub")))
|
||||||
(lp (cdr ls) res))))))
|
(let lp ((ls (module-metas mod '(include-shared))) (res '()))
|
||||||
|
(cond ((null? ls) (reverse res))
|
||||||
|
((module-file (car ls)) => (lambda (x) (lp (cdr ls) (cons x res))))
|
||||||
|
(else (lp (cdr ls) res))))))
|
||||||
|
|
||||||
(define (analyze-module-source name mod recursive?)
|
(define (analyze-module-source name mod recursive?)
|
||||||
(let ((env (module-env mod))
|
(let ((env (module-env mod))
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
signal/alarm signal/term signal/user1
|
signal/alarm signal/term signal/user1
|
||||||
signal/user2 signal/child signal/continue
|
signal/user2 signal/child signal/continue
|
||||||
signal/stop signal/tty-stop signal/tty-input
|
signal/stop signal/tty-stop signal/tty-input
|
||||||
signal/tty-output)
|
signal/tty-output wait/no-hang)
|
||||||
(import-immutable (scheme))
|
(import-immutable (scheme))
|
||||||
(cond-expand (threads (import (srfi 18))) (else #f))
|
(cond-expand (threads (import (srfi 18))) (else #f))
|
||||||
(include-shared "process")
|
(include-shared "process")
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
|
||||||
|
;;> An interface to spawning processes and sending and
|
||||||
|
;;> receiving signals between processes.
|
||||||
|
|
||||||
(c-system-include "sys/types.h")
|
(c-system-include "sys/types.h")
|
||||||
(c-system-include "sys/wait.h")
|
(c-system-include "sys/wait.h")
|
||||||
(c-system-include "signal.h")
|
(c-system-include "signal.h")
|
||||||
(c-system-include "unistd.h")
|
(c-system-include "unistd.h")
|
||||||
|
|
||||||
|
;;> The siginfo_t struct is used to return info about the status,
|
||||||
|
;;> process and user info of a called signal handler.
|
||||||
|
|
||||||
(define-c-type siginfo_t
|
(define-c-type siginfo_t
|
||||||
predicate: signal-info?
|
predicate: signal-info?
|
||||||
(int si_signo signal-number)
|
(int si_signo signal-number)
|
||||||
|
@ -16,9 +22,6 @@
|
||||||
;;(clock_t si_stime signal-system-time)
|
;;(clock_t si_stime signal-system-time)
|
||||||
)
|
)
|
||||||
|
|
||||||
(define-c-type sigset_t
|
|
||||||
predicate: signal-set?)
|
|
||||||
|
|
||||||
(define-c-const int (signal/hang-up "SIGHUP"))
|
(define-c-const int (signal/hang-up "SIGHUP"))
|
||||||
(define-c-const int (signal/interrupt "SIGINT"))
|
(define-c-const int (signal/interrupt "SIGINT"))
|
||||||
(define-c-const int (signal/quit "SIGQUIT"))
|
(define-c-const int (signal/quit "SIGQUIT"))
|
||||||
|
@ -41,8 +44,23 @@
|
||||||
|
|
||||||
(c-include "signal.c")
|
(c-include "signal.c")
|
||||||
|
|
||||||
|
;;> @subsubsubsection{@rawcode{(set-signal-action! signal handler)}}
|
||||||
|
|
||||||
|
;;> Sets the signal handler for @var{signal} to @var{handler}
|
||||||
|
;;> and returns the old handler. @var{handler} should be a procedure
|
||||||
|
;;> of one argument, the signal number, the value @scheme{#t} for
|
||||||
|
;;> the default signal handler, or @scheme{#f} for no handler.
|
||||||
|
|
||||||
|
;;> Signal handlers are queued run in a dedicated thread after the
|
||||||
|
;;> system handler has returned.
|
||||||
|
|
||||||
(define-c sexp (set-signal-action! "sexp_set_signal_action")
|
(define-c sexp (set-signal-action! "sexp_set_signal_action")
|
||||||
((value ctx sexp) (value self sexp) sexp sexp))
|
((value ctx sexp) (value self sexp) sexp sexp))
|
||||||
|
|
||||||
|
;;> The sigset_t struct represents a set of signals for masking.
|
||||||
|
|
||||||
|
(define-c-type sigset_t
|
||||||
|
predicate: signal-set?)
|
||||||
|
|
||||||
(define-c errno (make-signal-set "sigemptyset") ((pointer result sigset_t)))
|
(define-c errno (make-signal-set "sigemptyset") ((pointer result sigset_t)))
|
||||||
(define-c errno (signal-set-fill! "sigfillset") ((pointer sigset_t)))
|
(define-c errno (signal-set-fill! "sigfillset") ((pointer sigset_t)))
|
||||||
|
@ -59,15 +77,50 @@
|
||||||
(define-c errno (current-signal-mask "sigprocmask")
|
(define-c errno (current-signal-mask "sigprocmask")
|
||||||
((value SIG_BLOCK int) (pointer value NULL sigset_t) (pointer result sigset_t)))
|
((value SIG_BLOCK int) (pointer value NULL sigset_t) (pointer result sigset_t)))
|
||||||
|
|
||||||
|
;;> Send a @var{signal/alarm} signal to the current process
|
||||||
|
;;> after @var{unsigned-int} seconds have elapsed.
|
||||||
|
|
||||||
(define-c unsigned-int alarm (unsigned-int))
|
(define-c unsigned-int alarm (unsigned-int))
|
||||||
|
|
||||||
|
;;> Suspend the current process for @var{unsigned-int} seconds.
|
||||||
|
;;> See SRFI-18 @scheme{thread-sleep!} for a light-weight sleep
|
||||||
|
;;> for only the current thread.
|
||||||
|
|
||||||
(define-c unsigned-int sleep (unsigned-int))
|
(define-c unsigned-int sleep (unsigned-int))
|
||||||
|
|
||||||
|
;;> Fork the current process. Returns @rawcode{0} for the newly
|
||||||
|
;;> created process, and the process id of the new process for
|
||||||
|
;;> the parent.
|
||||||
|
|
||||||
(define-c pid_t fork ())
|
(define-c pid_t fork ())
|
||||||
|
|
||||||
|
(define-c-const int (wait/no-hang "WNOHANG"))
|
||||||
|
|
||||||
;;(define-c pid_t wait ((result int)))
|
;;(define-c pid_t wait ((result int)))
|
||||||
|
|
||||||
|
;;> @subsubsubsection{@rawcode{(waitpid pid options)}}
|
||||||
|
|
||||||
|
;;> Wait on the process @var{pid}, or any child process if @var{pid}
|
||||||
|
;;> is @rawcode{-1}. @var{options} should be 0, or @var{wait/no-hang}
|
||||||
|
;;> to return immediately if no processes have reported status. Returns
|
||||||
|
;;> a list whose first element is the actual @var{pid} reporting, and
|
||||||
|
;;> the second element is the integer status.
|
||||||
|
|
||||||
(define-c pid_t waitpid (int (result int) int))
|
(define-c pid_t waitpid (int (result int) int))
|
||||||
|
|
||||||
|
;;> Send a signal to the given process.
|
||||||
|
|
||||||
(define-c errno kill (int int))
|
(define-c errno kill (int int))
|
||||||
|
|
||||||
;;(define-c errno raise (int))
|
;;(define-c errno raise (int))
|
||||||
|
|
||||||
|
;;> Exits the current process immediately. Finalizers are not run.
|
||||||
|
|
||||||
(define-c void exit (int))
|
(define-c void exit (int))
|
||||||
|
|
||||||
|
;;> Replace the current process with the given command. Finalizers
|
||||||
|
;;> are not run.
|
||||||
|
|
||||||
(define-c int (execute execvp) (string (array string)))
|
(define-c int (execute execvp) (string (array string)))
|
||||||
|
|
||||||
(cond-expand
|
(cond-expand
|
||||||
|
|
130
tools/chibi-doc
130
tools/chibi-doc
|
@ -160,9 +160,15 @@
|
||||||
|
|
||||||
(define (expand-section tag)
|
(define (expand-section tag)
|
||||||
(lambda (sxml env)
|
(lambda (sxml env)
|
||||||
(let ((body (map (lambda (x) (expand x env)) (cdr sxml))))
|
(if (null? (cdr sxml))
|
||||||
`(div (a (^ (name . ,(section-name tag (sxml-strip (cons tag body))))))
|
(error "section must not be empty" sxml)
|
||||||
(,tag ,@body)))))
|
(let* ((name (and (eq? 'tag: (cadr sxml))
|
||||||
|
(pair? (cddr sxml))
|
||||||
|
(sxml-strip (caddr sxml))))
|
||||||
|
(body (map (lambda (x) (expand x env))
|
||||||
|
(if name (cdddr sxml) (cdr sxml))))
|
||||||
|
(name (or name (sxml-strip (cons tag body)))))
|
||||||
|
`(div (a (^ (name . ,(section-name tag name)))) (,tag ,@body))))))
|
||||||
|
|
||||||
(define (expand-url sxml env)
|
(define (expand-url sxml env)
|
||||||
(if (not (= 2 (length sxml)))
|
(if (not (= 2 (length sxml)))
|
||||||
|
@ -171,11 +177,10 @@
|
||||||
`(a (^ (href . ,url)) ,url))))
|
`(a (^ (href . ,url)) ,url))))
|
||||||
|
|
||||||
(define (expand-hyperlink sxml env)
|
(define (expand-hyperlink sxml env)
|
||||||
(if (not (= 3 (length sxml)))
|
(if (not (>= (length sxml) 3))
|
||||||
(error "hyperlink expects two arguments" sxml)
|
(error "hyperlink expects at least two arguments" sxml)
|
||||||
(let ((url (expand (cadr sxml) env))
|
(let ((url (expand (cadr sxml) env)))
|
||||||
(text (expand (caddr sxml) env)))
|
`(a (^ (href . ,url)) ,(map (lambda (x) (expand x env)) (cddr sxml))))))
|
||||||
`(a (^ (href . ,url)) ,text))))
|
|
||||||
|
|
||||||
(define (expand-note sxml env)
|
(define (expand-note sxml env)
|
||||||
`(div (^ (id . "notes"))
|
`(div (^ (id . "notes"))
|
||||||
|
@ -286,10 +291,10 @@
|
||||||
(style (^ (type . "text/css"))
|
(style (^ (type . "text/css"))
|
||||||
"
|
"
|
||||||
body {color: #000; background-color: #FFF}
|
body {color: #000; background-color: #FFF}
|
||||||
div#menu {font-size: smaller; position: absolute; top: 0; left: 0; width: 180px; height: 100%}
|
div#menu {font-size: smaller; position: absolute; top: 50px; left: 0; width: 180px; height: 100%}
|
||||||
div#menu ol {margin-left: 10px; padding-left: 10px}
|
|
||||||
div#main {position: absolute; top: 0; left: 200px; width: 520px; height: 100%}
|
div#main {position: absolute; top: 0; left: 200px; width: 520px; height: 100%}
|
||||||
div#notes {position: relative; top: 2em; left: 550px; max-width: 200px; height: 0px; font-size: smaller;}
|
div#notes {position: relative; top: 2em; left: 550px; max-width: 200px; height: 0px; font-size: smaller;}
|
||||||
|
div#footer {padding-bottom: 50px}
|
||||||
.result { color: #000; background-color: #FFEADF; width: 100%; padding: 3px}
|
.result { color: #000; background-color: #FFEADF; width: 100%; padding: 3px}
|
||||||
.command { color: #000; background-color: #FFEADF; width: 100%; padding: 5px}
|
.command { color: #000; background-color: #FFEADF; width: 100%; padding: 5px}
|
||||||
"
|
"
|
||||||
|
@ -303,7 +308,8 @@ div#notes {position: relative; top: 2em; left: 550px; max-width: 200px; height:
|
||||||
(if (and (pair? x) (eq? 'title (car x)))
|
(if (and (pair? x) (eq? 'title (car x)))
|
||||||
(cons 'h1 (cdr x))
|
(cons 'h1 (cdr x))
|
||||||
x))
|
x))
|
||||||
x)))))
|
x)
|
||||||
|
(div (^ (id . "footer")))))))
|
||||||
|
|
||||||
(define (fix-paragraphs x)
|
(define (fix-paragraphs x)
|
||||||
(let lp ((ls x) (p '()) (res '()))
|
(let lp ((ls x) (p '()) (res '()))
|
||||||
|
@ -349,13 +355,44 @@ div#notes {position: relative; top: 2em; left: 550px; max-width: 200px; height:
|
||||||
(define (get-signature proc source form)
|
(define (get-signature proc source form)
|
||||||
(match form
|
(match form
|
||||||
(('define (name . args) . body)
|
(('define (name . args) . body)
|
||||||
(cons name args))
|
(list (cons name args)))
|
||||||
(('define-syntax name ('syntax-rules () (clause . body) ...))
|
(('define-syntax name ('syntax-rules () (clause . body) ...))
|
||||||
(map (lambda (x) (cons name (cdr x)))
|
(map (lambda (x) (cons name (cdr x)))
|
||||||
(filter external-clause? clause)))
|
(filter external-clause? clause)))
|
||||||
|
((procedure? proc)
|
||||||
|
(procedure-signature proc))
|
||||||
(else
|
(else
|
||||||
(or (and (procedure? proc) (procedure-signature proc))
|
'())))
|
||||||
(procedure-name proc)))))
|
|
||||||
|
(define (get-ffi-signatures form)
|
||||||
|
(match form
|
||||||
|
(('define-c ret-type (or (name _) name) (args ...))
|
||||||
|
(list (cons name (map (lambda (x) (if (pair? x) (last x) x)) args))))
|
||||||
|
(('define-c-const type (or (name _) name))
|
||||||
|
(list (list 'const: type name)))
|
||||||
|
(((or 'define-c-struct 'define-c-class 'define-c-type) name . rest)
|
||||||
|
(let lp ((ls rest) (res '()))
|
||||||
|
(cond
|
||||||
|
((null? ls)
|
||||||
|
(reverse res))
|
||||||
|
((eq? 'predicate: (car ls))
|
||||||
|
(lp (cddr ls) (cons (list (cadr ls) 'obj) res)))
|
||||||
|
((eq? 'constructor: (car ls))
|
||||||
|
(lp (cddr ls)
|
||||||
|
(cons (if (pair? (cadr ls)) (cadr ls) (list (cadr ls))) res)))
|
||||||
|
((pair? (car ls))
|
||||||
|
(lp (cdr ls)
|
||||||
|
(append (if (pair? (cdddar ls))
|
||||||
|
(list (list (car (cdddar ls)) name (caar ls)))
|
||||||
|
'())
|
||||||
|
(list (list (caddar ls) name))
|
||||||
|
res)))
|
||||||
|
((symbol? (car ls))
|
||||||
|
(lp (cddr ls) res))
|
||||||
|
(else
|
||||||
|
(lp (cdr ls) res)))))
|
||||||
|
(else
|
||||||
|
#f)))
|
||||||
|
|
||||||
(define section-number
|
(define section-number
|
||||||
(let ((sections '(section subsection subsubsection subsubsubsection)))
|
(let ((sections '(section subsection subsubsection subsubsubsection)))
|
||||||
|
@ -380,27 +417,42 @@ div#notes {position: relative; top: 2em; left: 550px; max-width: 200px; height:
|
||||||
(symbol->string name))))
|
(symbol->string name))))
|
||||||
|
|
||||||
(define (insert-signature orig-ls name sig)
|
(define (insert-signature orig-ls name sig)
|
||||||
(let lp ((ls orig-ls) (rev-pre '()))
|
(cond
|
||||||
(cond
|
((not (pair? sig))
|
||||||
((or (null? ls) (section>=? (car ls) (section-number 'subsubsubsection)))
|
orig-ls)
|
||||||
`(,@(reverse rev-pre)
|
(else
|
||||||
,@(if (and (pair? ls)
|
(let ((name
|
||||||
(section-describes?
|
(or name (if (eq? 'const: (caar sig)) (caddar sig) (caar sig)))))
|
||||||
(extract-sxml 'subsubsubsection (car ls))
|
(let lp ((ls orig-ls) (rev-pre '()))
|
||||||
name))
|
(cond
|
||||||
'()
|
((or (null? ls)
|
||||||
`((subsubsubsection
|
(section>=? (car ls) (section-number 'subsubsubsection)))
|
||||||
(rawcode ,@(intersperse (map write-to-string sig) '(br))))))
|
`(,@(reverse rev-pre)
|
||||||
,@ls))
|
,@(if (and (pair? ls)
|
||||||
(else
|
(section-describes?
|
||||||
(lp (cdr ls) (cons (car ls) rev-pre))))))
|
(extract-sxml 'subsubsubsection (car ls))
|
||||||
|
name))
|
||||||
|
'()
|
||||||
|
`((subsubsubsection
|
||||||
|
tag: ,(write-to-string name)
|
||||||
|
(rawcode
|
||||||
|
,@(if (eq? 'const: (caar sig))
|
||||||
|
`((i ,(write-to-string (cadar sig)) ": ")
|
||||||
|
,(write-to-string (caddar sig)))
|
||||||
|
(intersperse (map write-to-string sig) '(br)))))))
|
||||||
|
,@ls))
|
||||||
|
(else
|
||||||
|
(lp (cdr ls) (cons (car ls) rev-pre)))))))))
|
||||||
|
|
||||||
(define (extract-docs file defs res)
|
(define (extract-docs file defs . o)
|
||||||
(call-with-input-file file
|
(call-with-input-file file
|
||||||
(lambda (in)
|
(lambda (in)
|
||||||
(let ((defs (map (lambda (x) `(,(car x) ,(cadr x) ,(cdaddr x)))
|
(let ((lang (or (and (pair? o) (car o)) 'scheme))
|
||||||
(filter (lambda (x) (equal? file (caaddr x))) defs))))
|
(defs (map (lambda (x) `(,(car x) ,(cadr x) ,(cdaddr x)))
|
||||||
(let lp ((lines '()) (cur '()) (res res))
|
(filter (lambda (x) (and (pair? (caddr x))
|
||||||
|
(equal? file (caaddr x))))
|
||||||
|
defs))))
|
||||||
|
(let lp ((lines '()) (cur '()) (res '()))
|
||||||
(define (collect)
|
(define (collect)
|
||||||
(if (pair? lines)
|
(if (pair? lines)
|
||||||
(append
|
(append
|
||||||
|
@ -435,6 +487,9 @@ div#notes {position: relative; top: 2em; left: 550px; max-width: 200px; height:
|
||||||
(procs (filter (lambda (x) (<= line1 (caddr x) line2))
|
(procs (filter (lambda (x) (<= line1 (caddr x) line2))
|
||||||
(filter caddr defs))))
|
(filter caddr defs))))
|
||||||
(cond
|
(cond
|
||||||
|
((and (eq? lang 'ffi) (get-ffi-signatures x))
|
||||||
|
=> (lambda (sigs)
|
||||||
|
(lp '() '() (append (insert-signature cur #f sigs) res))))
|
||||||
((= 1 (length procs))
|
((= 1 (length procs))
|
||||||
(let* ((sig (or (get-signature (caar procs) (cdar procs) x)
|
(let* ((sig (or (get-signature (caar procs) (cdar procs) x)
|
||||||
'()))
|
'()))
|
||||||
|
@ -573,11 +628,12 @@ div#notes {position: relative; top: 2em; left: 550px; max-width: 200px; height:
|
||||||
(filter (lambda (x) (or (procedure? (cdr x)) (macro? (cdr x))))
|
(filter (lambda (x) (or (procedure? (cdr x)) (macro? (cdr x))))
|
||||||
(map (lambda (x) (cons x (module-ref mod-name x)))
|
(map (lambda (x) (cons x (module-ref mod-name x)))
|
||||||
exports)))))
|
exports)))))
|
||||||
(let lp ((includes (module-includes mod))
|
(output
|
||||||
(res `((title ,(write-to-string mod-name)))))
|
`((title ,(write-to-string mod-name))
|
||||||
(if (null? includes)
|
,@(reverse (append-map (lambda (x) (extract-docs x defs))
|
||||||
(output (reverse res))
|
(module-includes mod)))
|
||||||
(lp (cdr includes) (extract-docs (car includes) defs res))))))
|
,@(reverse (append-map (lambda (x) (extract-docs x defs 'ffi))
|
||||||
|
(module-shared-includes mod)))))))
|
||||||
|
|
||||||
(define (main args)
|
(define (main args)
|
||||||
(case (length args)
|
(case (length args)
|
||||||
|
|
Loading…
Add table
Reference in a new issue