pull/2/head
Matthew Butterick 8 years ago
parent 4c46f9849f
commit 4847adf7e9

@ -1,8 +1,7 @@
#lang racket/base #lang racket/base
(require (require
racket/function racket/function
(for-syntax racket/list (for-syntax racket/base
racket/base
syntax/parse syntax/parse
br/syntax br/syntax
racket/syntax racket/syntax
@ -36,7 +35,7 @@
(for*/list ([pat-arg (in-list (syntax-flatten pats))] (for*/list ([pat-arg (in-list (syntax-flatten pats))]
[pat-datum (in-value (syntax->datum pat-arg))] [pat-datum (in-value (syntax->datum pat-arg))]
#:when (and (symbol? pat-datum) #:when (and (symbol? pat-datum)
(not (member pat-datum '(... _ else))) ; exempted from literality (not (member pat-datum '(... _))) ; exempted from literality
(not (string-prefix? (symbol->string pat-datum) pattern-arg-prefixer)) (not (string-prefix? (symbol->string pat-datum) pattern-arg-prefixer))
(not (upcased? (symbol->string pat-datum))))) (not (upcased? (symbol->string pat-datum)))))
pat-arg))) pat-arg)))

@ -2,41 +2,15 @@
(require racket/struct (for-syntax br/datum)) (require racket/struct (for-syntax br/datum))
(provide define-datatype cases occurs-free?) (provide define-datatype cases occurs-free?)
#;(begin (define-macro (define-datatype BASE-TYPE _base-type-predicate?
(struct lc-exp () #:transparent) (SUBTYPE [FIELD FIELD-PREDICATE?] ...) ...)
(struct var-exp lc-exp (var) #:transparent
#:guard (λ(var name)
(unless (symbol? var)
(error name (format "arg ~a not ~a" var 'symbol?)))
(values var)))
(struct lambda-exp lc-exp (bound-var body) #:transparent
#:guard (λ(bound-var body name)
(unless (symbol? bound-var)
(error name (format "arg ~a not ~a" bound-var 'symbol?)))
(unless (lc-exp? body)
(error name (format "arg ~a not ~a" body 'lc-exp?)))
(values bound-var body)))
(struct app-exp lc-exp (rator rand) #:transparent
#:guard (λ(rator rand name)
(unless (lc-exp? rator)
(error name (format "arg ~a not ~a" rator 'lc-exp?)))
(unless (lc-exp? rand)
(error name (format "arg ~a not ~a" rand 'lc-exp?)))
(values rator rand))))
(define #'(define-datatype _base-type _base-type-predicate?
(_subtype [_field _field-predicate?] ...) ...)
#'(begin #'(begin
(struct _base-type () #:transparent #:mutable) (struct BASE-TYPE () #:transparent #:mutable)
(struct _subtype _base-type (_field ...) #:transparent #:mutable (struct SUBTYPE BASE-TYPE (FIELD ...) #:transparent #:mutable
#:guard (λ(_field ... name) #:guard (λ(FIELD ... name)
(unless (_field-predicate? _field) (unless (FIELD-PREDICATE? FIELD)
(error name (format "arg ~a is not ~a" _field '_field-predicate?))) ... (error name (format "arg ~a is not ~a" FIELD 'FIELD-PREDICATE?))) ...
(values _field ...))) ...)) (values FIELD ...))) ...))
(define-datatype lc-exp lc-exp? (define-datatype lc-exp lc-exp?
@ -45,35 +19,36 @@
(app-exp [rator lc-exp?] [rand lc-exp?])) (app-exp [rator lc-exp?] [rand lc-exp?]))
#;(define (occurs-free? search-var exp) #;(define-syntax (cases stx)
(cond (syntax-case stx (else)
[(var-exp? exp) (let ([var (var-exp-var exp)]) [(_ _base-type INPUT-VAR
(eqv? var search-var))] [SUBTYPE (POSITIONAL-VAR ...) . _body] ...
[(lambda-exp? exp) (let ([bound-var (lambda-exp-bound-var exp)] [else . _else-body])
[body (lambda-exp-body exp)]) (inject-syntax ([#'(_subtype? ...) (suffix-id #'(SUBTYPE ...) "?")])
(and (not (eqv? search-var bound-var)) #'(cond
(occurs-free? search-var body)))] [(_subtype? INPUT-VAR) (match-let ([(list POSITIONAL-VAR ...) (struct->list INPUT-VAR)])
[(app-exp? exp) (let ([rator (app-exp-rator exp)] . _body)] ...
[rand (app-exp-rand exp)]) [else . _else-body]))]
(or [(_ _base-type INPUT-VAR
(occurs-free? search-var rator) SUBTYPE-CASE ...)
(occurs-free? search-var rand)))])) #'(cases _base-type INPUT-VAR
SUBTYPE-CASE ...
[else (void)])]))
(define-syntax (cases stx) (define-macro-cases cases
(syntax-case stx (else) [(_ BASE-TYPE INPUT-VAR
[(_ _base-type _input-var [SUBTYPE (POSITIONAL-VAR ...) . BODY] ...
[_subtype (_positional-var ...) . _body] ... [else . ELSE-BODY])
[else . _else-body]) (with-syntax ([(SUBTYPE? ...) (suffix-id #'(SUBTYPE ...) "?")])
(inject-syntax ([#'(_subtype? ...) (suffix-id #'(_subtype ...) "?")]) #'(cond
#'(cond [(SUBTYPE? INPUT-VAR) (match-let ([(list POSITIONAL-VAR ...) (struct->list INPUT-VAR)])
[(_subtype? _input-var) (match-let ([(list _positional-var ...) (struct->list _input-var)]) . BODY)] ...
. _body)] ... [else . ELSE-BODY]))]
[else . _else-body]))] [(_ BASE-TYPE INPUT-VAR
[(_ _base-type _input-var SUBTYPE-CASE ...)
_subtype-case ...) #'(cases BASE-TYPE INPUT-VAR
#'(cases _base-type _input-var SUBTYPE-CASE ...
_subtype-case ... [else (void)])])
[else (void)])]))
(define (occurs-free? search-var exp) (define (occurs-free? search-var exp)

@ -139,9 +139,10 @@
(define (syntax-flatten stx) (define (syntax-flatten stx)
(flatten (flatten
(let loop ([stx stx]) (let loop ([stx stx])
(define maybe-list (syntax->list stx)) (define maybe-pair (let ([e-stx (syntax-e stx)])
(if maybe-list (and (pair? e-stx) (flatten e-stx))))
(map loop maybe-list) (if maybe-pair
(map loop maybe-pair)
stx)))) stx))))
(define-syntax-rule (begin-label LABEL . EXPRS) (define-syntax-rule (begin-label LABEL . EXPRS)

Loading…
Cancel
Save