macro-stepper:
do compile-time evals when expanding fixes: (begin macro-def macro-use) pattern updated tests for lifts change svn: r16762
This commit is contained in:
parent
0d6da8957a
commit
32e38ca0e4
|
@ -170,3 +170,9 @@
|
|||
;; (make-p:require-for-template <Base>)
|
||||
;; (make-p:provide <Base>)
|
||||
;; #f
|
||||
|
||||
|
||||
;; ECTE represents expand/compile-time-evals
|
||||
;; (make-ecte stx ?stx Deriv Deriv)
|
||||
|
||||
(define-struct (ecte deriv) (first second) #:transparent)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#lang scheme/base
|
||||
(require (for-syntax scheme/base)
|
||||
syntax/stx
|
||||
"yacc-ext.ss"
|
||||
"yacc-interrupted.ss"
|
||||
"deriv.ss"
|
||||
|
@ -38,7 +39,7 @@
|
|||
(src-pos)
|
||||
(tokens basic-tokens prim-tokens renames-tokens)
|
||||
(end EOF)
|
||||
#;(debug "/tmp/ryan/DEBUG-PARSER.txt")
|
||||
#|(debug "/tmp/ryan/DEBUG-PARSER.txt")|#
|
||||
(error deriv-error))
|
||||
|
||||
;; tokens
|
||||
|
@ -60,16 +61,47 @@
|
|||
rename-one
|
||||
rename-list
|
||||
tag
|
||||
IMPOSSIBLE)
|
||||
IMPOSSIBLE
|
||||
start
|
||||
top-non-begin)
|
||||
|
||||
;; Entry point
|
||||
(productions
|
||||
(Expansion
|
||||
[(start EE/Lifts) $2]
|
||||
[(start EE/Lifts/Interrupted) $2]))
|
||||
[(start EE/Lifts/Interrupted) $2]
|
||||
[(start ExpandCTE) $2]
|
||||
[(start ExpandCTE/Interrupted) $2]))
|
||||
|
||||
(productions/I
|
||||
|
||||
(ExpandCTE
|
||||
[(visit start (? CheckImmediateMacro/Lifts) top-non-begin start (? EE) return)
|
||||
(make ecte $1 $7 $3 $6)]
|
||||
[(visit start CheckImmediateMacro/Lifts top-begin (? NextExpandCTEs) return)
|
||||
(begin
|
||||
(unless (list? $5)
|
||||
(error "NextExpandCTEs returned non-list ~s" $5))
|
||||
(make ecte $1 $6 $3
|
||||
(make p:begin $4 $6 (list (stx-car $4)) #f
|
||||
(make lderiv (cdr (stx->list $4))
|
||||
(and $6 (cdr (stx->list $6)))
|
||||
#f
|
||||
$5))))])
|
||||
|
||||
(CheckImmediateMacro/Lifts
|
||||
[((? CheckImmediateMacro))
|
||||
$1]
|
||||
[(CheckImmediateMacro lift-loop)
|
||||
(let ([e1 (wderiv-e1 $1)]
|
||||
[e2 $2])
|
||||
(make lift-deriv e1 e2 $1 $2 (make p:stop $2 $2 null #f)))])
|
||||
|
||||
(NextExpandCTEs
|
||||
(#:skipped null)
|
||||
[() null]
|
||||
[(next (? ExpandCTE) (? NextExpandCTEs)) (cons $2 $3)])
|
||||
|
||||
;; Expand with possible lifting
|
||||
(EE/Lifts
|
||||
[((? EE)) $1]
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
rename-list ; (list-of syntax)
|
||||
|
||||
IMPOSSIBLE ; useful for error-handling clauses that have no NoError counterpart
|
||||
|
||||
top-begin ; identifier
|
||||
top-non-begin ; .
|
||||
))
|
||||
|
||||
(define-tokens renames-tokens
|
||||
|
@ -160,6 +163,14 @@
|
|||
(149 . prim-varref)
|
||||
(150 . ,token-lift-require)
|
||||
(151 . ,token-lift-provide)
|
||||
|
||||
;; Emitted from Scheme
|
||||
(start . ,token-start)
|
||||
(visit . ,token-visit)
|
||||
(return . ,token-return)
|
||||
(next . ,token-next)
|
||||
(top-begin . ,token-top-begin)
|
||||
(top-non-begin . ,token-top-non-begin)
|
||||
))
|
||||
|
||||
(define (tokenize sig-n val pos)
|
||||
|
|
|
@ -271,6 +271,15 @@
|
|||
(error 'reductions "unknown tagged syntax: ~s" tagged-stx)))]
|
||||
[Expr ?form next])]
|
||||
|
||||
;; expand/compile-time-evals
|
||||
|
||||
[(Wrap ecte (e1 e2 first second))
|
||||
(R [#:pattern ?form]
|
||||
[#:pass1]
|
||||
[Expr ?form first]
|
||||
[#:pass2]
|
||||
[Expr ?form second])]
|
||||
|
||||
;; Lifts
|
||||
|
||||
[(Wrap lift-deriv (e1 e2 first lifted-stx second))
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
trace-verbose?
|
||||
events->token-generator
|
||||
current-expand-observe
|
||||
expand/compile-time-evals
|
||||
|
||||
trace-macro-limit
|
||||
trace-limit-handler)
|
||||
|
@ -22,18 +23,18 @@
|
|||
(define trace-verbose? (make-parameter #f))
|
||||
|
||||
;; trace : stx -> Deriv
|
||||
(define (trace stx)
|
||||
(let-values ([(result events derivp) (trace* stx expand)])
|
||||
(define (trace stx [expander expand/compile-time-evals])
|
||||
(let-values ([(result events derivp) (trace* stx expander)])
|
||||
(force derivp)))
|
||||
|
||||
;; trace/result : stx -> stx/exn Deriv
|
||||
(define (trace/result stx)
|
||||
(let-values ([(result events derivp) (trace* stx expand)])
|
||||
(define (trace/result stx [expander expand/compile-time-evals])
|
||||
(let-values ([(result events derivp) (trace* stx expander)])
|
||||
(values result
|
||||
(force derivp))))
|
||||
|
||||
;; trace* : stx (stx -> stx) -> stx/exn (list-of event) (promise-of Deriv)
|
||||
(define (trace* stx expander)
|
||||
(define (trace* stx [expander expand/compile-time-evals])
|
||||
(let-values ([(result events) (expand/events stx expander)])
|
||||
(values result
|
||||
events
|
||||
|
@ -70,7 +71,7 @@
|
|||
(if (and limit handler (exact-positive-integer? limit))
|
||||
(lambda (x y)
|
||||
(add! x y)
|
||||
(when (= x 8) ;; enter-macro
|
||||
(when (eqv? x 8) ;; enter-macro
|
||||
(set! counter (add1 counter))
|
||||
(when (= counter limit)
|
||||
(set! limit (handler counter)))))
|
||||
|
@ -85,3 +86,67 @@
|
|||
(add! 'EOF #f)
|
||||
(values result
|
||||
(reverse events)))))
|
||||
|
||||
|
||||
(require syntax/stx
|
||||
syntax/kerncase)
|
||||
|
||||
(define (emit sig [val #f])
|
||||
((current-expand-observe) sig val))
|
||||
|
||||
(define (expand/compile-time-evals stx)
|
||||
(define (expand/cte stx)
|
||||
(define _ (emit 'visit stx))
|
||||
(define e1 (expand-syntax-to-top-form stx))
|
||||
(define e2
|
||||
(syntax-case e1 (begin)
|
||||
[(begin expr ...)
|
||||
(begin
|
||||
(emit 'top-begin e1)
|
||||
(with-syntax ([(expr ...)
|
||||
;;left-to-right part of this map is important:
|
||||
(map (lambda (e)
|
||||
(emit 'next)
|
||||
(expand/cte e))
|
||||
(syntax->list #'(expr ...)))]
|
||||
[beg (stx-car e1)])
|
||||
(datum->syntax e1 (syntax-e (syntax (beg expr ...))) e1 e1)))]
|
||||
[else
|
||||
(begin
|
||||
(emit 'top-non-begin)
|
||||
(let ([e (expand-syntax e1)])
|
||||
(parameterize ((current-expand-observe void))
|
||||
(eval-compile-time-part e))
|
||||
e))]))
|
||||
(emit 'return e2)
|
||||
e2)
|
||||
(emit 'start)
|
||||
(expand/cte (namespace-syntax-introduce (datum->syntax #f stx))))
|
||||
|
||||
;; eval-compile-time-part : syntax boolean -> void
|
||||
;; compiles the syntax it receives as an argument and evaluates the compile-time part of it.
|
||||
;; pre: there are no top-level begins in stx.
|
||||
(define (eval-compile-time-part stx)
|
||||
(define (eval/compile stx)
|
||||
(eval (compile-syntax stx)))
|
||||
(kernel-syntax-case stx #f
|
||||
[(#%require req ...)
|
||||
(for ([req (syntax->list #'(req ...))])
|
||||
(namespace-require/expansion-time (syntax->datum req)))]
|
||||
[(module . _)
|
||||
(eval/compile stx)]
|
||||
[(define-syntaxes . _)
|
||||
(eval/compile stx)]
|
||||
[(define-values-for-syntax . _)
|
||||
(eval/compile stx)]
|
||||
[(define-values (id ...) . _)
|
||||
(with-syntax ([defvals (stx-car stx)]
|
||||
[undefined (letrec ([x x]) x)])
|
||||
(for ([id (syntax->list #'(id ...))])
|
||||
(with-syntax ([id id])
|
||||
(eval/compile #'(defvals (id) undefined)))))
|
||||
;; Following doesn't work (namespace mismatch)
|
||||
;; (eval/compile #'(define-values (id ...) (let ([id #f] ...) (values id ...))))
|
||||
]
|
||||
[_else
|
||||
(void)]))
|
||||
|
|
|
@ -244,7 +244,7 @@
|
|||
(parameterize ((trace-macro-limit (pref:macro-step-limit))
|
||||
(trace-limit-handler
|
||||
(lambda (c) (handle-macro-limit c))))
|
||||
(trace* expr expand)))
|
||||
(trace* expr)))
|
||||
|
||||
(define/private (handle-macro-limit c)
|
||||
(define option
|
||||
|
|
|
@ -427,10 +427,15 @@
|
|||
(define/private (adjust-deriv/lift deriv)
|
||||
(match deriv
|
||||
[(Wrap lift-deriv (e1 e2 first lifted-stx second))
|
||||
(let ([first (adjust-deriv/top first)])
|
||||
(let ([first (adjust-deriv/lift first)])
|
||||
(and first
|
||||
(let ([e1 (wderiv-e1 first)])
|
||||
(make-lift-deriv e1 e2 first lifted-stx second))))]
|
||||
[(Wrap ecte (e1 e2 first second))
|
||||
(let ([first (adjust-deriv/lift first)])
|
||||
(and first
|
||||
(let ([e1 (wderiv-e1 first)])
|
||||
(make ecte e1 e2 first second))))]
|
||||
[else (adjust-deriv/top deriv)]))
|
||||
|
||||
;; adjust-deriv/top : Derivation -> Derivation
|
||||
|
@ -442,18 +447,10 @@
|
|||
;; It's not original...
|
||||
;; Strip out mzscheme's top-interactions
|
||||
;; Keep anything that is a non-mzscheme top-interaction
|
||||
;; Drop everything else (not original program)
|
||||
(cond [(not (mrule? deriv)) #f]
|
||||
[(for/or ([x (base-resolves deriv)]) (top-interaction-kw? x))
|
||||
(cond [(for/or ([x (base-resolves deriv)]) (top-interaction-kw? x))
|
||||
;; Just mzscheme's top-interaction; strip it out
|
||||
(adjust-deriv/top (mrule-next deriv))]
|
||||
[(equal? (map syntax-e (base-resolves deriv))
|
||||
'(#%top-interaction))
|
||||
;; A *different* top interaction; keep it
|
||||
deriv]
|
||||
[else
|
||||
;; Not original and not tagged with top-interaction
|
||||
#f])))
|
||||
[else deriv])))
|
||||
|
||||
(define/public (top-interaction-kw? x)
|
||||
(or (free-identifier=? x #'#%top-interaction)
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
(provide trace/ns
|
||||
trace/t
|
||||
trace/k
|
||||
|
||||
testing-namespace
|
||||
|
||||
hide-all-policy
|
||||
hide-none-policy
|
||||
|
||||
|
@ -24,9 +27,12 @@
|
|||
(define (trace/k expr)
|
||||
(trace/ns expr #t))
|
||||
|
||||
;; Use just 'expand', not 'expand/compile-time-evals',
|
||||
;; for test backward compatibility
|
||||
;; FIXME: add tests that use 'expand/compile-time-evals'
|
||||
(define (trace/ns expr kernel?)
|
||||
(parameterize ((current-namespace (choose-namespace kernel?)))
|
||||
(trace expr)))
|
||||
(trace expr expand)))
|
||||
|
||||
(define (choose-namespace kernel?)
|
||||
(if kernel? kernel-namespace testing-namespace))
|
||||
|
|
|
@ -188,4 +188,19 @@
|
|||
(trace `(module m mzscheme
|
||||
(require ',freshname)
|
||||
(meval (+ 1 2)))))))
|
||||
|
||||
(test-case "macro def within begin"
|
||||
(let ([rs (reductions
|
||||
(trace '(begin
|
||||
(define-syntax-rule (m x e)
|
||||
(define x e))
|
||||
(m y 12))))])
|
||||
(check-pred list? rs)
|
||||
(check-false (ormap misstep? rs))
|
||||
(check-true (for/or ([step rs])
|
||||
(equal? (syntax->datum (state-e (protostep-s1 step)))
|
||||
'(m y 12))
|
||||
(equal? (syntax->datum (state-e (step-s2 step)))
|
||||
'(define y 12)))
|
||||
"looking for m => define")))
|
||||
))
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
(test "lift"
|
||||
(lift 'a)
|
||||
[#:steps (local-lift #rx"^lifted" (lift 'a))
|
||||
[#:steps (local-lift (#rx"^lifted") (lift 'a))
|
||||
(macro (#%expression #rx"^lifted"))
|
||||
(tag-top (#%expression (#%top . #rx"^lifted")))
|
||||
(capture-lifts (begin (define-values (#rx"^lifted") 'a)
|
||||
|
@ -53,7 +53,7 @@
|
|||
#:no-hidden-steps)
|
||||
(test "lift with id"
|
||||
(lift (id 'a))
|
||||
[#:steps (local-lift #rx"^lifted" (lift (id 'a)))
|
||||
[#:steps (local-lift (#rx"^lifted") (lift (id 'a)))
|
||||
(macro (#%expression #rx"^lifted"))
|
||||
(tag-top (#%expression (#%top . #rx"^lifted")))
|
||||
(capture-lifts (begin (define-values (#rx"^lifted") (id 'a))
|
||||
|
@ -64,7 +64,7 @@
|
|||
|
||||
(test "lift with Tid"
|
||||
(lift (Tid 'a))
|
||||
[#:steps (local-lift #rx"^lifted" (lift (Tid 'a)))
|
||||
[#:steps (local-lift (#rx"^lifted") (lift (Tid 'a)))
|
||||
(macro (#%expression #rx"^lifted"))
|
||||
(tag-top (#%expression (#%top . #rx"^lifted")))
|
||||
(capture-lifts (begin (define-values (#rx"^lifted") (Tid 'a))
|
||||
|
@ -76,40 +76,40 @@
|
|||
|
||||
(test "Tlift"
|
||||
(Tlift 'a)
|
||||
[#:steps (local-lift #rx"^lifted" (Tlift 'a))
|
||||
[#:steps (local-lift (#rx"^lifted") (Tlift 'a))
|
||||
(macro (#%expression #rx"^lifted"))
|
||||
(tag-top (#%expression (#%top . #rx"^lifted")))
|
||||
(capture-lifts (begin (define-values (#rx"^lifted") 'a)
|
||||
(#%expression (#%top . #rx"^lifted"))))]
|
||||
[#:hidden-steps (local-lift #rx"^lifted" (Tlift 'a))
|
||||
[#:hidden-steps (local-lift (#rx"^lifted") (Tlift 'a))
|
||||
(macro (#%expression #rx"^lifted"))
|
||||
(capture-lifts (begin (define-values (#rx"^lifted") 'a)
|
||||
(#%expression #rx"^lifted")))])
|
||||
|
||||
(test "Tlift with id"
|
||||
(Tlift (id 'a))
|
||||
[#:steps (local-lift #rx"^lifted" (Tlift (id 'a)))
|
||||
[#:steps (local-lift (#rx"^lifted") (Tlift (id 'a)))
|
||||
(macro (#%expression #rx"^lifted"))
|
||||
(tag-top (#%expression (#%top . #rx"^lifted")))
|
||||
(capture-lifts (begin (define-values (#rx"^lifted") (id 'a))
|
||||
(#%expression (#%top . #rx"^lifted"))))
|
||||
(macro (begin (define-values (#rx"^lifted") 'a)
|
||||
(#%expression (#%top . #rx"^lifted"))))]
|
||||
[#:hidden-steps (local-lift #rx"^lifted" (Tlift (id 'a)))
|
||||
[#:hidden-steps (local-lift (#rx"^lifted") (Tlift (id 'a)))
|
||||
(macro (#%expression #rx"^lifted"))
|
||||
(capture-lifts (begin (define-values (#rx"^lifted") (id 'a))
|
||||
(#%expression #rx"^lifted")))])
|
||||
|
||||
(test "Tlift with Tid"
|
||||
(Tlift (Tid 'a))
|
||||
[#:steps (local-lift #rx"^lifted" (Tlift (Tid 'a)))
|
||||
[#:steps (local-lift (#rx"^lifted") (Tlift (Tid 'a)))
|
||||
(macro (#%expression #rx"^lifted"))
|
||||
(tag-top (#%expression (#%top . #rx"^lifted")))
|
||||
(capture-lifts (begin (define-values (#rx"^lifted") (Tid 'a))
|
||||
(#%expression (#%top . #rx"^lifted"))))
|
||||
(macro (begin (define-values (#rx"^lifted") 'a)
|
||||
(#%expression (#%top . #rx"^lifted"))))]
|
||||
[#:steps (local-lift #rx"^lifted" (Tlift (Tid 'a)))
|
||||
[#:steps (local-lift (#rx"^lifted") (Tlift (Tid 'a)))
|
||||
(macro (#%expression #rx"^lifted"))
|
||||
(capture-lifts (begin (define-values (#rx"^lifted") (Tid 'a))
|
||||
(#%expression #rx"^lifted")))
|
||||
|
|
Loading…
Reference in New Issue
Block a user