[honu] use reified syntax classes to check for literals instead of direct comparisons with free-identifier=?
This commit is contained in:
parent
3bffcae3c2
commit
a38949d8ba
|
@ -6,6 +6,7 @@
|
||||||
(for-syntax racket/base
|
(for-syntax racket/base
|
||||||
"literals.rkt"
|
"literals.rkt"
|
||||||
"parse2.rkt"
|
"parse2.rkt"
|
||||||
|
"util.rkt"
|
||||||
syntax/parse)
|
syntax/parse)
|
||||||
racket/class)
|
racket/class)
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@
|
||||||
(define-splicing-syntax-class honu-class-thing
|
(define-splicing-syntax-class honu-class-thing
|
||||||
#:literals (honu-equal)
|
#:literals (honu-equal)
|
||||||
[pattern method:honu-function
|
[pattern method:honu-function
|
||||||
#:with result (replace-with-public #'method.result)]
|
#:with result (replace-with-public (local-binding method.result))]
|
||||||
[pattern var:honu-declaration
|
[pattern var:honu-declaration
|
||||||
#:with result #'(field [var.name var.expression] ...)]))
|
#:with result #'(field [var.name var.expression] ...)]))
|
||||||
|
|
||||||
|
@ -25,14 +26,14 @@
|
||||||
(define-honu-syntax honu-class
|
(define-honu-syntax honu-class
|
||||||
(lambda (code context)
|
(lambda (code context)
|
||||||
(syntax-parse code #:literal-sets (cruft)
|
(syntax-parse code #:literal-sets (cruft)
|
||||||
[(_ name (#%parens (~var constructor-argument (separate-ids #'honu-comma #'dont-care)))
|
[(_ name (#%parens (~var constructor-argument (separate-ids (literal-syntax-class honu-comma) (literal-syntax-class honu-comma))))
|
||||||
(#%braces method:honu-class-thing ...) . rest)
|
(#%braces method:honu-class-thing ...) . rest)
|
||||||
(define class
|
(define class
|
||||||
#'(%racket (define name (class* object% ()
|
#'(%racket (define name (class* object% ()
|
||||||
(super-new)
|
(super-new)
|
||||||
(init-field constructor-argument.id ...)
|
(init-field constructor-argument.id ...)
|
||||||
method.result ...))))
|
method.result ...))))
|
||||||
(values class #'rest #t)])))
|
(values class (local-binding rest) #t)])))
|
||||||
|
|
||||||
(provide honu-new)
|
(provide honu-new)
|
||||||
(define-honu-syntax honu-new
|
(define-honu-syntax honu-new
|
||||||
|
@ -42,5 +43,5 @@
|
||||||
(define new #'(%racket (make-object name arg.result ...)))
|
(define new #'(%racket (make-object name arg.result ...)))
|
||||||
(values
|
(values
|
||||||
new
|
new
|
||||||
#'rest
|
(local-binding rest)
|
||||||
#f)])))
|
#f)])))
|
||||||
|
|
|
@ -16,7 +16,9 @@
|
||||||
define-literal
|
define-literal
|
||||||
%racket)
|
%racket)
|
||||||
(for-syntax syntax/parse
|
(for-syntax syntax/parse
|
||||||
|
syntax/parse/experimental/reflect
|
||||||
racket/syntax
|
racket/syntax
|
||||||
|
"util.rkt"
|
||||||
"debug.rkt"
|
"debug.rkt"
|
||||||
"literals.rkt"
|
"literals.rkt"
|
||||||
"parse2.rkt"
|
"parse2.rkt"
|
||||||
|
@ -261,16 +263,16 @@
|
||||||
|
|
||||||
(begin-for-syntax
|
(begin-for-syntax
|
||||||
(define-splicing-syntax-class (id-must-be what)
|
(define-splicing-syntax-class (id-must-be what)
|
||||||
[pattern x:id #:when (free-identifier=? #'x what)])
|
[pattern (~reflect x (what))])
|
||||||
(define-splicing-syntax-class (id-except ignores)
|
(define-syntax-class (id-except ignore1 ignore2)
|
||||||
[pattern x:id #:when (not (for/fold ([ok #f])
|
[pattern (~and x:id (~not (~or (~reflect x1 (ignore1))
|
||||||
([ignore ignores])
|
(~reflect x2 (ignore2)))))])
|
||||||
(or ok (free-identifier=? #'x ignore))))])
|
|
||||||
(provide separate-ids)
|
(provide separate-ids)
|
||||||
(define-splicing-syntax-class (separate-ids separator end)
|
(define-splicing-syntax-class (separate-ids separator end)
|
||||||
[pattern (~seq (~var first (id-except (list separator end)))
|
[pattern (~seq (~var first (id-except separator end))
|
||||||
(~seq (~var between (id-must-be separator))
|
(~seq (~var between (id-must-be separator))
|
||||||
(~var next (id-except (list separator end)))) ...)
|
(~var next (id-except separator end))) ...)
|
||||||
#:with (id ...) #'(first.x next.x ...)]))
|
#:with (id ...) #'(first.x next.x ...)]))
|
||||||
|
|
||||||
(begin-for-syntax
|
(begin-for-syntax
|
||||||
|
@ -278,7 +280,8 @@
|
||||||
|
|
||||||
(define-literal-set declaration-literals (honu-comma honu-equal))
|
(define-literal-set declaration-literals (honu-comma honu-equal))
|
||||||
(define-splicing-syntax-class var-id
|
(define-splicing-syntax-class var-id
|
||||||
[pattern x:id #:when (not ((literal-set->predicate declaration-literals) #'x))])
|
[pattern (~var x (id-except (literal-syntax-class honu-comma)
|
||||||
|
(literal-syntax-class honu-equal)))])
|
||||||
|
|
||||||
;; parses a declaration
|
;; parses a declaration
|
||||||
;; var x = 9
|
;; var x = 9
|
||||||
|
@ -286,7 +289,8 @@
|
||||||
(define-splicing-syntax-class honu-declaration
|
(define-splicing-syntax-class honu-declaration
|
||||||
#:literal-sets (cruft)
|
#:literal-sets (cruft)
|
||||||
#:literals (honu-equal honu-var)
|
#:literals (honu-equal honu-var)
|
||||||
[pattern (~seq honu-var (~var variables (separate-ids #'honu-comma #'honu-equal))
|
[pattern (~seq honu-var (~var variables (separate-ids (literal-syntax-class honu-comma)
|
||||||
|
(literal-syntax-class honu-equal)))
|
||||||
honu-equal one:honu-expression)
|
honu-equal one:honu-expression)
|
||||||
#:with (name ...) #'(variables.id ...)
|
#:with (name ...) #'(variables.id ...)
|
||||||
#:with expression #'one.result]))
|
#:with expression #'one.result]))
|
||||||
|
|
|
@ -3,7 +3,12 @@
|
||||||
(provide (except-out (all-defined-out) test-delimiter))
|
(provide (except-out (all-defined-out) test-delimiter))
|
||||||
(require "debug.rkt"
|
(require "debug.rkt"
|
||||||
racket/match
|
racket/match
|
||||||
(for-syntax racket/base)
|
syntax/parse
|
||||||
|
syntax/parse/experimental/reflect
|
||||||
|
(for-syntax racket/base
|
||||||
|
syntax/parse
|
||||||
|
"debug.rkt"
|
||||||
|
)
|
||||||
syntax/stx
|
syntax/stx
|
||||||
racket/list)
|
racket/list)
|
||||||
|
|
||||||
|
@ -94,3 +99,32 @@
|
||||||
[match-variable (extract-variable #'pattern)])
|
[match-variable (extract-variable #'pattern)])
|
||||||
#'(match expression
|
#'(match expression
|
||||||
[match-pattern match-variable]))]))
|
[match-pattern match-variable]))]))
|
||||||
|
|
||||||
|
;; local-binding and module-binding check that the identifier is bound at the given phase
|
||||||
|
(define-syntax (local-binding stx)
|
||||||
|
(syntax-parse stx
|
||||||
|
[(_ name)
|
||||||
|
(define type (identifier-binding #'name))
|
||||||
|
(when (not (eq? type 'lexical))
|
||||||
|
(raise-syntax-error 'local-binding "not bound locally" #'name))
|
||||||
|
#'#'name]))
|
||||||
|
|
||||||
|
(define-syntax (module-binding stx)
|
||||||
|
(syntax-parse stx
|
||||||
|
[(_ name level)
|
||||||
|
(define type (identifier-binding #'name (syntax-e #'level)))
|
||||||
|
(when (not (and (list? type)
|
||||||
|
(= (length type) 7)))
|
||||||
|
(raise-syntax-error 'module-binding
|
||||||
|
(format "not bound by a module at phase ~a" (syntax-e #'level))
|
||||||
|
#'name))
|
||||||
|
#'#'name]))
|
||||||
|
|
||||||
|
(define-syntax-rule (literal-syntax-class literal)
|
||||||
|
(let ()
|
||||||
|
(define-literal-set set (literal))
|
||||||
|
(define-syntax-class class
|
||||||
|
#:literal-sets (set)
|
||||||
|
;; BUG! shouldn't need ~literal here since we are using literal sets
|
||||||
|
[pattern (~literal literal)])
|
||||||
|
(reify-syntax-class class)))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user