From: Raphaƫl Van Dyck Date: Thu, 15 Jan 2026 19:43:09 +0000 (+0100) Subject: revise user manual, tutorial, and reference manual X-Git-Url: http://evlambda.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=611f981185c72513a65f164f4e40391f74568da7;p=evlambda.git revise user manual, tutorial, and reference manual --- diff --git a/system-files/REFERENCE-MANUAL b/system-files/REFERENCE-MANUAL index 51460c6..20694ee 100644 --- a/system-files/REFERENCE-MANUAL +++ b/system-files/REFERENCE-MANUAL @@ -36,7 +36,7 @@

Note that some whitespace is needed to separate the lexeme + from the lexeme 123 and the lexeme 123 from the lexeme 456 but no whitespace is needed to separate the lexeme ( from the lexeme + or the lexeme 456 from the lexeme ).

Step 2.2 A component of the reader called the parser converts the sequence of tokens from step 2.1 (minus the tokens of category whitespace, which are ignored by the parser) into a cons whose car is the variable from step 2.1 and whose cdr is a cons whose car is the first number from step 2.1 and whose cdr is a cons whose car is the second number from step 2.1 and whose cdr is the empty list. Together, those three conses represent the list (+ 123 456).

-

Step 3 The evaluator evaluates the list (+ 123 456) to the number 579. The evaluation of the top-level form (+ 123 456) entails the evaluation of other non-top-level forms. Each form must be classified in order to determine how it should be evaluated. The form (+ 123 456) is classified as a plain function call. The variable + is treated as an abbreviation for the form (fref +). The form (fref +) is classified as an fref-form. The forms 123 and 456 are classified as self-evaluating objects. Because the global function + is a closure, its invocation entails the evaluation (and thus the classification) of other forms. The component of the evaluator responsible for classifying forms is called the syntax analyzer.

+

Step 3 The evaluator evaluates the list (+ 123 456) to the number 579. The evaluation of the top-level form (+ 123 456) entails the evaluation of other non-top-level forms. Each form must be classified in order to determine how it should be evaluated. The form (+ 123 456) is classified as a plain function call. The variable + is treated as an abbreviation for the form (fref +). The form (fref +) is classified as an fref-form. The forms 123 and 456 are classified as self-evaluating objects. Because the global function + is a closure, its invocation entails the evaluation (and thus the classification) of other forms. The component of the evaluator responsible for classifying forms is called the syntax analyzer.

Step 4 The printer converts the number 579 into the sequence of characters 579. (The sequence of characters is the printable representation of the number.)

Step 5 The sequence of characters 579 is written into the listener buffer.

EVLambda has three levels of syntax:

@@ -92,7 +92,7 @@

Because the characters < and & can appear inside EVLambda source code, a documented EVLambda source file is not always a well-formed XML document.

Documentation Generator

The documentation generator converts a documented EVLambda source file to HTML in two steps:

-

Step 1 The characters < and & appearing inside EVLambda source code are escaped and some tags are added to better delimit the EVLambda source code and the comments. The resulting file is a well-formed XML document.

+

Step 1 The characters < and & appearing inside EVLambda source code are escaped and some tags are added to better delimit the code from the surrounding documentation and the comments from the surrounding code. The resulting file is a well-formed XML document.

Step 2 The resulting file from step 1 is converted to HTML by an XSLT stylesheet.

Unicode

The characters contained inside listener buffers and EVLambda source files are Unicode characters. Unicode is a character set containing, as of version 17.0, $159801$ characters. Each Unicode character is uniquely identified by a nonnegative integer called its code point. Code points range from $0$ to $1114111$ in decimal and from 0 to 10FFFF in hexadecimal. (Not all code points are assigned to a character.) The notation $U{+}\mlvar{hex}$ denotes the Unicode character whose code point is represented by the hexadecimal numeral $\mlvar{hex}$. The order on integers directly translates into an order on Unicode characters. With respect to that order, the Unicode character $c_1$ precedes the Unicode character $c_2$ if and only if the code point of $c_1$ is strictly less than the code point of $c_2$. That order can be used to define ranges of Unicode characters.

@@ -198,31 +198,29 @@ \^the caret \-the hyphen \]the closing square bracket - \U{$\mlvar{hex}$}the Unicode character whose code point is represented by the hexadecimal numeral $\mlvar{hex}$ + \U{$\mlvar{hex}$}the Unicode character whose code point is represented by the hexadecimal numeral $\mlvar{hex}$ \C{$\mlvar{cat}$}the Unicode characters whose general categories are $\mlvar{cat}$

The zero-or-more-times, one-or-more-times, and zero-or-one-time operations have precedence over the concatenation operation and the concatenation operation has precedence over the union and difference operations. All operations are left associative. Parenthesis can be added to override those precedence and associativity rules.

References to named regular expressions can be used wherever regular expressions can be used. References to named regular expressions denoting classes of characters can also be used inside character classes. Circular definitions are not allowed.

Except for the parts referencing named regular expressions, regular expressions are typeset in a monospaced typeface. Spaces can be added freely outside literal strings and character classes without modifying the meaning of a regular expression.

Extended Backus-Naur Form (EBNF)

-

The parser and the syntax analyzer use a variant of the extended Backus-Naur form (EBNF) notation to specify various context-free grammars.

+

The parser and the syntax analyzer use a variant of the extended Backus-Naur form (EBNF) notation to define various context-free grammars.

The following table summarizes the syntax of the variant of the EBNF notation used in this document:

- - + + - - - - - - - - - - + + + + + + +
SyntaxMeaning
$\mlvar{lhs}\Coloneq\mlvar{rhs}$definition of a production rule (the left-hand-side is a nonterminal symbol and the right-hand-side is a sequence of zero or more nonterminal and/or terminal symbols)
$\metavar{nonterminal}$nonterminal symbol
$\mlvar{lhs}$ $\Coloneq$ $\mlvar{rhs}$definition of a production rule
$\metavar{nonterminal}$nonterminal symbol
terminalterminal symbol
'$\mlvar{char}$'terminal symbol consisting of the character $\mlvar{char}$ ($\mlvar{char}\neq\code{'}$)
"$\mlvar{char}$"terminal symbol consisting of the character $\mlvar{char}$ ($\mlvar{char}\neq\code{"}$)
'$\mlvar{char}_1\ldots\mlvar{char}_n$'abbreviation for '$\mlvar{char}_1$''$\mlvar{char}_n$' ($\mlvar{char}_i\neq\code{'}$)
"$\mlvar{char}_1\ldots\mlvar{char}_n$"abbreviation for "$\mlvar{char}_1$""$\mlvar{char}_n$" ($\mlvar{char}_i\neq\code{"}$)
$\epsilon$empty sequence of symbols
$\mlvar{rhs}_1\mid\cdots\mid\mlvar{rhs}_n$union (alternation) operation
$\mlvar{symbol}\ast$zero-or-more-times (Kleene star) operation
$\mlvar{symbol}+$one-or-more-times (Kleene plus) operation
$\mlvar{symbol}?$zero-or-one-time (optional) operation
$(\mlvar{rhs})$grouping (the group can be used wherever a symbol can be used)
$\epsilon$empty sequence of symbols
$\mlvar{rhs}_1$ | $\ldots$ | $\mlvar{rhs}_n$union (alternation) operation
$\mlvar{symbol}$*zero-or-more-times (Kleene star) operation
$\mlvar{symbol}$+one-or-more-times (Kleene plus) operation
$\mlvar{symbol}$?zero-or-one-time (optional) operation
{$\mlvar{rhs}$}group
??special sequence
+

A left-hand-side ($\mlvar{lhs}$) consists of a nonterminal symbol. A right-hand-side ($\mlvar{rhs}$) consists of a sequence of zero or more nonterminal and/or terminal symbols. A group can be used wherever a symbol can be used. A special sequence is a free-form text specifying a set of terminal symbols.

Tokenizer

The tokenizer converts an input sequence of Unicode characters into a sequence of tokens in two steps. During the first step, the tokenizer converts the input sequence of Unicode characters into a provisional sequence of tokens. During the second step, the tokenizer converts the provisional sequence of tokens into a final sequence of tokens.

Character Classes

@@ -334,7 +332,6 @@
Pattern: (($\metavar{valid-char}$ - ($\metavar{whitespace-char}$ | $\metavar{syntax-char}$ | '\\\\')) | ('\\\\' [\\\\<]) | ('\\\\U{' [a-fA-F0-9]+ '}'))+
Value: The backslash plays the role of an escape character. The escape sequences are interpreted as specified in the table below. The value is the lexeme after interpretation of the escape sequences.
-

An escape character is a character that modifies the meaning of the following characters. Together, an escape character and the characters whose meanings are modified by the escape character form an escape sequence.

Escape sequences in lexemes associated with tokens of categories string and hash-string are interpreted as follows:

@@ -452,5 +449,603 @@
Escape sequenceMeaning

Here is the result of combining the Unicode character “NINJA” with the different skin-tone modifiers:

> '(#"🥷🏻")
(#"\U{D83E}" #"\U{DD77}" #"\U{D83C}" #"\U{DFFB}")

> '(#"🥷🏼")
(#"\U{D83E}" #"\U{DD77}" #"\U{D83C}" #"\U{DFFC}")

> '(#"🥷🏽")
(#"\U{D83E}" #"\U{DD77}" #"\U{D83C}" #"\U{DFFD}")

> '(#"🥷🏾")
(#"\U{D83E}" #"\U{DD77}" #"\U{D83C}" #"\U{DFFE}")

> '(#"🥷🏿")
(#"\U{D83E}" #"\U{DD77}" #"\U{D83C}" #"\U{DFFF}")

+

Parser

+

The parser uses a context-free grammar to convert the sequence of tokens produced by the tokenizer into a sequence of objects. The conversion is conceptually a two-step process. During the first step, the parser converts the sequence of tokens into a derivation tree. During the second step, the parser assigns a meaning to the derivation tree.

+

The construction of the derivation tree is directed by the context-free grammar. Because the parser ignores the tokens' values and only takes into account the tokens' categories when constructing the derivation tree, the terminal symbols of the context-free grammar are the names of the token categories.

+

The production rule describing the whole sequence of tokens produced by the tokenizer depends on the origin of the input sequence of characters.

+

When the origin of the input sequence of characters is a listener buffer, the whole sequence of tokens is described by the following production rule:

+ + + + + + +
$\metavar{input}$$\Coloneq$$\metavar{object}$
+

When the origin of the input sequence of characters is a plain EVLambda source file, the whole sequence of tokens is described by the following production rule:

+ + + + + + +
$\metavar{input}$$\Coloneq$$\metavar{object}$*
+

When the origin of the input sequence of characters is a documented EVLambda source file, the whole sequence of tokens is described by the following production rule (the XML element is a chapter element):

+ + + + + + +
$\metavar{input}$$\Coloneq$$\metavar{xml-comment}$* $\metavar{xml-element}$ $\metavar{xml-comment}$*
+

The rest of the context-free grammar, which does not depend on the origin of the input sequence of characters, is defined as follows:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$\metavar{xml-markup}$$\Coloneq$$\metavar{xml-element}$ | $\metavar{xml-comment}$
$\metavar{xml-element}$$\Coloneq$xml-start-tag $\metavar{xml-element-content}$* xml-end-tag | xml-empty-element-tag
$\metavar{xml-element-content}$$\Coloneq$$\metavar{xml-markup}$ | $\metavar{object}$
$\metavar{xml-comment}$$\Coloneq$xml-comment
$\metavar{object}$$\Coloneq$void | boolean | number | character | string | keyword | variable | $\metavar{abbreviation}$ | $\metavar{list}$ | $\metavar{vector}$
$\metavar{abbreviation}$$\Coloneq$$\metavar{quotation}$ | $\metavar{quasiquotation}$ | $\metavar{unquotation}$ | $\metavar{splicing-unquotation}$
$\metavar{quotation}$$\Coloneq$quote $\metavar{xml-markup}$* $\metavar{object}$
$\metavar{quasiquotation}$$\Coloneq$quasiquote $\metavar{xml-markup}$* $\metavar{object}$
$\metavar{unquotation}$$\Coloneq$unquote $\metavar{xml-markup}$* $\metavar{object}$
$\metavar{splicing-unquotation}$$\Coloneq$unquote-splicing $\metavar{xml-markup}$* $\metavar{object}$
$\metavar{list}$$\Coloneq$$\metavar{proper-list}$ | $\metavar{dotted-list}$
$\metavar{proper-list}$$\Coloneq$left-parenthesis {$\metavar{xml-markup}$* $\metavar{object}$}* $\metavar{xml-markup}$* right-parenthesis
$\metavar{dotted-list}$$\Coloneq$left-parenthesis {$\metavar{xml-markup}$* $\metavar{object}$}+ $\metavar{xml-markup}$* dot $\metavar{xml-markup}$* $\metavar{object}$ $\metavar{xml-markup}$* right-parenthesis
$\metavar{vector}$$\Coloneq$hash-left-parenthesis {$\metavar{xml-markup}$* $\metavar{object}$}* $\metavar{xml-markup}$* right-parenthesis
+

Let us denote by $\mathcal{M}$ the function assigning a meaning to a derivation tree. The function $\mathcal{M}$ is defined by specifying, for each production rule, how the meaning of the nonterminal symbol on the left-hand side is computed from (1) the meanings of the nonterminal symbols on the right-hand side and (2) the terminal symbols on the right-hand side. Here is the definition of the function $\mathcal{M}$ (pairs of angle brackets denote sequence formation and $\|$ denotes sequence concatenation):

+
+ +
$\metavar{input}\Coloneq$ $\metavar{object}$
+
$\mathcal{M}(\metavar{input})=\langle\mathcal{M}(\metavar{object})\rangle$
+
$\metavar{input}\Coloneq$ $\metavarn{object}{1}$ $\ldots$ $\metavarn{object}{n\geq0}$
+
$\mathcal{M}(\metavar{input})=\langle\mathcal{M}(\metavarn{object}{1}),\ldots,\mathcal{M}(\metavarn{object}{n})\rangle$
+
$\metavar{input}\Coloneq$ $\metavar{xml-comment}$* $\metavar{xml-element}$ $\metavar{xml-comment}$*
+
$\mathcal{M}(\metavar{input})=\mathcal{M}(\metavar{xml-element})$
+ +
$\metavar{xml-markup}\Coloneq$ $\metavar{xml-element}$
+
$\mathcal{M}(\metavar{xml-markup})=\mathcal{M}(\metavar{xml-element})$
+
$\metavar{xml-markup}\Coloneq$ $\metavar{xml-comment}$
+
$\mathcal{M}(\metavar{xml-markup})=\mathcal{M}(\metavar{xml-comment})$
+ +
$\metavar{xml-element}\Coloneq$ xml-start-tag $\metavarn{xml-element-content}{1}$ $\ldots$ $\metavarn{xml-element-content}{n\geq0}$ xml-end-tag
+
$\mathcal{M}(\metavar{xml-element})=\mathcal{M}(\metavarn{xml-element-content}{1})\|\cdots\|\mathcal{M}(\metavarn{xml-element-content}{n})$
+
$\metavar{xml-element}\Coloneq$ xml-empty-element-tag
+
$\mathcal{M}(\metavar{xml-element})=\langle\rangle$
+ +
$\metavar{xml-element-content}\Coloneq$ $\metavar{xml-markup}$
+
$\mathcal{M}(\metavar{xml-element-content})=\mathcal{M}(\metavar{xml-markup})$
+
$\metavar{xml-element-content}\Coloneq$ $\metavar{object}$
+
$\mathcal{M}(\metavar{xml-element-content})=\langle\mathcal{M}(\metavar{object})\rangle$
+ +
$\metavar{xml-comment}\Coloneq$ xml-comment
+
$\mathcal{M}(\metavar{xml-comment})=\langle\rangle$
+ +
$\metavar{object}\Coloneq$ void
+
$\mathcal{M}(\metavar{object})=$ the value of the token of category void
+
$\metavar{object}\Coloneq$ boolean
+
$\mathcal{M}(\metavar{object})=$ the value of the token of category boolean
+
$\metavar{object}\Coloneq$ number
+
$\mathcal{M}(\metavar{object})=$ the value of the token of category number
+
$\metavar{object}\Coloneq$ character
+
$\mathcal{M}(\metavar{object})=$ the value of the token of category character
+
$\metavar{object}\Coloneq$ string
+
$\mathcal{M}(\metavar{object})=$ the value of the token of category string
+
$\metavar{object}\Coloneq$ keyword
+
$\mathcal{M}(\metavar{object})=$ the value of the token of category keyword
+
$\metavar{object}\Coloneq$ variable
+
$\mathcal{M}(\metavar{object})=$ the value of the token of category variable
+
$\metavar{object}\Coloneq$ $\metavar{abbreviation}$
+
$\mathcal{M}(\metavar{object})=\mathcal{M}(\metavar{abbreviation})$
+
$\metavar{object}\Coloneq$ $\metavar{list}$
+
$\mathcal{M}(\metavar{object})=\mathcal{M}(\metavar{list})$
+
$\metavar{object}\Coloneq$ $\metavar{vector}$
+
$\mathcal{M}(\metavar{object})=\mathcal{M}(\metavar{vector})$
+ +
$\metavar{abbreviation}\Coloneq$ $\metavar{quotation}$
+
$\mathcal{M}(\metavar{abbreviation})=\mathcal{M}(\metavar{quotation})$
+
$\metavar{abbreviation}\Coloneq$ $\metavar{quasiquotation}$
+
$\mathcal{M}(\metavar{abbreviation})=\mathcal{M}(\metavar{quasiquotation})$
+
$\metavar{abbreviation}\Coloneq$ $\metavar{unquotation}$
+
$\mathcal{M}(\metavar{abbreviation})=\mathcal{M}(\metavar{unquotation})$
+
$\metavar{abbreviation}\Coloneq$ $\metavar{splicing-unquotation}$
+
$\mathcal{M}(\metavar{abbreviation})=\mathcal{M}(\metavar{splicing-unquotation})$
+ +
$\metavar{quotation}\Coloneq$ quote $\metavar{object}$
+
$\mathcal{M}(\metavar{quotation})=$ a cons whose car is the variable quote and whose cdr is a cons whose car is $\mathcal{M}(\metavar{object})$ and whose cdr is the empty list
+ +
$\metavar{quasiquotation}\Coloneq$ quasiquote $\metavar{object}$
+
$\mathcal{M}(\metavar{quasiquotation})=$ a cons whose car is the variable quasiquote and whose cdr is a cons whose car is $\mathcal{M}(\metavar{object})$ and whose cdr is the empty list
+ +
$\metavar{unquotation}\Coloneq$ unquote $\metavar{object}$
+
$\mathcal{M}(\metavar{unquotation})=$ a cons whose car is the variable unquote and whose cdr is a cons whose car is $\mathcal{M}(\metavar{object})$ and whose cdr is the empty list
+ +
$\metavar{splicing-unquotation}\Coloneq$ unquote-splicing $\metavar{object}$
+
$\mathcal{M}(\metavar{splicing-unquotation})=$ a cons whose car is the variable unquote-splicing and whose cdr is a cons whose car is $\mathcal{M}(\metavar{object})$ and whose cdr is the empty list
+ +
$\metavar{list}\Coloneq$ $\metavar{proper-list}$
+
$\mathcal{M}(\metavar{list})=\mathcal{M}(\metavar{proper-list})$
+
$\metavar{list}\Coloneq$ $\metavar{dotted-list}$
+
$\mathcal{M}(\metavar{list})=\mathcal{M}(\metavar{dotted-list})$
+ +
$\metavar{proper-list}\Coloneq$ left-parenthesis right-parenthesis
+
$\mathcal{M}(\metavar{proper-list})=$ the empty list
+
$\metavar{proper-list}\Coloneq$ left-parenthesis $\metavarn{object}{1}$ $\ldots$ $\metavarn{object}{n\geq1}$ right-parenthesis
+
$\mathcal{M}(\metavar{proper-list})=$ the first cons of a chain of $n$ conses $\cons_1,\ldots,\cons_n$ such that the car of $\cons_i$ is $\mathcal{M}(\metavarn{object}{i})$, the cdr of $\cons_{i\lt n}$ is $\cons_{i+1}$, and the cdr of $\cons_n$ is the empty list
+ +
$\metavar{dotted-list}\Coloneq$ left-parenthesis $\metavarn{object}{1}$ $\ldots$ $\metavarn{object}{n\geq1}$ dot $\metavarn{object}{n+1}$ right-parenthesis
+
$\mathcal{M}(\metavar{dotted-list})=$ the first cons of a chain of $n$ conses $\cons_1,\ldots,\cons_n$ such that the car of $\cons_i$ is $\mathcal{M}(\metavarn{object}{i})$, the cdr of $\cons_{i\lt n}$ is $\cons_{i+1}$, and the cdr of $\cons_n$ is $\mathcal{M}(\metavarn{object}{n+1})$
+ +
$\metavar{vector}\Coloneq$ hash-left-parenthesis $\metavarn{object}{1}$ $\ldots$ $\metavarn{object}{n\geq0}$ right-parenthesis
+
$\mathcal{M}(\metavar{vector})=$ a vector of $n$ elements $\mlvar{elem}_1,\ldots,\mlvar{elem}_n$ such that $\mlvar{elem}_i$ is $\mathcal{M}(\metavarn{object}{i})$
+
+

Note that the XML markup inside abbreviations, lists, and vectors cannot produce objects and has therefore been omitted from the definition of the function $\mathcal{M}$.

+

Pattern Language and Template Languages

+

The pattern language is a context-free language whose sentences are patterns meant to be matched against objects. The pattern language can be used to specify a set of objects $S$ as follows:

+ +

The language specified by a grammar such as $G$ is called a template language. Template languages will be used to specify the forms recognized by the syntax analyzer, to specify template macro calls, to specify data structures, …

+

Here are the terminal symbols of the context-free grammar specifying the pattern language:

+ +

Here are the production rules of the context-free grammar specifying the pattern language:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$\metavar{pattern}$$\Coloneq$$\metavar{type}$ | $\metavar{void}$ | $\metavar{boolean}$ | $\metavar{number}$ | $\metavar{character}$ | $\metavar{string}$ | $\metavar{keyword}$ | $\metavar{variable}$ | $\metavar{list}$ | $\metavar{vector}$
$\metavar{type}$$\Coloneq$$\object$ | $\void$ | $\boolean$ | $\number$ | $\character$ | $\string$ | $symbol$ | $\keyword$ | $\variable$ | $\list$ | $\emptylist$ | $\cons$ | $\vector$ | $\function$ | $\primitivefunction$ | $\closure$
$\metavar{void}$$\Coloneq$? any readable representation of an object of type void ?
$\metavar{boolean}$$\Coloneq$? any readable representation of an object of type boolean ?
$\metavar{number}$$\Coloneq$? any readable representation of an object of type number ?
$\metavar{character}$$\Coloneq$? any readable representation of an object of type character ?
$\metavar{string}$$\Coloneq$? any readable representation of an object of type string ?
$\metavar{keyword}$$\Coloneq$? any readable representation of an object of type keyword ?
$\metavar{variable}$$\Coloneq$? any readable representation of an object of type variable ?
$\metavar{list}$$\Coloneq$$\metavar{proper-list}$ | $\metavar{dotted-list}$
$\metavar{proper-list}$$\Coloneq$($\metavar{pattern}$*)
$\metavar{dotted-list}$$\Coloneq$($\metavar{pattern}$+ . $\metavar{pattern}$)
$\metavar{vector}$$\Coloneq$#($\metavar{pattern}$*)
+

The rules specifying if an object matches a pattern are the following:

+ +

By way of example, let us consider the template language specified by the following context-free grammar:

+ + + + + + + + + + + + + + + + +
$\metavar{association-list}$$\Coloneq$({($\metavar{key}$ . $\metavar{value}$)}*)
$\metavar{key}$$\Coloneq$$\object$
$\metavar{value}$$\Coloneq$$\object$
+

The sentences of the example template language are the following:

+ +

The objects specified by the example template language (= the objects matching at least one sentence of the example template language) are the proper lists of conses of arbitrary objects. As suggested by the names of the nonterminal symbols, the first object of each cons operates as a key, the second object of each cons operates as a value, and the proper list as a whole is called an association list.

+

Read-Time Conditionalization Facility

+

The purpose of the read-time conditionalization facility is to alter the flow of tokens according to some conditions. Because the facility is conceptually located between the tokenizer and the parser, its associated syntax does not belong to the context-free grammar used by the parser. It is however convenient to specify the syntax of a read-time conditional by the following production rule:

+ + + + + + +
$\metavar{read-time-conditional}$$\Coloneq${hash-plus | hash-minus} $\metavar{xml-markup}$* $\metavar{object}$ $\metavar{xml-markup}$* $\metavar{object}$
+

The first object is called the feature expression and the second object is called the conditionalized object.

+

When the facility encounters a hash-plus or a hash-minus token, it instructs the parser to parse, hand over, and discard the feature expression. The feature expression is then evaluated by the facility according to the rules stated below. If the feature expression evaluates to true, then the facility ends its processing of the read-time conditional by instructing the parser to parse and retain the conditionalized object. (The net effect is the same as if only the tokens of the conditionalized object had existed.) If the feature expression evaluates to false, then the facility ends its processing of the read-time conditional by instructing the parser to parse and discard the conditionalized object. (The net effect is the same as if the tokens of the read-time conditional had not existed.)

+

Feature expressions must belong to the set objects specified by the template language specified by the following context-free grammar:

+ + + + + + + + + + + +
$\metavar{feature-expression}$$\Coloneq$$\symbol$ | (not $\metavar{operand}$) | (and $\metavar{operand}$*) | (or $\metavar{operand}$*)
$\metavar{operand}$$\Coloneq$$\metavar{feature-expression}$
+

Feature expressions are evaluated as follows:

+
+
$\metavar{feature-expression}\Coloneq$ $\symbol$
+
The feature expression evaluates to true if the symbol belongs to the value of the global variable *features* and to false otherwise.
+
$\metavar{feature-expression}\Coloneq$ (not $\metavar{operand}$)
+
The feature expression evaluates to true if its operand evaluates to false and to false otherwise.
+
$\metavar{feature-expression}\Coloneq$ (and $\metavar{operand}$*)
+
The feature expression evaluates to true if all its operands evaluate to true and to false otherwise.
+
$\metavar{feature-expression}\Coloneq$ (or $\metavar{operand}$*)
+
The feature expression evaluates to false if all its operands evaluate to false and to true otherwise.
+
+

By way of example, let us consider the following sequence of characters:

+
(1 . #+foo 2 #-foo 3)
+

If the symbol foo belongs to the value of the global variable *features*, then the sequence of characters is parsed as the dotted list (1 . 2). Otherwise, the sequence of characters is parsed as the dotted list (1 . 3).

+

Syntax Analyzer

+

The forms recognized by the syntax analyzer are specified by the template language specified by the following context-free grammar:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$\metavar{form}$$\Coloneq$$\metavar{special-form}$ | $\metavar{macro-call}$ | $\metavar{plain-function-call}$ | $\metavar{self-evaluating-object}$
$\metavar{special-form}$$\Coloneq$$\metavar{quote-form}$ | $\metavar{progn-form}$ | $\metavar{if-form}$ | $\metavar{lambda-abstraction}$ | $\metavar{variable-reference}$ | $\metavar{variable-assignment}$ | $\metavar{\_for-each-form}$ | $\metavar{\_catch-errors-form}$ | $\metavar{multiple-value-call-form}$ | $\metavar{apply-form}$ | $\metavar{multiple-value-apply-form}$
$\metavar{quote-form}$$\Coloneq$(quote $\metavar{literal}$)
$\metavar{literal}$$\Coloneq$$\object$
$\metavar{progn-form}$$\Coloneq$(progn $\metavar{serial-form}$*)
$\metavar{serial-form}$$\Coloneq$$\metavar{form}$
$\metavar{if-form}$$\Coloneq$(if $\metavar{test-form}$ $\metavar{then-form}$ $\metavar{else-form}$)
$\metavar{test-form}$$\Coloneq$$\metavar{form}$
$\metavar{then-form}$$\Coloneq$$\metavar{form}$
$\metavar{else-form}$$\Coloneq$$\metavar{form}$
$\metavar{lambda-abstraction}$$\Coloneq$$\metavar{\_vlambda-form}$ | $\metavar{\_mlambda-form}$ | $\metavar{\_flambda-form}$ | $\metavar{\_dlambda-form}$
$\metavar{\_vlambda-form}$$\Coloneq$(_vlambda $\metavar{parameter-list}$ $\metavar{body}$)
$\metavar{\_mlambda-form}$$\Coloneq$(_mlambda $\metavar{parameter-list}$ $\metavar{body}$)
$\metavar{\_flambda-form}$$\Coloneq$(_flambda $\metavar{parameter-list}$ $\metavar{body}$)
$\metavar{\_dlambda-form}$$\Coloneq$(_dlambda $\metavar{parameter-list}$ $\metavar{body}$)
$\metavar{parameter-list}$$\Coloneq$$\variable$ | ($\variable$*) | ($\variable$+ . $\variable$)
$\metavar{body}$$\Coloneq$$\metavar{serial-form}$*
$\metavar{variable-reference}$$\Coloneq$$\variable$ | $\metavar{vref-form}$ | $\metavar{fref-form}$ | $\metavar{dref-form}$
$\metavar{vref-form}$$\Coloneq$(vref $\variable$)
$\metavar{fref-form}$$\Coloneq$(fref $\variable$)
$\metavar{dref-form}$$\Coloneq$(dref $\variable$)
$\metavar{variable-assignment}$$\Coloneq$$\metavar{vset-form}$ | $\metavar{fset-form}$ | $\metavar{dset-form}$
$\metavar{vset-form}$$\Coloneq$(vset! $\variable$ $\metavar{value-form}$)
$\metavar{fset-form}$$\Coloneq$(fset! $\variable$ $\metavar{value-form}$)
$\metavar{dset-form}$$\Coloneq$(dset! $\variable$ $\metavar{value-form}$)
$\metavar{value-form}$$\Coloneq$$\metavar{form}$
$\metavar{\_for-each-form}$$\Coloneq$(_for-each $\metavar{function-form}$ $\metavar{list-form}$)
$\metavar{function-form}$$\Coloneq$$\metavar{form}$
$\metavar{list-form}$$\Coloneq$$\metavar{form}$
$\metavar{\_catch-errors-form}$$\Coloneq$(_catch-errors $\metavar{try-form}$)
$\metavar{try-form}$$\Coloneq$$\metavar{form}$
$\metavar{multiple-value-call-form}$$\Coloneq$(multiple-value-call $\metavar{operator-form}$ $\metavar{operand-form}$*)
$\metavar{apply-form}$$\Coloneq$(apply $\metavar{operator-form}$ $\metavar{operand-form}$*)
$\metavar{multiple-value-apply-form}$$\Coloneq$(multiple-value-apply $\metavar{operator-form}$ $\metavar{operand-form}$*)
$\metavar{macro-call}$$\Coloneq$($\metavar{macro-operator}$ $\metavar{macro-operand}$*)
$\metavar{macro-operator}$$\Coloneq$$\variable$
$\metavar{macro-operand}$$\Coloneq$$\object$
$\metavar{plain-function-call}$$\Coloneq$($\metavar{operator-form}$ $\metavar{operand-form}$*)
$\metavar{operator-form}$$\Coloneq$$\metavar{form}$
$\metavar{operand-form}$$\Coloneq$$\metavar{form}$
$\metavar{self-evaluating-object}$$\Coloneq$$\void$ | $\boolean$ | $\number$ | $\character$ | $\string$ | $\keyword$ | $\vector$ | $\primitivefunction$ | $\closure$
+

The names of the nonterminal symbols are the names that will be used throughout this document to name the forms and their components.

+

The following production rules introduce additional terminology:

+ + + + + + + + + + + + + + + + +
$\metavar{special-operator}$$\Coloneq$quote | progn | if | _vlambda | _mlambda | _flambda | _dlambda | vref | fref | dref | vset! | fset! | dset! | _for-each | _catch-errors | multiple-value-call | apply | multiple-value-apply
$\metavar{call}$$\Coloneq$$\metavar{macro-call}$ | $\metavar{function-call}$
$\metavar{function-call}$$\Coloneq$$\metavar{plain-function-call}$ | $\metavar{multiple-value-call-form}$ | $\metavar{apply-form}$ | $\metavar{multiple-value-apply-form}$
+

The variables quasiquote, unquote, and unquote-splicing are not special operators. The variable quasiquote is the name of a global macro and the variables unquote and unquote-splicing are variables having special meanings in the context of a call to the global macro quasiquote.

+

A form consisting of a variable $\var$ is treated as an abbreviation. If it appears in operator position, then it is treated as an abbreviation for the special form (fref $\var$). Otherwise, it is treated as an abbreviation for the special form (vref $\var$).

+

Classifying a form is the first step in evaluating a form. If the classification fails, then the evaluation fails.

+

Some syntax analyzers classify forms without checking that the components that must be forms are actually forms. Syntax analyzers associated with interpreters usually function this way. With this kind of syntax analyzer, the components that must be forms are classified if and when they are evaluated.

+

According to the template language, some objects can simultaneously be a special form, a macro call, and a plain function call. Additional rules are needed to disambiguate the situation.

+

The following rules used by the syntax analyzer are not expressed by the template language:

+ +

Documentation Generator

+

In this section, the character ⇰ marks the places where line breaks have been added to wrap long lines.

+

Let us consider the following documented EVLambda source file:

+
<chapter>
<title>Recursive Functions</title>
<para>...para...</para>
<para>...para...</para>
<section>
<title>Factorial Function</title>
<para>...para...</para>
<para>...para...</para>
(fdef fact (n)
<para>...block...</para>
<para>...block...</para>
(if (= n 0)
1 <comment>...eol...</comment>
(* n (fact (- n 1))))) <comment>...eoll...</comment>

(test 1 (fact 0))
(test 120 (fact 5))
(test 3628800 (fact 10))
</section>
<section>
<title>Fibonacci Sequence</title>
<para>...para...</para>
<para>...para...</para>
(fdef fib (n)
<para>...block...</para>
<para>...block...</para>
(if (= n 0)
0 <comment>...eol...</comment>
(if (= n 1)
1 <comment>...eol...</comment>
(+ (fib (- n 1)) (fib (- n 2)))))) <comment>...eoll...</comment>

(test 0 (fib 0))
(test 5 (fib 5))
(test 55 (fib 10))
</section>
</chapter>
+

The first step of the documentation generation process converts the documented EVLambda source file into the following XML document:

+
<chapter>
<title>Recursive Functions</title>
<para>...para...</para>
<para>...para...</para>
<section>
<title>Factorial Function</title>
<para>...para...</para>
<para>...para...</para>
<toplevelcode><blockcode>(fdef fact (n)⇰
</blockcode><indentation style="margin-left: 2ch;"><blockcomment>
<para>...block...</para>
<para>...block...</para></blockcomment></indentation><blockcode>
(if (= n 0)
1 <comment>...eol...</comment>
(* n (fact (- n 1))))) ⇰
<comment>...eoll...</comment></blockcode></toplevelcode>

<toplevelcode><blockcode>(test 1 (fact 0))
(test 120 (fact 5))
(test 3628800 (fact 10))</blockcode></toplevelcode>
</section>
<section>
<title>Fibonacci Sequence</title>
<para>...para...</para>
<para>...para...</para>
<toplevelcode><blockcode>(fdef fib (n)⇰
</blockcode><indentation style="margin-left: 2ch;"><blockcomment>
<para>...block...</para>
<para>...block...</para></blockcomment></indentation><blockcode>
(if (= n 0)
0 <comment>...eol...</comment>
(if (= n 1)
1 <comment>...eol...</comment>
(+ (fib (- n 1)) (fib (- n 2)))))) ⇰
<comment>...eoll...</comment></blockcode></toplevelcode>

<toplevelcode><blockcode>(test 0 (fib 0))
(test 5 (fib 5))
(test 55 (fib 10))</blockcode></toplevelcode>
</section>
</chapter>
+

Here are a few remarks about the XML document:

+ +

The second step of the documentation generation process converts the XML document into the following HTML document:

+
<html>
<head>
</head>
<body>
<h1>Recursive Functions</h1>
<p>...para...</p>
<p>...para...</p>
<h2>Factorial Function</h2>
<p>...para...</p>
<p>...para...</p>
<pre class="blockcode">(fdef fact (n)</pre>
<div class="indentation" style="margin-left: 2ch;">
<div class="blockcomment">
<p>...block...</p>
<p>...block...</p>
</div>
</div>
<pre class="blockcode">
(if (= n 0)
1 <span class="eolcomment">...eol...</span>
(* n (fact (- n 1))))) ⇰
<span class="eolcomment">...eoll...</span></pre>
<pre class="blockcode">(test 1 (fact 0))
(test 120 (fact 5))
(test 3628800 (fact 10))</pre>
<h2>Fibonacci Sequence</h2>
<p>...para...</p>
<p>...para...</p>
<pre class="blockcode">(fdef fib (n)</pre>
<div class="indentation" style="margin-left: 2ch;">
<div class="blockcomment">
<p>...block...</p>
<p>...block...</p>
</div>
</div>
<pre class="blockcode">
(if (= n 0)
0 <span class="eolcomment">...eol...</span>
(if (= n 1)
1 <span class="eolcomment">...eol...</span>
(+ (fib (- n 1)) (fib (- n 2)))))) ⇰
<span class="eolcomment">...eoll...</span></pre>
<pre class="blockcode">(test 0 (fib 0))
(test 5 (fib 5))
(test 55 (fib 10))</pre>
</body>
</html>
diff --git a/system-files/TUTORIAL b/system-files/TUTORIAL index 7613694..a355ee1 100644 --- a/system-files/TUTORIAL +++ b/system-files/TUTORIAL @@ -163,9 +163,9 @@
(vdef $\metavar{variable}$ $\metavar{value-form}$)
The purpose of the macro is to define a global variable by ensuring that the variable is bound in the value namespace of the global environment to the primary value of the value-form. The macro call evaluates to the variable.
(fdef $\metavar{variable}$ $\metavar{parameter-list}$ $\metavar{body}$)
-
The purpose of the macro is to define a global function by ensuring that the variable is bound in the function namespace of the global environment to the closure resulting from the evaluation of the _vlambda-form (_vlambda $\metavar{parameter-list}$ $\metavar{body}$). The macro call evaluates to the variable.
+
The purpose of the macro is to define a global function by ensuring that the variable is bound in the function namespace of the global environment to the closure resulting from the evaluation of the _vlambda-form (_vlambda $\metavar{parameter-list}$ $\metavar{body}$). The macro call evaluates to the variable.
(mdef $\metavar{variable}$ $\metavar{parameter-list}$ $\metavar{body}$)
-
The purpose of the macro is to define a global macro by ensuring that the variable is bound in the function namespace of the global environment to the closure resulting from the evaluation of the _mlambda-form (_mlambda $\metavar{parameter-list}$ $\metavar{body}$). The macro call evaluates to the variable.
+
The purpose of the macro is to define a global macro by ensuring that the variable is bound in the function namespace of the global environment to the closure resulting from the evaluation of the _mlambda-form (_mlambda $\metavar{parameter-list}$ $\metavar{body}$). The macro call evaluates to the variable.

Evaluation and Invocation Traces

An evaluation trace is a structured recording of some or all of the evaluations, invocations, and various steps performed by the evaluator to evaluate a form. It is assumed that the evaluation of the form completes normally, which implies that all evaluations and invocations entailed by the evaluation of the form also complete normally. Evaluation traces have the following format:

@@ -201,7 +201,7 @@
  • The form (fref +) is evaluated with respect to $[]$ and $[]$.
  • @@ -223,7 +223,7 @@
  • The global function + is invoked on the numbers 1 and 2.