implement honu-syntax

This commit is contained in:
jon 2010-05-05 15:56:51 -06:00 committed by Jon Rafkind
parent 99e6eb5e9d
commit 2f5593a104
6 changed files with 164 additions and 27 deletions

View File

@ -6,6 +6,7 @@
;; "private/honu.ss" ;; "private/honu.ss"
"private/parse.ss" "private/parse.ss"
"private/literals.ss" "private/literals.ss"
"private/syntax.ss"
"private/macro.ss") "private/macro.ss")
(define test-x-class (define test-x-class
@ -30,6 +31,7 @@
) )
#%datum #%datum
#%braces #%braces
#%parens
x x
true true
false false
@ -37,11 +39,13 @@
display2 display2
newline newline
else else
foobar2000
(rename-out (rename-out
(honu-if if) (honu-if if)
(honu-provide provide) (honu-provide provide)
(honu-macro-item macroItem) (honu-macro-item macroItem)
(honu-macro macro) (honu-macro macro)
(honu-syntax syntax)
)) ))
#; #;

View File

@ -269,8 +269,9 @@
(lambda (transformer) (lambda (transformer)
(let-values ([(code rest) (transformer body context)]) (let-values ([(code rest) (transformer body context)])
(combine-k code rest)))] (combine-k code rest)))]
[else (call-values parse-one (extract-until body (list #'\; [else (call-values (extract-until body (list #'\;
)))])) ))
parse-one )]))
#| #|
(define-honu-macro (e ... * e ... \;)) (define-honu-macro (e ... * e ... \;))
@ -295,13 +296,6 @@ x(2)
) )
(define-syntax (define-honu-syntax stx)
(let-values ([(id rhs) (normalize-definition stx #'lambda #f)])
(with-syntax ([id id]
[rhs rhs])
#'(define-syntax id (make-honu-transformer rhs)))))
#| #|
Yes, check out head patterns and splicing syntax classes. Yes, check out head patterns and splicing syntax classes.
@ -320,6 +314,14 @@ Then, in the pattern above for 'if', 'then' would be bound to the following synt
|# |#
(define-syntax (define-honu-syntax stx)
(let-values ([(id rhs) (normalize-definition stx #'lambda #f)])
(with-syntax ([id id]
[rhs rhs])
(syntax/loc stx
(define-syntax id (make-honu-transformer rhs))))))
(define-honu-syntax honu-provide (define-honu-syntax honu-provide
(lambda (stx ctx) (lambda (stx ctx)
(syntax-parse stx (syntax-parse stx
@ -328,6 +330,8 @@ Then, in the pattern above for 'if', 'then' would be bound to the following synt
(values #'(provide something) (values #'(provide something)
#'rest)]))) #'rest)])))
;; (honu-syntax ...)
(define-honu-syntax honu-macro-item (define-honu-syntax honu-macro-item
(lambda (stx ctx) (lambda (stx ctx)
(syntax-parse stx (syntax-parse stx
@ -465,11 +469,18 @@ if (foo){
(define-syntax (honu-top stx) (define-syntax (honu-top stx)
(raise-syntax-error #f "interactive use is not yet supported")) (raise-syntax-error #f "interactive use is not yet supported"))
(define-syntax (foobar2000 stx)
(printf "Called foobar2000 on ~a\n" (syntax->datum stx))
(syntax-case stx ()
[(_ x y ...) #'(printf "foobar2000 ~a\n" x)]))
(define (display2 x y) (define (display2 x y)
(printf "~a ~a" x y)) (printf "~a ~a" x y))
(define-syntax (honu-unparsed-begin stx) (define-syntax (honu-unparsed-begin stx)
;; (printf "honu unparsed begin: ~a\n" (syntax->datum stx)) (printf "honu unparsed begin: ~a\n" (syntax->datum stx))
(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
@ -479,7 +490,8 @@ if (foo){
;; (printf "Rest is ~a\n" (syntax->datum rest)) ;; (printf "Rest is ~a\n" (syntax->datum rest))
(with-syntax ([code code] (with-syntax ([code code]
[(rest ...) rest]) [(rest ...) rest])
#'(begin code (honu-unparsed-begin rest ...))))] (syntax/loc stx
(begin code (honu-unparsed-begin rest ...)))))]
#; #;
[(_ . body) (let-values ([(code rest) (parse-block-one the-top-block-context [(_ . body) (let-values ([(code rest) (parse-block-one the-top-block-context
#'body #'body
@ -490,9 +502,17 @@ if (foo){
[(rest ...) rest]) [(rest ...) rest])
#'(begin code (honu-unparsed-begin rest ...))))])) #'(begin code (honu-unparsed-begin rest ...))))]))
#;
(define-syntax-rule (#%dynamic-honu-module-begin forms ...) (define-syntax-rule (#%dynamic-honu-module-begin forms ...)
#; #;
(#%module-begin-typed-scheme (#%module-begin-typed-scheme
;; (require honu/private/typed-utils) ;; (require honu/private/typed-utils)
(honu-unparsed-begin forms ...)) (honu-unparsed-begin forms ...))
(#%plain-module-begin (honu-unparsed-begin forms ...))) (#%plain-module-begin (honu-unparsed-begin forms ...)))
(define-syntax (#%dynamic-honu-module-begin stx)
(syntax-case stx ()
[(_ forms ...)
(begin
(printf "Module begin ~a\n" (syntax->datum #'(forms ...)))
#'(#%plain-module-begin (honu-unparsed-begin forms ...)))]))

View File

@ -16,4 +16,4 @@
honu-= honu-+= honu--= honu-*= honu-/= honu-%= honu-= honu-+= honu--= honu-*= honu-/= honu-%=
honu-&= honu-^= honu-\|= honu-<<= honu->>= honu->>>= honu-&= honu-^= honu-\|= honu-<<= honu->>= honu->>>=
honu->> honu-<< honu->>> honu-< honu-> honu-<= honu->= honu->> honu-<< honu->>> honu-< honu-> honu-<= honu->=
honu-? honu-: honu-comma honu-. #%braces) honu-? honu-: honu-comma honu-. #%braces #%parens)

View File

@ -1,6 +1,9 @@
#lang scheme/base #lang scheme/base
(require "honu-typed-scheme.ss" (require "honu-typed-scheme.ss"
"literals.ss"
"parse.ss"
"syntax.ss"
(for-syntax "debug.ss" (for-syntax "debug.ss"
"contexts.ss" "contexts.ss"
scheme/base scheme/base
@ -11,6 +14,17 @@
(provide honu-macro) (provide honu-macro)
(define-syntax (ensure-defined stx)
(syntax-case stx ()
[(_ id ...)
(begin
(for-each (lambda (id)
(syntax-local-value id (lambda () (raise-syntax-error 'syntax-id "not defined" id))))
(syntax->list #'(id ...)))
#'(void))]))
(ensure-defined #%parens #%braces)
(define-for-syntax (extract-conventions pattern) (define-for-syntax (extract-conventions pattern)
(let loop ([out '()] (let loop ([out '()]
[in pattern]) [in pattern])
@ -26,9 +40,6 @@
(loop out #'(rest1 rest ...))] (loop out #'(rest1 rest ...))]
[(foo) out]))) [(foo) out])))
(define-syntax (semicolon stx)
stx)
(define-for-syntax (extract-patterns pattern) (define-for-syntax (extract-patterns pattern)
(let loop ([out '()] (let loop ([out '()]
[in pattern]) [in pattern])
@ -311,7 +322,8 @@
(syntax-case stx () (syntax-case stx ()
[(_ x ...) (do-it #'(x ...))])) [(_ x ...) (do-it #'(x ...))]))
;; (provide unpull) (provide (for-syntax unpull))
#; #;
(define-honu-syntax unpull (define-honu-syntax unpull
(lambda (stx ctx) (lambda (stx ctx)
@ -355,6 +367,23 @@
'pattern))] 'pattern))]
)))])) )))]))
#;
(define-syntax (honu-unparsed-expr stx)
(define (fix stx)
(printf "Fix ~a\n" (syntax->datum stx))
(syntax-parse stx #:literals (honu-syntax #%parens)
[(honu-syntax (#%parens x ...) y ...)
(with-syntax ([(y* ...) (fix #'(y ...))])
#'(x ... y* ...))]
[(z x ...)
(with-syntax ([z* (fix #'z)]
[(x* ...) (fix #'(x ...))])
#'(z* x* ...))]
[else stx]
))
(printf "unparsed expr ~a\n" stx)
(fix (stx-cdr stx)))
(define-syntax (test2 stx) (define-syntax (test2 stx)
(syntax-case stx () (syntax-case stx ()
[(_ x ...) [(_ x ...)
@ -383,7 +412,8 @@
(syntax->list #'(pattern ...)))] (syntax->list #'(pattern ...)))]
) )
(values (values
#'(define-honu-syntax name (syntax/loc stx
(define-honu-syntax name
(lambda (stx ctx) (lambda (stx ctx)
;; (define-literal-set literals (honu-literal ...)) ;; (define-literal-set literals (honu-literal ...))
(syntax-parse stx (syntax-parse stx
@ -397,16 +427,18 @@
(cond (cond
[(type-context? ctx) (X)] [(type-context? ctx) (X)]
[(type-or-expression-context? ctx) (X)] [(type-or-expression-context? ctx) (X)]
[(expression-context? ctx) #'(honu-unparsed-expr out (... ...))] [(expression-context? ctx) (syntax/loc stx (honu-unparsed-expr (out (... ...))))]
[(expression-block-context? ctx) [(expression-block-context? ctx)
#'(honu-unparsed-begin out (... ...))] (syntax/loc stx
(honu-unparsed-begin out (... ...)))]
[(block-context? ctx) [(block-context? ctx)
#'(honu-unparsed-begin out (... ...))] (syntax/loc stx
(honu-unparsed-begin out (... ...)))]
[(variable-definition-context? ctx) (X)] [(variable-definition-context? ctx) (X)]
[(constant-definition-context? ctx) (X)] [(constant-definition-context? ctx) (X)]
[(function-definition-context? ctx) (X)] [(function-definition-context? ctx) (X)]
[(prototype-context? ctx) (X)] [(prototype-context? ctx) (X)]
[else #'(honu-unparsed-expr out (... ...))]) [else (syntax/loc stx (out (... ...)))])
#; #;
#'(honu-unparsed-begin out (... ...)) #'(honu-unparsed-begin out (... ...))
#'rrest) #'rrest)
@ -422,9 +454,22 @@
#f obj 'obj #f ctx #f obj 'obj #f ctx
out (... ...) rrest) out (... ...) rrest)
#; #;
#'rrest))]))) #'rrest))]))))
#'rest))] #'rest))]
[else (raise-syntax-error 'honu-macro "fail!")] [(_ (m x ...)
(z y ...)
#;
(#%braces (#%braces name pattern ...))
. rest)
(begin
(printf "Got literals ~a\n" #'(x ...))
(printf "M is ~a, = to #%parens is ~a\n" #'m (free-identifier=? #'#%parens #'m))
(printf "Z is ~a, = to #%braces is ~a\n" #'z (free-identifier=? #'#%braces #'z))
(printf "Rest is ~a\n" (syntax->datum #'rest))
#;
(printf "Got name ~a pattern ~a\n" #'name #'(pattern ...))
(raise-syntax-error 'honu-macro "f1" stx))]
[else (raise-syntax-error 'honu-macro "fail" stx)]
))) )))
;; (my-syntax guz (_ display (#%parens x ...)) (+ x ...)) ;; (my-syntax guz (_ display (#%parens x ...)) (+ x ...))

View File

@ -3,11 +3,14 @@
(require "contexts.ss" (require "contexts.ss"
"util.ss" "util.ss"
(for-template "literals.ss" (for-template "literals.ss"
"language.ss") "language.ss"
"syntax.ss")
syntax/parse syntax/parse
syntax/parse/experimental/splicing syntax/parse/experimental/splicing
(for-syntax syntax/parse) (for-syntax syntax/parse)
scheme/splicing scheme/splicing
(for-syntax syntax/define)
syntax/name
syntax/stx syntax/stx
(for-syntax "util.ss") (for-syntax "util.ss")
(for-template scheme/base)) (for-template scheme/base))
@ -40,8 +43,14 @@
#:attrs (result) #:attrs (result)
#:description "honu-expr" #:description "honu-expr"
(lambda (stx fail) (lambda (stx fail)
(printf "Honu expr ~a\n" stx)
(cond (cond
[(stx-null? stx) (fail)] [(stx-null? stx) (fail)]
[(syntax-parse stx #:literals (honu-syntax)
[(honu-syntax expr ...) #'(expr ...)]
[else #f]) => (lambda (exprs)
(printf "Ignoring honu-syntax 1!\n")
(list exprs 0 #''()))]
[(get-transformer stx) => (lambda (transformer) [(get-transformer stx) => (lambda (transformer)
(printf "Transforming honu macro ~a\n" (car stx)) (printf "Transforming honu macro ~a\n" (car stx))
(let-values ([(used rest) (let-values ([(used rest)
@ -55,8 +64,14 @@
#:attributes (result) #:attributes (result)
#:description "honu-expr" #:description "honu-expr"
(lambda (stx fail) (lambda (stx fail)
(printf "Honu expr ~a\n" stx)
(cond (cond
[(stx-null? stx) (fail)] [(stx-null? stx) (fail)]
[(syntax-parse stx #:literals (honu-syntax)
[(honu-syntax expr ...) #'(expr ...)]
[else #f]) => (lambda (exprs)
(printf "Ignoring honu-syntax 2!\n")
(list '() 0 exprs))]
[(get-transformer stx) => (lambda (transformer) [(get-transformer stx) => (lambda (transformer)
(printf "Transforming honu macro ~a\n" (car stx)) (printf "Transforming honu macro ~a\n" (car stx))
(let-values ([(used rest) (let-values ([(used rest)
@ -96,6 +111,7 @@
(define-splicing-syntax-class (do-rest context left) (define-splicing-syntax-class (do-rest context left)
(pattern (~seq (~var op operator-class) (pattern (~seq (~var op operator-class)
(~var right (next context)) (~var right (next context))
(~var new-right (do-rest context ((attribute op.func) left #'right.result)))) (~var new-right (do-rest context ((attribute op.func) left #'right.result))))
#:with result (attribute new-right.result)) #:with result (attribute new-right.result))
(pattern (~seq) #:with result left)) (pattern (~seq) #:with result left))
@ -203,6 +219,26 @@
#:with result #'e.result]) #:with result #'e.result])
(define (fix-output stx)
#|
(printf "Fix output ~a\n" stx)
(when (and (stx-pair? stx) (equal? 'syntax (syntax->datum (stx-car stx))))
(printf "syntax == honu-syntax? ~a\n" (free-identifier=? (stx-car stx) #'honu-syntax)))
|#
(syntax-parse stx #:literals (honu-syntax #%parens syntax)
[((honu-syntax (#%parens x ...) y ...) rest ...)
(with-syntax ([(y* ...) (fix-output #'(y ... rest ...))])
(syntax/loc stx
(x ... y* ...)))]
;; dont touch real syntax
[(syntax stuff ...) stx]
[(z x ...)
(with-syntax ([z* (fix-output #'z)]
[(x* ...) (fix-output #'(x ...))])
(syntax/loc stx
(z* x* ...)))]
[else stx]))
(define (parse-block-one/2 stx context) (define (parse-block-one/2 stx context)
(define (parse-one stx context) (define (parse-one stx context)
@ -213,10 +249,30 @@
#; #;
[(x:number . rest) (values #'x #'rest)] [(x:number . rest) (values #'x #'rest)]
)) ))
(printf "Parsing ~a\n" stx)
(cond (cond
[(stx-null? stx) (values stx '())] [(stx-null? stx) (values stx '())]
[(get-transformer stx) => (lambda (transformer) [(get-transformer stx) => (lambda (transformer)
(transformer stx context))] (printf "Parse one: execute transformer ~a\n" transformer)
#;
(printf "output of transformer is ~a\n" (let-values ([(a b) (transformer stx context)]) (list a b)))
(call-values (transformer stx context)
(lambda (reparse rest)
(printf "Transformer gave us ~a\n" reparse)
#;
(values reparse rest)
#;
(values (fix-output reparse) rest)
#;
(printf "Macroized ~a and ~a\n" reparse rest)
(syntax-parse (fix-output reparse) #:literals (honu-unparsed-expr)
[(honu-unparsed-expr stuff ...)
(let-values ([(out rest2)
(with-syntax ([(more ...) rest])
(parse-block-one/2 #'(stuff ... more ...) context))])
(values out rest2))]
[else (values reparse rest)]))
))]
[else (parse-one stx context)])) [else (parse-one stx context)]))
(define-values (prop:honu-transformer honu-transformer? honu-transformer-ref) (define-values (prop:honu-transformer honu-transformer? honu-transformer-ref)
@ -230,7 +286,6 @@
(and (positive? (string-length str)) (and (positive? (string-length str))
(memq (string-ref str 0) sym-chars))))))) (memq (string-ref str 0) sym-chars)))))))
(define-values (struct:honu-trans make-honu-trans honu-trans? honu-trans-ref honu-trans-set!) (define-values (struct:honu-trans make-honu-trans honu-trans? honu-trans-ref honu-trans-set!)
(make-struct-type 'honu-trans #f 1 0 #f (make-struct-type 'honu-trans #f 1 0 #f
(list (list prop:honu-transformer #t)) (list (list prop:honu-transformer #t))
@ -246,6 +301,8 @@
(make-honu-trans proc)) (make-honu-trans proc))
;; returns a transformer or #f ;; 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
@ -283,3 +340,14 @@
;; (printf "~a bound transformer? ~a\n" stx (bound-transformer stx)) ;; (printf "~a bound transformer? ~a\n" stx (bound-transformer stx))
(or (bound-transformer stx) (or (bound-transformer stx)
(special-transformer stx))) (special-transformer stx)))
#;
(define-honu-syntax honu-syntax
(lambda (stx ctx)
(syntax-case stx ()
[(_ expr ...)
(begin
(printf "Honu syntax on ~a\n" #'(expr ...))
(raise-syntax-error 'honu-syntax "should have been handled already")
#;
(parse-block-one/2 #'(expr ...) the-expression-context))])))

View File

@ -33,7 +33,7 @@
(loop (stx-cdr r) (cons (stx-car r) val-stxs))]))] (loop (stx-cdr r) (cons (stx-car r) val-stxs))]))]
[(r ids) (extract-until r ids #f)])) [(r ids) (extract-until r ids #f)]))
(define-syntax-rule (call-values function values-producing) (define-syntax-rule (call-values values-producing function)
(call-with-values (lambda () values-producing) function)) (call-with-values (lambda () values-producing) function))
;; shortcut for treating arguments as syntax objects ;; shortcut for treating arguments as syntax objects