stxclass: minor improvements to syntax, docs, literals, etc
svn: r11808
This commit is contained in:
parent
d44850f515
commit
f22c42d8a4
|
@ -1,5 +1,5 @@
|
||||||
#lang setup/infotab
|
#lang setup/infotab
|
||||||
|
|
||||||
;; Not ready yet
|
;; Not ready yet
|
||||||
#;(define scribblings '(("stxclass.scrbl")))
|
(define scribblings '(("stxclass.scrbl")))
|
||||||
(define compile-omit-paths '("test.ss"))
|
(define compile-omit-paths '("test.ss"))
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
(require scheme/stxparam
|
(require scheme/stxparam
|
||||||
(for-syntax scheme/base))
|
(for-syntax scheme/base))
|
||||||
(provide pattern
|
(provide pattern
|
||||||
union
|
|
||||||
...*
|
...*
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -15,13 +14,15 @@
|
||||||
current-expression
|
current-expression
|
||||||
current-macro-name)
|
current-macro-name)
|
||||||
|
|
||||||
;; (define-syntax-class name SyntaxClassRHS)
|
;; (define-syntax-class name SyntaxClassDirective* SyntaxClassRHS*)
|
||||||
;; (define-syntax-class (name id ...) SyntaxClassRHS)
|
;; (define-syntax-class (name id ...) SyntaxClassDirective* SyntaxClassRHS*)
|
||||||
|
|
||||||
;; A SyntaxClassRHS is one of
|
;; A SCDirective is one of
|
||||||
|
;; #:description String
|
||||||
|
;; #:transparent
|
||||||
|
|
||||||
|
;; A SyntaxClassRHS is
|
||||||
;; (pattern Pattern PatternDirective ...)
|
;; (pattern Pattern PatternDirective ...)
|
||||||
;; (union SyntaxClassRHS ...)
|
|
||||||
;; syntax-class-id
|
|
||||||
|
|
||||||
;; A Pattern is one of
|
;; A Pattern is one of
|
||||||
;; name:syntaxclass
|
;; name:syntaxclass
|
||||||
|
@ -56,7 +57,6 @@
|
||||||
(raise-syntax-error #f "keyword used out of context" stx))))
|
(raise-syntax-error #f "keyword used out of context" stx))))
|
||||||
|
|
||||||
(define-keyword pattern)
|
(define-keyword pattern)
|
||||||
(define-keyword union)
|
|
||||||
(define-keyword ...*)
|
(define-keyword ...*)
|
||||||
(define-keyword ...**)
|
(define-keyword ...**)
|
||||||
|
|
||||||
|
@ -75,10 +75,15 @@
|
||||||
(define (current-macro-name)
|
(define (current-macro-name)
|
||||||
(let ([expr (current-expression)])
|
(let ([expr (current-expression)])
|
||||||
(and expr
|
(and expr
|
||||||
(syntax-case expr ()
|
(syntax-case expr (set!)
|
||||||
|
[(set! kw . _)
|
||||||
|
#'kw]
|
||||||
[(kw . _)
|
[(kw . _)
|
||||||
(identifier? #'kw)
|
(identifier? #'kw)
|
||||||
#'kw]
|
#'kw]
|
||||||
|
[kw
|
||||||
|
(identifier? #'kw)
|
||||||
|
#'kw]
|
||||||
[_ #f]))))
|
[_ #f]))))
|
||||||
|
|
||||||
;; A PatternParseResult is one of
|
;; A PatternParseResult is one of
|
||||||
|
@ -113,7 +118,8 @@
|
||||||
(let loop ([f1 frontier1] [f2 frontier2])
|
(let loop ([f1 frontier1] [f2 frontier2])
|
||||||
(cond [(and (null? f1) (null? f2))
|
(cond [(and (null? f1) (null? f2))
|
||||||
;; FIXME: merge
|
;; FIXME: merge
|
||||||
(k x1 `(union ,p1 ,p2) #f frontier1)]
|
(let ([p (and p1 p2 (format "~a; or ~a" p1 p2))])
|
||||||
|
(k x1 p #f frontier1))]
|
||||||
[(and (pair? f1) (null? f2)) (go1)]
|
[(and (pair? f1) (null? f2)) (go1)]
|
||||||
[(and (null? f1) (pair? f2)) (go2)]
|
[(and (null? f1) (pair? f2)) (go2)]
|
||||||
[(and (pair? f1) (pair? f2))
|
[(and (pair? f1) (pair? f2))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#lang scheme/base
|
#lang scheme/base
|
||||||
|
|
||||||
(require "sc.ss"
|
(require "sc.ss"
|
||||||
|
"util.ss"
|
||||||
syntax/stx
|
syntax/stx
|
||||||
syntax/kerncase
|
syntax/kerncase
|
||||||
scheme/struct-info
|
scheme/struct-info
|
||||||
|
@ -49,8 +50,8 @@
|
||||||
(define-syntax-class define-syntaxes-form
|
(define-syntax-class define-syntaxes-form
|
||||||
(pattern (kw:define-syntaxes-kw (var:identifier ...) rhs)))
|
(pattern (kw:define-syntaxes-kw (var:identifier ...) rhs)))
|
||||||
(define-syntax-class definition-form
|
(define-syntax-class definition-form
|
||||||
(union define-values-form
|
(pattern :define-values-form)
|
||||||
define-syntaxes-form))
|
(pattern :define-syntaxes-form))
|
||||||
|
|
||||||
(define-basic-syntax-class static
|
(define-basic-syntax-class static
|
||||||
([datum 0] [value 0])
|
([datum 0] [value 0])
|
||||||
|
@ -123,7 +124,7 @@
|
||||||
[expr 1])
|
[expr 1])
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
(let-values ([(ex1 ex2 defs vdefs sdefs exprs)
|
(let-values ([(ex1 ex2 defs vdefs sdefs exprs)
|
||||||
(head-local-expand-syntaxes x #f #t)])
|
(head-local-expand-and-categorize-syntaxes x #f #; #t)])
|
||||||
(list ex1 ex2 defs vdefs sdefs exprs))))
|
(list ex1 ex2 defs vdefs sdefs exprs))))
|
||||||
|
|
||||||
(define-basic-syntax-class internal-definitions
|
(define-basic-syntax-class internal-definitions
|
||||||
|
@ -135,72 +136,9 @@
|
||||||
[expr 1])
|
[expr 1])
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
(let-values ([(ex1 ex2 defs vdefs sdefs exprs)
|
(let-values ([(ex1 ex2 defs vdefs sdefs exprs)
|
||||||
(head-local-expand-syntaxes x #t #f)])
|
(head-local-expand-and-categorize-syntaxes x #t #; #f)])
|
||||||
(list ex1 ex2 defs vdefs sdefs exprs))))
|
(list ex1 ex2 defs vdefs sdefs exprs))))
|
||||||
|
|
||||||
;; head-local-expand-syntaxes : syntax boolean boolean -> stxs ^ 6
|
|
||||||
;; Setting allow-def-after-expr? allows def/expr interleaving.
|
|
||||||
;; Setting need-expr? requires at least one expr to be present.
|
|
||||||
(define (head-local-expand-syntaxes x allow-def-after-expr? need-expr?)
|
|
||||||
(let ([intdef (syntax-local-make-definition-context)]
|
|
||||||
[ctx '(block)])
|
|
||||||
(let loop ([x x] [ex null] [defs null] [vdefs null] [sdefs null] [exprs null])
|
|
||||||
(cond [(stx-pair? x)
|
|
||||||
(let ([ee (local-expand (stx-car x)
|
|
||||||
ctx
|
|
||||||
(kernel-form-identifier-list)
|
|
||||||
intdef)])
|
|
||||||
(syntax-case ee (begin define-values define-syntaxes)
|
|
||||||
[(begin e ...)
|
|
||||||
(loop (append (syntax->list #'(e ...)) (stx-cdr x)) ex defs vdefs sdefs exprs)]
|
|
||||||
[(begin . _)
|
|
||||||
(raise-syntax-error #f "bad begin form" ee)]
|
|
||||||
[(define-values (var ...) rhs)
|
|
||||||
(andmap identifier? (syntax->list #'(var ...)))
|
|
||||||
(begin
|
|
||||||
(when (and (pair? exprs) (not allow-def-after-expr?))
|
|
||||||
(raise-syntax-error #f "definition after expression" ee))
|
|
||||||
(syntax-local-bind-syntaxes (syntax->list #'(var ...)) #f intdef)
|
|
||||||
(loop (stx-cdr x)
|
|
||||||
(cons ee ex)
|
|
||||||
(cons ee defs)
|
|
||||||
(cons ee vdefs)
|
|
||||||
sdefs
|
|
||||||
exprs))]
|
|
||||||
[(define-values . _)
|
|
||||||
(raise-syntax-error #f "bad define-values form" ee)]
|
|
||||||
[(define-syntaxes (var ...) rhs)
|
|
||||||
(andmap identifier? (syntax->list #'(var ...)))
|
|
||||||
(begin
|
|
||||||
(when (and (pair? exprs) (not allow-def-after-expr?))
|
|
||||||
(raise-syntax-error #f "definition after expression" ee))
|
|
||||||
(syntax-local-bind-syntaxes (syntax->list #'(var ...))
|
|
||||||
#'rhs
|
|
||||||
intdef)
|
|
||||||
(loop (stx-cdr x)
|
|
||||||
(cons ee ex)
|
|
||||||
(cons ee defs)
|
|
||||||
vdefs
|
|
||||||
(cons ee sdefs)
|
|
||||||
exprs))]
|
|
||||||
[(define-syntaxes . _)
|
|
||||||
(raise-syntax-error #f "bad define-syntaxes form" ee)]
|
|
||||||
[_
|
|
||||||
(loop (stx-cdr x)
|
|
||||||
(cons ee ex)
|
|
||||||
defs
|
|
||||||
vdefs
|
|
||||||
sdefs
|
|
||||||
(cons ee exprs))]))]
|
|
||||||
[(stx-null? x)
|
|
||||||
(let ([ex (reverse ex)])
|
|
||||||
(values ex
|
|
||||||
ex
|
|
||||||
(reverse defs)
|
|
||||||
(reverse vdefs)
|
|
||||||
(reverse sdefs)
|
|
||||||
(reverse exprs)))]))))
|
|
||||||
|
|
||||||
(define-syntax-rule (define-contract-stxclass name c)
|
(define-syntax-rule (define-contract-stxclass name c)
|
||||||
(define-basic-syntax-class* (name)
|
(define-basic-syntax-class* (name)
|
||||||
([orig-stx 0])
|
([orig-stx 0])
|
||||||
|
|
|
@ -72,8 +72,12 @@
|
||||||
;; rhs->pks : RHS (listof SAttr) identifier -> (listof PK)
|
;; rhs->pks : RHS (listof SAttr) identifier -> (listof PK)
|
||||||
(define (rhs->pks rhs relsattrs main-var)
|
(define (rhs->pks rhs relsattrs main-var)
|
||||||
(match rhs
|
(match rhs
|
||||||
[(struct rhs:union (orig-stx attrs rhss))
|
[(struct rhs:union (orig-stx attrs transparent? description patterns))
|
||||||
(for*/list ([rhs rhss] [pk (rhs->pks rhs relsattrs main-var)]) pk)]
|
(for*/list ([rhs patterns] [pk (rhs-pattern->pks rhs relsattrs main-var)])
|
||||||
|
pk)]))
|
||||||
|
|
||||||
|
(define (rhs-pattern->pks rhs relsattrs main-var)
|
||||||
|
(match rhs
|
||||||
[(struct rhs:pattern (orig-stx attrs pattern decls remap sides))
|
[(struct rhs:pattern (orig-stx attrs pattern decls remap sides))
|
||||||
(list (make-pk (list pattern)
|
(list (make-pk (list pattern)
|
||||||
(expr:convert-sides sides
|
(expr:convert-sides sides
|
||||||
|
@ -143,7 +147,7 @@
|
||||||
#:literals literals)])
|
#:literals literals)])
|
||||||
(syntax-case rest ()
|
(syntax-case rest ()
|
||||||
[(b)
|
[(b)
|
||||||
(let* ([pattern (parse-pattern #'p decls)])
|
(let* ([pattern (parse-pattern #'p decls 0)])
|
||||||
(make-pk (list pattern)
|
(make-pk (list pattern)
|
||||||
(expr:convert-sides sides
|
(expr:convert-sides sides
|
||||||
(pattern-attrs pattern)
|
(pattern-attrs pattern)
|
||||||
|
@ -202,6 +206,55 @@
|
||||||
#`(let-syntax ([failvar (make-rename-transformer (quote-syntax #,failid))])
|
#`(let-syntax ([failvar (make-rename-transformer (quote-syntax #,failid))])
|
||||||
(try failvar (expr ...))))))]))
|
(try failvar (expr ...))))))]))
|
||||||
|
|
||||||
|
(define (report-stxclass stxclass)
|
||||||
|
(and stxclass
|
||||||
|
(format "expected ~a"
|
||||||
|
(or (sc-description stxclass)
|
||||||
|
(sc-name stxclass)))))
|
||||||
|
|
||||||
|
(define (report-constants pairs? data literals)
|
||||||
|
(cond [pairs? #f]
|
||||||
|
[(null? data)
|
||||||
|
(format "expected ~a" (report-choices-literals literals))]
|
||||||
|
[(null? literals)
|
||||||
|
(format "expected ~a" (report-choices-data data))]
|
||||||
|
[else
|
||||||
|
(format "expected ~a; or ~a"
|
||||||
|
(report-choices-data data)
|
||||||
|
(report-choices-literals literals))]))
|
||||||
|
|
||||||
|
(define (report-choices-literals literals0)
|
||||||
|
(define literals
|
||||||
|
(sort (map syntax-e literals0)
|
||||||
|
string<?
|
||||||
|
#:key symbol->string
|
||||||
|
#:cache-keys? #t))
|
||||||
|
(case (length literals)
|
||||||
|
[(1) (format "the literal identifier ~s" (car literals))]
|
||||||
|
[else (format "one of the following literal identifiers: ~a"
|
||||||
|
(comma-list literals))]))
|
||||||
|
|
||||||
|
(define (report-choices-data data)
|
||||||
|
(case (length data)
|
||||||
|
[(1) (format "the datum ~s" (car data))]
|
||||||
|
[else (format "one of the following literals: ~a"
|
||||||
|
(comma-list data))]))
|
||||||
|
|
||||||
|
(define (comma-list items0)
|
||||||
|
(define items (for/list ([item items0]) (format "~s" item)))
|
||||||
|
(define (loop items)
|
||||||
|
(cond [(null? items)
|
||||||
|
null]
|
||||||
|
[(null? (cdr items))
|
||||||
|
(list ", or " (car items))]
|
||||||
|
[else
|
||||||
|
(list* ", " (car items) (loop (cdr items)))]))
|
||||||
|
(case (length items)
|
||||||
|
[(2) (format "~a or ~a" (car items) (cadr items))]
|
||||||
|
[else (let ([strings (list* (car items) (loop (cdr items)))])
|
||||||
|
(apply string-append strings))]))
|
||||||
|
|
||||||
|
|
||||||
;; parse:extpk : (listof identifier) (listof FC) ExtPK identifier -> stx
|
;; parse:extpk : (listof identifier) (listof FC) ExtPK identifier -> stx
|
||||||
;; Pre: vars is not empty
|
;; Pre: vars is not empty
|
||||||
(define (parse:extpk vars fcs extpk failid)
|
(define (parse:extpk vars fcs extpk failid)
|
||||||
|
@ -217,7 +270,7 @@
|
||||||
(if (ok? r)
|
(if (ok? r)
|
||||||
#,(parse:pks (cdr vars) (cdr fcs) (shift-pks:id pks #'r) failid)
|
#,(parse:pks (cdr vars) (cdr fcs) (shift-pks:id pks #'r) failid)
|
||||||
#,(fail failid (car vars)
|
#,(fail failid (car vars)
|
||||||
#:pattern (and stxclass (sc-name stxclass))
|
#:pattern (report-stxclass stxclass)
|
||||||
#:fc (car fcs)))))]
|
#:fc (car fcs)))))]
|
||||||
[(struct cpks (pairpks datumpkss literalpkss))
|
[(struct cpks (pairpks datumpkss literalpkss))
|
||||||
(with-syntax ([var0 (car vars)]
|
(with-syntax ([var0 (car vars)]
|
||||||
|
@ -270,13 +323,13 @@
|
||||||
#'())
|
#'())
|
||||||
[datum-test datum-rhs] ...
|
[datum-test datum-rhs] ...
|
||||||
[else
|
[else
|
||||||
#,(let ([ps #'(pair-pattern ... datum-pattern ...)])
|
#,(fail failid (car vars)
|
||||||
(with-syntax ([ep (if (= (length (syntax->list ps)) 1)
|
#:pattern (report-constants (pair? pairpks)
|
||||||
(car (syntax->list ps))
|
(for/list ([d datumpkss])
|
||||||
#`(union #,@ps))])
|
(datumpks-datum d))
|
||||||
(fail failid (car vars)
|
(for/list ([l literalpkss])
|
||||||
#:pattern #'ep
|
(literalpks-literal l)))
|
||||||
#:fc (car fcs))))]))))]
|
#:fc (car fcs))]))))]
|
||||||
#;
|
#;
|
||||||
[(struct pk ((cons (struct pat:splice (orig-stx attrs depth head tail))
|
[(struct pk ((cons (struct pat:splice (orig-stx attrs depth head tail))
|
||||||
rest-ps)
|
rest-ps)
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
format-symbol)
|
format-symbol)
|
||||||
|
|
||||||
;; An SC is one of (make-sc symbol (listof symbol) (list-of SAttr) identifier)
|
;; An SC is one of (make-sc symbol (listof symbol) (list-of SAttr) identifier)
|
||||||
(define-struct sc (name inputs attrs parser-name)
|
(define-struct sc (name inputs attrs parser-name description)
|
||||||
#:property prop:procedure (lambda (self stx) (sc-parser-name self))
|
#:property prop:procedure (lambda (self stx) (sc-parser-name self))
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
|
@ -44,13 +44,19 @@
|
||||||
(define-struct attr (name depth inner)
|
(define-struct attr (name depth inner)
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
;; A RHS is one of
|
;; RHSBase is stx (listof SAttr)
|
||||||
;; (make-rhs:union <RHS> (listof RHS))
|
(define-struct rhs (orig-stx attrs)
|
||||||
;; (make-rhs:pattern <RHS> Pattern Env Env (listof SideClause))
|
#:transparent)
|
||||||
;; where <RHS> is stx (listof SAttr)
|
|
||||||
(define-struct rhs (orig-stx attrs) #:transparent)
|
;; A RHS is
|
||||||
(define-struct (rhs:union rhs) (rhss) #:transparent)
|
;; (make-rhs:union <RHSBase> (listof RHS))
|
||||||
(define-struct (rhs:pattern rhs) (pattern decls remap wheres) #:transparent)
|
(define-struct (rhs:union rhs) (transparent? description patterns)
|
||||||
|
#:transparent)
|
||||||
|
|
||||||
|
;; An RHSPattern is
|
||||||
|
;; (make-rhs:pattern <RHSBase> Pattern Env Env (listof SideClause))
|
||||||
|
(define-struct (rhs:pattern rhs) (pattern decls remap wheres)
|
||||||
|
#:transparent)
|
||||||
|
|
||||||
;; A Pattern is one of
|
;; A Pattern is one of
|
||||||
;; (make-pat:id <Pattern> identifier SC/#f (listof stx))
|
;; (make-pat:id <Pattern> identifier SC/#f (listof stx))
|
||||||
|
@ -88,7 +94,7 @@
|
||||||
;; make-empty-sc : identifier => SC
|
;; make-empty-sc : identifier => SC
|
||||||
;; Dummy stxclass for calculating attributes of recursive stxclasses.
|
;; Dummy stxclass for calculating attributes of recursive stxclasses.
|
||||||
(define (make-empty-sc name)
|
(define (make-empty-sc name)
|
||||||
(make sc (syntax-e name) null null #f))
|
(make sc (syntax-e name) null null #f #f))
|
||||||
|
|
||||||
(define (iattr? a)
|
(define (iattr? a)
|
||||||
(and (attr? a) (identifier? (attr-name a))))
|
(and (attr? a) (identifier? (attr-name a))))
|
||||||
|
@ -101,8 +107,8 @@
|
||||||
[sattr? (any/c . -> . boolean?)]
|
[sattr? (any/c . -> . boolean?)]
|
||||||
[reorder-iattrs
|
[reorder-iattrs
|
||||||
((listof sattr?) (listof iattr?) (identifier? . -> . symbol?) . -> . (listof iattr?))]
|
((listof sattr?) (listof iattr?) (identifier? . -> . symbol?) . -> . (listof iattr?))]
|
||||||
[parse-rhs (syntax? boolean? . -> . rhs?)]
|
[parse-rhs (syntax? boolean? syntax? . -> . rhs?)]
|
||||||
[parse-splice-rhs (syntax? boolean? . -> . rhs?)]
|
[parse-splice-rhs (syntax? boolean? syntax? . -> . rhs?)]
|
||||||
[flatten-sattrs
|
[flatten-sattrs
|
||||||
([(listof sattr?)] [exact-integer? (or/c symbol? false/c)] . ->* . (listof sattr?))]
|
([(listof sattr?)] [exact-integer? (or/c symbol? false/c)] . ->* . (listof sattr?))]
|
||||||
|
|
||||||
|
@ -208,25 +214,51 @@
|
||||||
|
|
||||||
(define allow-unbound-stxclasses (make-parameter #f))
|
(define allow-unbound-stxclasses (make-parameter #f))
|
||||||
|
|
||||||
;; parse-rhs : stx(SyntaxClassRHS) boolean -> RHS
|
;; parse-rhs : stx(SyntaxClassRHS) boolean stx -> RHS
|
||||||
;; If allow-unbound? is true, then unbound stxclass acts as if it has no attrs.
|
;; If allow-unbound? is true, then unbound stxclass acts as if it has no attrs.
|
||||||
;; Used for pass1 (attr collection); parser requires stxclasses to be bound.
|
;; Used for pass1 (attr collection); parser requires stxclasses to be bound.
|
||||||
(define (parse-rhs stx allow-unbound?)
|
(define (parse-rhs stx allow-unbound? ctx)
|
||||||
(parse-rhs* stx allow-unbound? #f))
|
(parse-rhs* stx allow-unbound? #f ctx))
|
||||||
|
|
||||||
;; parse-splice-rhs : stx(SyntaxClassRHS) boolean -> RHS
|
;; parse-splice-rhs : stx(SyntaxClassRHS) boolean stx -> RHS
|
||||||
;; If allow-unbound? is true, then unbound stxclass acts as if it has no attrs.
|
;; If allow-unbound? is true, then unbound stxclass acts as if it has no attrs.
|
||||||
;; Used for pass1 (attr collection); parser requires stxclasses to be bound.
|
;; Used for pass1 (attr collection); parser requires stxclasses to be bound.
|
||||||
(define (parse-splice-rhs stx allow-unbound?)
|
(define (parse-splice-rhs stx allow-unbound? ctx)
|
||||||
(parse-rhs* stx allow-unbound? #t))
|
(parse-rhs* stx allow-unbound? #t ctx))
|
||||||
|
|
||||||
;; parse-rhs* : stx boolean boolean -> RHS
|
;; parse-rhs* : stx boolean boolean -> RHS
|
||||||
(define (parse-rhs* stx allow-unbound? splice?)
|
(define (parse-rhs* stx allow-unbound? splice? ctx)
|
||||||
(syntax-case stx (pattern union)
|
(define-values (chunks rest)
|
||||||
|
(chunk-kw-seq stx rhs-directive-table #:context ctx))
|
||||||
|
(define lits (assq '#:literals chunks))
|
||||||
|
(define desc (assq '#:description chunks))
|
||||||
|
(define trans (assq '#:transparent chunks))
|
||||||
|
(define literals (if lits (caddr lits) null))
|
||||||
|
(define (gather-patterns stx)
|
||||||
|
(syntax-case stx (pattern)
|
||||||
|
[((pattern . _) . rest)
|
||||||
|
(cons (parse-rhs-pattern (stx-car stx) allow-unbound? splice? literals)
|
||||||
|
(gather-patterns #'rest))]
|
||||||
|
[()
|
||||||
|
null]))
|
||||||
|
(define patterns (gather-patterns rest))
|
||||||
|
(when (null? patterns)
|
||||||
|
(raise-syntax-error #f "syntax class has no variants" ctx))
|
||||||
|
(let ([sattrs (intersect-attrss (map rhs-attrs patterns) ctx)])
|
||||||
|
(make rhs:union stx sattrs
|
||||||
|
(and desc (caddr desc))
|
||||||
|
(and trans #t)
|
||||||
|
patterns)))
|
||||||
|
|
||||||
|
;; parse-rhs-pattern : stx boolean boolean (listof identifier) -> RHS
|
||||||
|
(define (parse-rhs-pattern stx allow-unbound? splice? literals)
|
||||||
|
(syntax-case stx (pattern)
|
||||||
[(pattern p . rest)
|
[(pattern p . rest)
|
||||||
(parameterize ((allow-unbound-stxclasses allow-unbound?))
|
(parameterize ((allow-unbound-stxclasses allow-unbound?))
|
||||||
(let-values ([(rest decls remap clauses)
|
(let-values ([(rest decls remap clauses)
|
||||||
(parse-pattern-directives #'rest #:sc? #t)])
|
(parse-pattern-directives #'rest
|
||||||
|
#:literals literals
|
||||||
|
#:sc? #t)])
|
||||||
(unless (stx-null? rest)
|
(unless (stx-null? rest)
|
||||||
(raise-syntax-error #f "unexpected terms after pattern directives"
|
(raise-syntax-error #f "unexpected terms after pattern directives"
|
||||||
(if (pair? rest) (car rest) rest)))
|
(if (pair? rest) (car rest) rest)))
|
||||||
|
@ -241,25 +273,16 @@
|
||||||
(map pattern-attrs with-patterns))
|
(map pattern-attrs with-patterns))
|
||||||
stx)]
|
stx)]
|
||||||
[sattrs (iattrs->sattrs attrs remap)])
|
[sattrs (iattrs->sattrs attrs remap)])
|
||||||
(make rhs:pattern stx sattrs pattern decls remap clauses))))]
|
(make rhs:pattern stx sattrs pattern decls remap clauses))))]))
|
||||||
[(union p ...)
|
|
||||||
(let* ([rhss (for/list ([rhs (syntax->list #'(p ...))])
|
;; rhs-directive-table
|
||||||
(parse-rhs* rhs allow-unbound? splice?))]
|
(define rhs-directive-table
|
||||||
[sattrs (intersect-attrss (map rhs-attrs rhss) stx)])
|
(list (list '#:literals check-idlist)
|
||||||
(make rhs:union stx sattrs rhss))]
|
(list '#:description check-string)
|
||||||
[(id arg ...)
|
(list '#:transparent)))
|
||||||
(identifier? #'id)
|
|
||||||
(parse-rhs* (syntax/loc stx (pattern || #:declare || (id arg ...)))
|
|
||||||
allow-unbound?
|
|
||||||
splice?)]
|
|
||||||
[id
|
|
||||||
(identifier? #'id)
|
|
||||||
(parse-rhs* (syntax/loc stx (pattern || #:declare || id))
|
|
||||||
allow-unbound?
|
|
||||||
splice?)]))
|
|
||||||
|
|
||||||
;; parse-pattern : stx(Pattern) env number -> Pattern
|
;; parse-pattern : stx(Pattern) env number -> Pattern
|
||||||
(define (parse-pattern stx [decls (lambda _ #f)] [depth 0] [allow-splice? #f])
|
(define (parse-pattern stx decls depth [allow-splice? #f])
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[dots
|
[dots
|
||||||
(or (dots? #'dots)
|
(or (dots? #'dots)
|
||||||
|
@ -354,12 +377,6 @@
|
||||||
(raise-syntax-error 'pattern "expected sequence of patterns or sequence directive"
|
(raise-syntax-error 'pattern "expected sequence of patterns or sequence directive"
|
||||||
(if (pair? stx) (car stx) stx))]))
|
(if (pair? stx) (car stx) stx))]))
|
||||||
|
|
||||||
(define (check-nat/f stx)
|
|
||||||
(let ([d (syntax-e stx)])
|
|
||||||
(unless (nat/f d)
|
|
||||||
(raise-syntax-error #f "expected exact nonnegative integer or #f" stx))
|
|
||||||
stx))
|
|
||||||
|
|
||||||
(define head-directive-table
|
(define head-directive-table
|
||||||
(list (list '#:min check-nat/f)
|
(list (list '#:min check-nat/f)
|
||||||
(list '#:max check-nat/f)
|
(list '#:max check-nat/f)
|
||||||
|
@ -369,7 +386,7 @@
|
||||||
(list '#:mand)))
|
(list '#:mand)))
|
||||||
|
|
||||||
(define (parse-heads-k stx heads heads-attrs heads-depth k)
|
(define (parse-heads-k stx heads heads-attrs heads-depth k)
|
||||||
(define-values (chunks rest) (chunk-kw-seq stx head-directive-table))
|
(define-values (chunks rest) (chunk-kw-seq/no-dups stx head-directive-table))
|
||||||
(reject-duplicate-chunks chunks)
|
(reject-duplicate-chunks chunks)
|
||||||
(let* ([min-row (assq '#:min chunks)]
|
(let* ([min-row (assq '#:min chunks)]
|
||||||
[max-row (assq '#:max chunks)]
|
[max-row (assq '#:max chunks)]
|
||||||
|
@ -412,10 +429,6 @@
|
||||||
(and occurs-row (caddr occurs-row))
|
(and occurs-row (caddr occurs-row))
|
||||||
(and default-row (caddr default-row)))))
|
(and default-row (caddr default-row)))))
|
||||||
|
|
||||||
;; nat/f : any -> boolean
|
|
||||||
(define (nat/f x)
|
|
||||||
(or (not x) (exact-nonnegative-integer? x)))
|
|
||||||
|
|
||||||
;; append-attrs : (listof (listof IAttr)) stx -> (listof IAttr)
|
;; append-attrs : (listof (listof IAttr)) stx -> (listof IAttr)
|
||||||
(define (append-attrs attrss stx)
|
(define (append-attrs attrss stx)
|
||||||
(let* ([all (apply append attrss)]
|
(let* ([all (apply append attrss)]
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
syntax/stx
|
syntax/stx
|
||||||
"kws.ss")
|
"kws.ss")
|
||||||
(provide define-syntax-class
|
(provide define-syntax-class
|
||||||
define-syntax-splice-class
|
|
||||||
define-basic-syntax-class
|
define-basic-syntax-class
|
||||||
define-basic-syntax-class*
|
define-basic-syntax-class*
|
||||||
parse-sc
|
parse-sc
|
||||||
|
@ -24,7 +23,6 @@
|
||||||
with-patterns
|
with-patterns
|
||||||
|
|
||||||
pattern
|
pattern
|
||||||
union
|
|
||||||
...*
|
...*
|
||||||
|
|
||||||
fail-sc
|
fail-sc
|
||||||
|
@ -35,27 +33,32 @@
|
||||||
|
|
||||||
(define-syntax (define-syntax-class stx)
|
(define-syntax (define-syntax-class stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(define-syntax-class (name arg ...) rhs)
|
[(define-syntax-class (name arg ...) . rhss)
|
||||||
#'(begin (define-syntax name
|
#`(begin (define-syntax name
|
||||||
|
(let ([the-rhs (parse-rhs (quote-syntax rhss) #t (quote-syntax #,stx))])
|
||||||
(make sc 'name
|
(make sc 'name
|
||||||
'(arg ...)
|
'(arg ...)
|
||||||
(rhs-attrs (parse-rhs (quote-syntax rhs) #t))
|
(rhs-attrs the-rhs)
|
||||||
((syntax-local-certifier) #'parser)))
|
((syntax-local-certifier) #'parser)
|
||||||
(define parser (rhs->parser name rhs (arg ...))))]
|
(rhs:union-description the-rhs))))
|
||||||
[(define-syntax-class name rhs)
|
(define parser (rhs->parser name rhss (arg ...) #,stx)))]
|
||||||
#'(define-syntax-class (name) rhs)]))
|
[(define-syntax-class name . rhss)
|
||||||
|
(syntax/loc stx
|
||||||
|
(define-syntax-class (name) . rhss))]))
|
||||||
|
|
||||||
|
#;
|
||||||
(define-syntax (define-syntax-splice-class stx)
|
(define-syntax (define-syntax-splice-class stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(define-syntax-splice-class (name arg ...) rhs)
|
[(define-syntax-splice-class (name arg ...) . rhss)
|
||||||
#'(begin (define-syntax name
|
#`(begin (define-syntax name
|
||||||
(make ssc 'name
|
(make ssc 'name
|
||||||
'(arg ...)
|
'(arg ...)
|
||||||
(rhs-attrs (parse-splice-rhs (quote-syntax rhs) #t))
|
(rhs-attrs
|
||||||
|
(parse-splice-rhs (quote-syntax rhss) #t (quote-syntax #,stx)))
|
||||||
((syntax-local-certifier) #'parser)))
|
((syntax-local-certifier) #'parser)))
|
||||||
(define parser (splice-rhs->parser name rhs (arg ...))))]
|
(define parser (splice-rhs->parser name rhss (arg ...) #,stx)))]
|
||||||
[(define-syntax-splice-class name rhs)
|
[(define-syntax-splice-class name . rhss)
|
||||||
#'(define-syntax-splice-class (name) rhs)]))
|
(syntax/loc stx (define-syntax-splice-class (name) . rhss))]))
|
||||||
|
|
||||||
(define-syntax define-basic-syntax-class
|
(define-syntax define-basic-syntax-class
|
||||||
(syntax-rules ()
|
(syntax-rules ()
|
||||||
|
@ -89,12 +92,13 @@
|
||||||
(make sc 'name
|
(make sc 'name
|
||||||
'(arg ...)
|
'(arg ...)
|
||||||
(list (make-attr 'attr-name 'attr-depth null) ...)
|
(list (make-attr 'attr-name 'attr-depth null) ...)
|
||||||
((syntax-local-certifier) #'parser))))]))
|
((syntax-local-certifier) #'parser)
|
||||||
|
#f)))]))
|
||||||
|
|
||||||
(define-syntax (rhs->parser stx)
|
(define-syntax (rhs->parser stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(rhs->parser name rhs (arg ...))
|
[(rhs->parser name rhss (arg ...) ctx)
|
||||||
(let ([rhs (parse-rhs #'rhs #f)]
|
(let ([rhs (parse-rhs #'rhss #f #'ctx)]
|
||||||
[sc (syntax-local-value #'name)])
|
[sc (syntax-local-value #'name)])
|
||||||
(parse:rhs rhs
|
(parse:rhs rhs
|
||||||
(sc-attrs sc)
|
(sc-attrs sc)
|
||||||
|
@ -182,7 +186,7 @@
|
||||||
[_
|
[_
|
||||||
(err "expected end of list" x)])]
|
(err "expected end of list" x)])]
|
||||||
[expected
|
[expected
|
||||||
(err (format "expected ~s~a"
|
(err (format "~a~a"
|
||||||
expected
|
expected
|
||||||
(cond [(zero? n) ""]
|
(cond [(zero? n) ""]
|
||||||
[(= n +inf.0) " after matching main pattern"]
|
[(= n +inf.0) " after matching main pattern"]
|
||||||
|
@ -204,3 +208,6 @@
|
||||||
|
|
||||||
(define (fail-sc stx #:pattern [pattern #f] #:reason [reason #f])
|
(define (fail-sc stx #:pattern [pattern #f] #:reason [reason #f])
|
||||||
(make-failed stx pattern reason))
|
(make-failed stx pattern reason))
|
||||||
|
|
||||||
|
(define (syntax-class-fail stx #:reason [reason #f])
|
||||||
|
(make-failed stx #f reason))
|
||||||
|
|
|
@ -3,37 +3,22 @@
|
||||||
(require (for-syntax scheme/base
|
(require (for-syntax scheme/base
|
||||||
scheme/struct-info)
|
scheme/struct-info)
|
||||||
syntax/boundmap
|
syntax/boundmap
|
||||||
|
syntax/kerncase
|
||||||
syntax/stx)
|
syntax/stx)
|
||||||
|
|
||||||
(provide make
|
(provide make
|
||||||
|
|
||||||
chunk-kw-seq/no-dups
|
chunk-kw-seq/no-dups
|
||||||
chunk-kw-seq
|
chunk-kw-seq
|
||||||
reject-duplicate-chunks
|
reject-duplicate-chunks
|
||||||
check-id
|
check-id
|
||||||
#|
|
check-nat/f
|
||||||
monomap?
|
check-string
|
||||||
monomap-get
|
check-idlist
|
||||||
monomap-put!
|
|
||||||
monomap-map
|
|
||||||
monomap-for-each
|
|
||||||
monomap-domain
|
|
||||||
monomap-range
|
|
||||||
|
|
||||||
isomap?
|
head-local-expand-and-categorize-syntaxes
|
||||||
isomap-get
|
categorize-expanded-syntaxes
|
||||||
isomap-reverse-get
|
head-local-expand-syntaxes)
|
||||||
isomap-put!
|
|
||||||
isomap-map
|
|
||||||
isomap-for-each
|
|
||||||
isomap-domain
|
|
||||||
isomap-range
|
|
||||||
|
|
||||||
make-bound-id-monomap
|
|
||||||
make-free-id-monomap
|
|
||||||
make-hash-monomap
|
|
||||||
(rename-out [-make-isomap make-isomap])
|
|
||||||
|#
|
|
||||||
)
|
|
||||||
|
|
||||||
(define-syntax (make stx)
|
(define-syntax (make stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
|
@ -80,7 +65,8 @@
|
||||||
[arity (cdr (assq kw-value kws))]
|
[arity (cdr (assq kw-value kws))]
|
||||||
[args+rest (stx-split #'more arity)])
|
[args+rest (stx-split #'more arity)])
|
||||||
(if args+rest
|
(if args+rest
|
||||||
(loop (cdr args+rest) (cons (list* kw-value #'kw (car args+rest)) rchunks))
|
(loop (cdr args+rest)
|
||||||
|
(cons (list* kw-value #'kw (car args+rest)) rchunks))
|
||||||
(raise-syntax-error #f "too few arguments for keyword" #'kw ctx)))]
|
(raise-syntax-error #f "too few arguments for keyword" #'kw ctx)))]
|
||||||
[(kw . more)
|
[(kw . more)
|
||||||
(keyword? (syntax-e #'kw))
|
(keyword? (syntax-e #'kw))
|
||||||
|
@ -90,13 +76,14 @@
|
||||||
(loop stx null))
|
(loop stx null))
|
||||||
|
|
||||||
(define (reject-duplicate-chunks chunks #:context [ctx #f])
|
(define (reject-duplicate-chunks chunks #:context [ctx #f])
|
||||||
|
(define kws (make-hasheq))
|
||||||
(define (loop chunks)
|
(define (loop chunks)
|
||||||
(when (pair? chunks)
|
(when (pair? chunks)
|
||||||
(let* ([kw (caar chunks)]
|
(let ([kw (caar chunks)])
|
||||||
[dup (assq kw (cdr chunks))])
|
(when (hash-ref kws kw #f)
|
||||||
(when dup
|
(raise-syntax-error #f "duplicate keyword argument" (cadar chunks) ctx))
|
||||||
(raise-syntax-error #f "duplicate keyword argument" (cadr dup) ctx))
|
(hash-set! kws kw #t))
|
||||||
(loop (cdr chunks)))))
|
(loop (cdr chunks))))
|
||||||
(loop chunks))
|
(loop chunks))
|
||||||
|
|
||||||
;; stx-split : stx nat -> (cons (listof stx) stx)
|
;; stx-split : stx nat -> (cons (listof stx) stx)
|
||||||
|
@ -115,6 +102,104 @@
|
||||||
(raise-syntax-error 'pattern "expected identifier" stx))
|
(raise-syntax-error 'pattern "expected identifier" stx))
|
||||||
stx)
|
stx)
|
||||||
|
|
||||||
|
(define (check-string stx)
|
||||||
|
(unless (string? (syntax-e stx))
|
||||||
|
(raise-syntax-error #f "expected string" stx))
|
||||||
|
stx)
|
||||||
|
|
||||||
|
;; nat/f : any -> boolean
|
||||||
|
(define (nat/f x)
|
||||||
|
(or (not x) (exact-nonnegative-integer? x)))
|
||||||
|
|
||||||
|
(define (check-nat/f stx)
|
||||||
|
(let ([d (syntax-e stx)])
|
||||||
|
(unless (nat/f d)
|
||||||
|
(raise-syntax-error #f "expected exact nonnegative integer or #f" stx))
|
||||||
|
stx))
|
||||||
|
|
||||||
|
(define (check-idlist stx)
|
||||||
|
(unless (and (stx-list? stx) (andmap identifier? (stx->list stx)))
|
||||||
|
(raise-syntax-error #f "expected list of identifiers" stx))
|
||||||
|
(stx->list stx))
|
||||||
|
|
||||||
|
|
||||||
|
;; head-local-expand-syntaxes : syntax boolean boolean -> stxs ^ 6
|
||||||
|
;; Setting allow-def-after-expr? allows def/expr interleaving.
|
||||||
|
(define (head-local-expand-and-categorize-syntaxes x allow-def-after-expr?)
|
||||||
|
(define estxs (head-local-expand-syntaxes x allow-def-after-expr?))
|
||||||
|
(define-values (defs vdefs sdefs exprs)
|
||||||
|
(categorize-expanded-syntaxes estxs))
|
||||||
|
(values estxs estxs defs vdefs sdefs exprs))
|
||||||
|
|
||||||
|
(define (categorize-expanded-syntaxes estxs0)
|
||||||
|
(let loop ([estxs estxs0] [defs null] [vdefs null] [sdefs null] [exprs null])
|
||||||
|
(cond [(pair? estxs)
|
||||||
|
(let ([ee (car estxs)])
|
||||||
|
(syntax-case ee (begin define-values define-syntaxes)
|
||||||
|
[(define-values . _)
|
||||||
|
(loop (cdr estxs)
|
||||||
|
(cons ee defs)
|
||||||
|
(cons ee vdefs)
|
||||||
|
sdefs
|
||||||
|
exprs)]
|
||||||
|
[(define-syntaxes (var ...) rhs)
|
||||||
|
(loop (cdr estxs)
|
||||||
|
(cons ee defs)
|
||||||
|
vdefs
|
||||||
|
(cons ee sdefs)
|
||||||
|
exprs)]
|
||||||
|
[_
|
||||||
|
(loop (cdr estxs)
|
||||||
|
defs
|
||||||
|
vdefs
|
||||||
|
sdefs
|
||||||
|
(cons ee exprs))]))]
|
||||||
|
[(null? estxs)
|
||||||
|
(values (reverse defs)
|
||||||
|
(reverse vdefs)
|
||||||
|
(reverse sdefs)
|
||||||
|
(reverse exprs))])))
|
||||||
|
|
||||||
|
;; head-local-expand-syntaxes : syntax boolean -> (listof syntax)
|
||||||
|
(define (head-local-expand-syntaxes x allow-def-after-expr?)
|
||||||
|
(let ([intdef (syntax-local-make-definition-context)]
|
||||||
|
[ctx '(block)])
|
||||||
|
(let loop ([x x] [ex null] [expr? #f])
|
||||||
|
(cond [(stx-pair? x)
|
||||||
|
(let ([ee (local-expand (stx-car x)
|
||||||
|
ctx
|
||||||
|
(kernel-form-identifier-list)
|
||||||
|
intdef)])
|
||||||
|
(syntax-case ee (begin define-values define-syntaxes)
|
||||||
|
[(begin e ...)
|
||||||
|
(loop (append (syntax->list #'(e ...)) (stx-cdr x)) ex expr?)]
|
||||||
|
[(begin . _)
|
||||||
|
(raise-syntax-error #f "bad begin form" ee)]
|
||||||
|
[(define-values (var ...) rhs)
|
||||||
|
(andmap identifier? (syntax->list #'(var ...)))
|
||||||
|
(begin
|
||||||
|
(when (and expr? (not allow-def-after-expr?))
|
||||||
|
(raise-syntax-error #f "definition after expression" ee))
|
||||||
|
(syntax-local-bind-syntaxes (syntax->list #'(var ...)) #f intdef)
|
||||||
|
(loop (stx-cdr x) (cons ee ex) expr?))]
|
||||||
|
[(define-values . _)
|
||||||
|
(raise-syntax-error #f "bad define-values form" ee)]
|
||||||
|
[(define-syntaxes (var ...) rhs)
|
||||||
|
(andmap identifier? (syntax->list #'(var ...)))
|
||||||
|
(begin
|
||||||
|
(when (and expr? (not allow-def-after-expr?))
|
||||||
|
(raise-syntax-error #f "definition after expression" ee))
|
||||||
|
(syntax-local-bind-syntaxes (syntax->list #'(var ...))
|
||||||
|
#'rhs
|
||||||
|
intdef)
|
||||||
|
(loop (stx-cdr x) (cons ee ex) expr?))]
|
||||||
|
[(define-syntaxes . _)
|
||||||
|
(raise-syntax-error #f "bad define-syntaxes form" ee)]
|
||||||
|
[_
|
||||||
|
(loop (stx-cdr x) (cons ee ex) #t)]))]
|
||||||
|
[(stx-null? x)
|
||||||
|
(reverse ex)]))))
|
||||||
|
|
||||||
|
|
||||||
#|
|
#|
|
||||||
;; Mappings
|
;; Mappings
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
@(require scribble/manual
|
@(require scribble/manual
|
||||||
scribble/struct
|
scribble/struct
|
||||||
(for-label stxclass/stxclass))
|
(for-label macro-debugger/stxclass/stxclass))
|
||||||
|
|
||||||
@title{Parsing Syntax and Syntax Classes}
|
@title{Parsing Syntax and Syntax Classes}
|
||||||
|
|
||||||
@defmodule[stxclass/stxclass]
|
@defmodule[macro-debugger/stxclass/stxclass]
|
||||||
|
|
||||||
@section{Parsing Syntax}
|
@section{Parsing Syntax}
|
||||||
@declare-exporting[stxclass/stxclass]
|
@declare-exporting[macro-debugger/stxclass/stxclass]
|
||||||
|
|
||||||
@defform/subs[(syntax-parse stx-expr maybe-literals clause ...)
|
@defform/subs[(syntax-parse stx-expr maybe-literals clause ...)
|
||||||
([maybe-literals code:blank
|
([maybe-literals code:blank
|
||||||
|
@ -222,7 +222,7 @@ generalized sequences. It may not be used as an expression.
|
||||||
}
|
}
|
||||||
|
|
||||||
@section{Syntax Classes}
|
@section{Syntax Classes}
|
||||||
@declare-exporting[stxclass/stxclass]
|
@declare-exporting[macro-debugger/stxclass/stxclass]
|
||||||
|
|
||||||
Syntax classes provide an abstraction mechanism for the specification
|
Syntax classes provide an abstraction mechanism for the specification
|
||||||
of syntax. Basic syntax classes include @scheme[identifier] and
|
of syntax. Basic syntax classes include @scheme[identifier] and
|
||||||
|
@ -239,30 +239,43 @@ syntax. While the values of the attributes depend on the matched
|
||||||
syntax, the set of attributes and each attribute's ellipsis nesting
|
syntax, the set of attributes and each attribute's ellipsis nesting
|
||||||
depth is fixed for each syntax class.
|
depth is fixed for each syntax class.
|
||||||
|
|
||||||
@defform*/subs[#:literals (union pattern)
|
@defform*/subs[#:literals (pattern)
|
||||||
[(define-syntax-class name-id stxclass-body)
|
[(define-syntax-class name-id stxclass-option ...
|
||||||
(define-syntax-class (name-id arg-id ...) stxclass-body)]
|
stxclass-variant ...)
|
||||||
([stxclass-body
|
(define-syntax-class (name-id arg-id ...) stxclass-option ...
|
||||||
(union stxclass-body ...)
|
stxclass-variant ...)]
|
||||||
|
([stxclass-options
|
||||||
|
(code:line #:description string)
|
||||||
|
(code:line #:transparent)]
|
||||||
|
[stxclass-variant
|
||||||
(pattern syntax-pattern pattern-directive ...)])]{
|
(pattern syntax-pattern pattern-directive ...)])]{
|
||||||
|
|
||||||
Defines @scheme[name-id] as a syntax class. When the @scheme[arg-id]s
|
Defines @scheme[name-id] as a syntax class. When the @scheme[arg-id]s
|
||||||
are present, they are bound as variables (not pattern variables) in
|
are present, they are bound as variables (not pattern variables) in
|
||||||
the body.
|
the body.
|
||||||
|
|
||||||
The body of the syntax-class definition specifies the syntax it
|
The body of the syntax-class definition contains one or more variants
|
||||||
accepts and determines the attributes it provides.
|
that specify the syntax it accepts and determines the attributes it
|
||||||
|
provides. The syntax class provides only those attributes which are
|
||||||
|
present in every variant. Each such attribute must be defined with the
|
||||||
|
same ellipsis nesting depth and the same sub-attributes in each
|
||||||
|
component.
|
||||||
|
|
||||||
@specsubform[#:literals (union)
|
@specsubform[(code:line #:description string)]{
|
||||||
(union stxclass-body ...)]{
|
|
||||||
|
|
||||||
Accepts any syntax accepted by one of the component bodies.
|
Specifies a string to use in error messages involving the syntax
|
||||||
|
class. For example, if a term is rejected by the syntax class, an
|
||||||
Provides only those attributes which are present in every component
|
error of the form @scheme["expected <description>"] may be generated.
|
||||||
body. Each such attribute must be defined with the same ellipsis
|
|
||||||
nesting depth and the same sub-attributes in each component.
|
|
||||||
|
|
||||||
|
If absent, the name of the syntax class is used instead.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@specsubform[#:transparent]{
|
||||||
|
|
||||||
|
Indicates that errors may be reported with respect to the internal
|
||||||
|
structure of the syntax class.
|
||||||
|
}
|
||||||
|
|
||||||
@specsubform/subs[#:literals (pattern)
|
@specsubform/subs[#:literals (pattern)
|
||||||
(pattern syntax-pattern pattern-directive ...)
|
(pattern syntax-pattern pattern-directive ...)
|
||||||
([stxclass-pattern-directive
|
([stxclass-pattern-directive
|
||||||
|
@ -320,17 +333,12 @@ match only proper lists:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@deftogether[(
|
@defidform[pattern]{
|
||||||
@defidform[union]
|
|
||||||
@defidform[pattern]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Keywords recognized by @scheme[define-syntax-class]. They may not be
|
|
||||||
used as expressions.
|
|
||||||
|
|
||||||
|
Keyword recognized by @scheme[define-syntax-class]. It may not be
|
||||||
|
used as an expression.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@defform[(define-basic-syntax-class (name-id arg-id ...)
|
@defform[(define-basic-syntax-class (name-id arg-id ...)
|
||||||
([attr-id attr-depth] ...)
|
([attr-id attr-depth] ...)
|
||||||
parser-expr)]{
|
parser-expr)]{
|
||||||
|
@ -390,7 +398,7 @@ the @scheme[arg-expr]s) on the syntax object produced by
|
||||||
|
|
||||||
|
|
||||||
@section{Library syntax classes}
|
@section{Library syntax classes}
|
||||||
@declare-exporting[stxclass/stxclass]
|
@declare-exporting[macro-debugger/stxclass/stxclass]
|
||||||
|
|
||||||
@(define-syntax-rule (defstxclass name . pre-flows)
|
@(define-syntax-rule (defstxclass name . pre-flows)
|
||||||
(defidform name . pre-flows))
|
(defidform name . pre-flows))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user