use new syntax-parse primitive to enable macro invocation during expression parsing
svn: r17891
This commit is contained in:
parent
68c197d02f
commit
f980cf9462
|
@ -1,6 +1,7 @@
|
||||||
#lang scheme/base
|
#lang scheme/base
|
||||||
|
|
||||||
(require "private/honu-typed-scheme.ss"
|
(require "private/honu-typed-scheme.ss"
|
||||||
|
;; "private/honu.ss"
|
||||||
"private/macro.ss")
|
"private/macro.ss")
|
||||||
|
|
||||||
(provide (rename-out (#%dynamic-honu-module-begin #%module-begin)
|
(provide (rename-out (#%dynamic-honu-module-begin #%module-begin)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
syntax/name
|
syntax/name
|
||||||
syntax/define
|
syntax/define
|
||||||
syntax/parse
|
syntax/parse
|
||||||
|
syntax/parse/experimental
|
||||||
scheme/splicing
|
scheme/splicing
|
||||||
"contexts.ss"
|
"contexts.ss"
|
||||||
"util.ss"
|
"util.ss"
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
(and (positive? (string-length str))
|
(and (positive? (string-length str))
|
||||||
(memq (string-ref str 0) sym-chars)))))))
|
(memq (string-ref str 0) sym-chars)))))))
|
||||||
|
|
||||||
|
;; returns a transformer or #f
|
||||||
(define (get-transformer stx)
|
(define (get-transformer stx)
|
||||||
;; if its an identifier and bound to a transformer return it
|
;; if its an identifier and bound to a transformer return it
|
||||||
(define (bound-transformer stx)
|
(define (bound-transformer stx)
|
||||||
|
@ -366,16 +368,46 @@ x(2)
|
||||||
[pattern (type:id name:id (#%parens args ...) body:block . rest)
|
[pattern (type:id name:id (#%parens args ...) body:block . rest)
|
||||||
#:with result #'(define (name args ...)
|
#:with result #'(define (name args ...)
|
||||||
body.result)])
|
body.result)])
|
||||||
(define-syntax-class expr
|
|
||||||
[pattern f])
|
(define (syntax-object-position mstart end)
|
||||||
|
(if (stx-null? end)
|
||||||
|
(length (syntax->list mstart))
|
||||||
|
(let loop ([start mstart]
|
||||||
|
[count 0])
|
||||||
|
;; (printf "Checking ~a vs ~a\n" start end)
|
||||||
|
(cond
|
||||||
|
[(stx-null? start) (raise-syntax-error 'honu-macro "the `rest' syntax returned by a honu macro did not return objects at the same syntactic nesting level as the head of the pattern. this is probably because it returned syntax from some inner nesting level such as (if (x + 1 2) more-stuff) where `rest' was (+ 1 2) instead of `more-stuff'" end mstart)]
|
||||||
|
[(eq? (stx-car start) (stx-car end)) count]
|
||||||
|
;; [(equal? start end) count]
|
||||||
|
[else (loop (stx-cdr start) (add1 count))]))))
|
||||||
|
|
||||||
|
(define-primitive-splicing-syntax-class (expr)
|
||||||
|
#:attrs (result)
|
||||||
|
#:description "expr"
|
||||||
|
(lambda (stx fail)
|
||||||
|
(cond
|
||||||
|
[(stx-null? stx) (fail)]
|
||||||
|
[(get-transformer stx) => (lambda (transformer)
|
||||||
|
(let-values ([(used rest)
|
||||||
|
(transformer stx context)])
|
||||||
|
(list rest (syntax-object-position stx rest)
|
||||||
|
used)))]
|
||||||
|
|
||||||
|
[else (syntax-case stx ()
|
||||||
|
[(f . rest) (list #'rest 1 #'f)])])))
|
||||||
|
|
||||||
|
#;
|
||||||
|
(define-splicing-syntax-class expr
|
||||||
|
[pattern (~seq f ...) #:with result])
|
||||||
|
|
||||||
(define-splicing-syntax-class call
|
(define-splicing-syntax-class call
|
||||||
#:literals (honu-comma)
|
#:literals (honu-comma)
|
||||||
[pattern (~seq e:expr (#%parens (~seq arg:ternary (~optional honu-comma)) ...))
|
[pattern (~seq e:expr (#%parens (~seq arg:ternary (~optional honu-comma)) ...))
|
||||||
#:with call #'(e arg.result ...)])
|
#:with call #'(e.result arg.result ...)])
|
||||||
(define-splicing-syntax-class expression-last
|
(define-splicing-syntax-class expression-last
|
||||||
[pattern (~seq call:call) #:with result #'call.call]
|
[pattern (~seq call:call) #:with result #'call.call]
|
||||||
[pattern (~seq x:number) #:with result #'x]
|
[pattern (~seq x:number) #:with result #'x]
|
||||||
|
[pattern (~seq e:expr) #:with result #'e.result]
|
||||||
)
|
)
|
||||||
|
|
||||||
(define-syntax-rule (define-infix-operator name next [operator reducer] ...)
|
(define-syntax-rule (define-infix-operator name next [operator reducer] ...)
|
||||||
|
@ -524,7 +556,7 @@ Then, in the pattern above for 'if', 'then' would be bound to the following synt
|
||||||
(lambda (stx ctx)
|
(lambda (stx ctx)
|
||||||
(define (parse-complete-block stx)
|
(define (parse-complete-block stx)
|
||||||
;; (printf "Parsing complete block ~a\n" (syntax->datum stx))
|
;; (printf "Parsing complete block ~a\n" (syntax->datum stx))
|
||||||
(with-syntax ([(exprs ...) (parse-block stx ctx)])
|
(with-syntax ([(exprs ...) (parse-block stx the-expression-block-context)])
|
||||||
#'(begin exprs ...))
|
#'(begin exprs ...))
|
||||||
#;
|
#;
|
||||||
(let-values ([(a b)
|
(let-values ([(a b)
|
||||||
|
@ -556,7 +588,7 @@ Then, in the pattern above for 'if', 'then' would be bound to the following synt
|
||||||
[(_ condition:paren-expr on-true:block else on-false:block . rest)
|
[(_ condition:paren-expr on-true:block else on-false:block . rest)
|
||||||
;; (printf "used if with else\n")
|
;; (printf "used if with else\n")
|
||||||
(let ([result #'(if condition.expr on-true.line on-false.line)])
|
(let ([result #'(if condition.expr on-true.line on-false.line)])
|
||||||
(expression-result ctx result #'rest))]
|
(expression-result ctx result (syntax/loc #'rest rest)))]
|
||||||
[(_ condition:paren-expr on-true:block . rest)
|
[(_ condition:paren-expr on-true:block . rest)
|
||||||
;; (printf "used if with no else\n")
|
;; (printf "used if with no else\n")
|
||||||
(let ([result #'(when condition.expr on-true.line)])
|
(let ([result #'(when condition.expr on-true.line)])
|
||||||
|
@ -656,6 +688,8 @@ if (foo){
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_) #'(begin (void))]
|
[(_) #'(begin (void))]
|
||||||
[(_ . body) (let-values ([(code rest) (parse-block-one/2 #'body
|
[(_ . body) (let-values ([(code rest) (parse-block-one/2 #'body
|
||||||
|
the-expression-context
|
||||||
|
#;
|
||||||
the-top-block-context)])
|
the-top-block-context)])
|
||||||
;; (printf "Rest is ~a\n" (syntax->datum rest))
|
;; (printf "Rest is ~a\n" (syntax->datum rest))
|
||||||
(with-syntax ([code code]
|
(with-syntax ([code code]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user