#lang scheme/base (require "sc.ss" "../util.ss" syntax/stx syntax/kerncase scheme/struct-info scheme/contract/private/helpers (for-syntax scheme/base syntax/kerncase "rep.ss" (only-in "rep-data.ss" make-literalset)) (for-template scheme/base scheme/contract/base)) (provide identifier boolean str character keyword number integer exact-integer exact-nonnegative-integer exact-positive-integer id nat char expr expr/c static atom-in-list kernel-literals) (define-syntax-rule (define-pred-stxclass name pred) (define-syntax-class name #:attributes () #:opaque (pattern x #:fail-unless (pred (syntax-e #'x)) #f))) (define-pred-stxclass identifier symbol?) (define-pred-stxclass boolean boolean?) (define-pred-stxclass str string?) (define-pred-stxclass character char?) (define-pred-stxclass keyword keyword?) (define-pred-stxclass number number?) (define-pred-stxclass integer integer?) (define-pred-stxclass exact-integer exact-integer?) (define-pred-stxclass exact-nonnegative-integer exact-nonnegative-integer?) (define-pred-stxclass exact-positive-integer exact-positive-integer?) ;; Aliases (define-syntax id (make-rename-transformer #'identifier)) (define-syntax nat (make-rename-transformer #'exact-nonnegative-integer)) (define-syntax char (make-rename-transformer #'character)) (define notfound (box 'notfound)) (define-syntax-class (static pred name) #:attributes (value) #:description name (pattern x:id #:fail-unless (syntax-transforming?) "not within the extent of a macro transformer" #:attr value (syntax-local-value #'x (lambda () notfound)) #:fail-when (eq? (attribute value) notfound) #f #:fail-unless (pred (attribute value)) #f)) (define-syntax-class (atom-in-list atoms name) #:attributes () #:description name (pattern x #:fail-unless (memv (syntax-e #'x) atoms) #f)) (define-syntax-class struct-name #:description "struct name" #:attributes (descriptor constructor predicate [accessor 1] super complete?) (pattern s #:declare s (static struct-info? "struct name") #:with info (extract-struct-info (attribute s.value)) #:with descriptor (list-ref (attribute info) 0) #:with constructor (list-ref (attribute info) 1) #:with predicate (list-ref (attribute info) 2) #:with r-accessors (reverse (list-ref (attribute info) 3)) #:with (accessor ...) (datum->syntax #f (let ([r-accessors (attribute r-accessors)]) (if (and (pair? r-accessors) (eq? #f (car r-accessors))) (cdr r-accessors) r-accessors))) #:with super (list-ref (attribute info) 5) #:attr complete? (or (null? (attribute r-accessors)) (and (pair? (attribute r-accessors)) (not (eq? #f (car (attribute r-accessors)))))))) (define-syntax-class expr #:attributes () (pattern x #:fail-when (keyword? (syntax-e #'x)) #f)) (define-syntax-class (expr/c ctc) #:attributes (c) (pattern x:expr #:with c #`(contract #,ctc x (quote #,(string->symbol (or (build-src-loc-string #'x) ""))) (quote #,(or ')) (quote-syntax #,(syntax/loc #'x ()))))) ;; Literal sets (define-syntax kernel-literals (make-literalset (list* (quote-syntax module) (quote-syntax #%plain-module-begin) (quote-syntax #%require) (quote-syntax #%provide) (for/list ([id (kernel-form-identifier-list)]) (list (syntax-e id) id)))))