From e91b656a1be3e85f163f1b8d5a80e1869d19e873 Mon Sep 17 00:00:00 2001 From: ESL Date: Fri, 26 Jul 2024 13:13:49 -0400 Subject: [PATCH] Create syntax-rules.md --- misc/syntax-rules.md | 201 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 misc/syntax-rules.md diff --git a/misc/syntax-rules.md b/misc/syntax-rules.md new file mode 100644 index 0000000..4e5ee0a --- /dev/null +++ b/misc/syntax-rules.md @@ -0,0 +1,201 @@ +# Syntax-rules extensions + +SKINT implements all standard features of R7RS `syntax-rules`, including custom ellipsis, non-final ellipsis patterns, non-binding underscore pattern, and `(... tpl)` template escapes. It also has the following incompatibilities and extensions: + +## Keyword at the beginning of the pattern + +Current implementation is incompatible with R7RS in one aspect: the keyword at the beginning of the pattern in a `` *is* considered a pattern variable (please see below for why it is important). In the future, we will allow this behavior only through simple pattern escape mechanism. + +## Support for boxes + +Boxes, as defined by SRFI-111 and the future `(scheme box)` library, are supported natively, and can be parts of both patterns and templates. See examples of their use below. + +## Simple pattern escape + +A pattern of the form `( )` where `` is the current ellipsis is interpreted as if it were ``, but ellipses and underscores in `` lose their special meaning, e.g.: + +```scheme +(define-syntax underscored + (syntax-rules () + [(_ (... _) (... ...)) (list (... ...) (... _))])) + +(underscored 1 2) +; => (2 1) +``` + +This feature may be useful in macro-generators to make sure that any identifier can play a role of a pattern variable. + +## Named pattern escapes + +A pattern of the form `( )` where `` is the current ellipsis is interpreted as if it were ``, with additional constraint that the S-expression it matches should also satisfy the constraint specified by ``. Predicate names are compared to predefined symbols according to `free-identifier=?` rules. The following named pattern escapes are supported: + + * `(... number? )` + * `(... exact-integer? )` + * `(... boolean? )` + * `(... char? )` + * `(... string? )` + * `(... bytevector? )` + * `(... id? )` + +All but the last predicate have the same meaning as the corresponding Scheme procedures. The `id?` predicate checks if the corresponding S-expression is either a symbol or a syntax object representing an identifier. + +The rationale for adding these escapes is obvious: while `syntax-rules`-based macros can perform very complex calculations with structured S-expressions, they lack an ability to deal with *atomic* S-expressions (with the exception of identifiers – they can be recognized, but the technique for that is quite complicated). + +Example (also uses box templates): + +```scheme +(define-syntax wrap-by-type + (syntax-rules () + [(_ (... string? x)) '#&x] + [(_ (... number? x)) '#(x)] + [(_ x) 'x])) + +(list (wrap-by-type 42) (wrap-by-type "yes") (wrap-by-type #\c))) +; => (#(42) #&"yes" #\c) +``` + +## Named template escapes + +A template of the form `( )` where `` is the current ellipsis is interpreted as follows. First, `` (which can be any nonempty sequence of `