[plt-scheme] macro writing
--- Ivanyi Peter <pivanyi at freemail.hu> wrote:
>
> > SUGGESTION ONE:
> > Separate the definitions manually. Match on the following
> pattern initially:
> >
> > (syntax-rules ()
> > ((_ n1 (any-names ...) e1 e2 ...)
> > <code here>))
> >
> > And in <code here>, write code to manually search through
> > (syntax (any-names ...)) for the keyword "locals". Then
> > you can construct separate lists or syntax objects for
> > arguments and local definitions.
>
> Hi,
>
> Ok, I have done the following. It works, but I am looking for
> some suggestions how to simplify it? My problem is with the
> get-local-init function. I would like to replace it with a
> map but DrScheme always reports an error that I am supplying
> a syntax and not a list. Any idea how to avoid this problem?
You can "unwrap" a syntax object that contains a list one level with
the syntax->list procedure.
In your case, you can also get what you want automatically in the
template of the macro's main syntax-case. Instead of
(syntax (define (n1 new-args ...)
(let* (new-locals ...)
e1 e2 ...)))
write
(syntax (define (n1 new-args ...)
(let* ([new-local-var #f] ...)
e1 e2 ...)))
> Another question: When I expand it to check I get the
> following error:
>
> > (expand-once (defun a1 () (+ 1 2)))
> define: not allowed in an expression context in:
> (define (a1) (let* () (+ 1 2)))
You forgot to quote or syntax-quote the thing you were expanding. Try
this:
(expand-once #'(defun a1 () (+ 1 2)))
Writing #'X is the same as (syntax X).
> So I get the right expansion, but reports the error.
>
> Thanks for any help,
>
> Peter
>
> P.S: Here is the code. (The per sign (/) separates arguments
> and local variables.)
One last note: your code formatting makes this hard to read and
wastes a lot of space. Keep the closing parenthesis on the same line.
Ryan
---------------------------------------------------------------------------------
>
> (define-syntax defun
> (letrec
> ((get-args
> (lambda (args)
> (syntax-case args (/)
> (() (syntax ()))
> ((/ a1 ...) (syntax ()))
> ((a2 a3 ...) (cons (syntax a2) (get-args (syntax
> (a3 ...)))))
> )
> )
> )
> (get-local-init
> (lambda (args)
> (syntax-case args ()
> (() (syntax ()))
> ((a2 a3 ...) (cons (list (syntax a2) #f)
> (get-local-init (syntax (a3 ...)))))
> ((a1 ...) (list (list (syntax (a1 ...)) #f)))
> )
> )
> )
> (get-locals
> (lambda (args)
> (syntax-case args (/)
> (() (syntax ()))
> ((/ a1 ...) (get-local-init (syntax (a1 ...))))
> ((a2 a3 ...) (get-locals (syntax (a3 ...))))
> )
> )
> )
>
> )
>
> (lambda (x)
> (syntax-case x ()
> ((_ n1 (args ...) e1 e2 ...)
> (with-syntax
> (((new-args ...) (get-args (syntax (args ...)))))
> (with-syntax
> (((new-locals ...) (get-locals (syntax (args
> ...)))))
> (if (null? (syntax (new-locals ...)))
> (syntax (define (n1 new-args ...) e1 e2 ...))
> (syntax (define (n1 new-args ...)
> (let* (new-locals ...)
> e1 e2 ...)))
> )
> )
> )
> )
> )
> )
> )
> )
>
> (defun a1 () (+ 1 2))
> (defun a2 (a) (+ 1 a))
> (defun a3 (a b) (+ a b))
> (defun a4 (a b c) (+ a b c))
> (defun a5 (/) (+ 2 3))
> (defun a6 (/ a) (+ 2 3))
> (defun a7 (/ a b) (+ 2 3))
> (defun a8 (/ a b c) (+ 2 3))
> (defun a9 (a b /) (+ a b))
> (defun aa (a b / c) (+ a b))
> (defun ab (a b / c d) (+ a b))
> (defun ac (a b / c d e) (+ a b))
>
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme