This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: Problem with macro expansion
On Nov 25, 2009, at 12:37 PM, Per Bothner wrote:
On 11/25/2009 03:38 AM, Colin Fleming wrote:
(token open-vector "#(")
(define-syntax token
(syntax-rules () ((_ name desc)
(define-constant name :: IElement (Element:new
desc)))))
The (define-constant open-vector :: IElement (Element:new "#(")) is
what I'd like to make a macro out of, which should result in being
able to use the form (token open-vector "#(").
In the REPL this works, but when I try to compile the class, I get
the error:
(compiling Tokens.scm to scheme.Tokens)
Tokens.scm:9:1: define-constant is only allowed in a<body>
The error message is confusing, but the problem appears to be
because you have a macro usage before the macro application.
In general that doesn't work, especially in this case where the
macro expands into a definition.
I encountered a similar problem, where something works in the REPL but
fails during compilation, attempting to use:
(define-syntax (import-class fqcn)
(syntax-case fqcn ()
((import-class fqcn)
(let* ((cls :: java.lang.Class (eval (syntax fqcn)))
(name :: string (java.lang.Class:getSimpleName cls)))
#`(define-alias ,name ,cls)))))
which is intended to approximate the effect of a Java import.
(import-class java.awt.event.ActionEvent) expands to
(define-alias ActionEvent java.awt.event.ActionEvent)
so that from then on I can use the class's simple name.
In the REPL:
#|kawa:15|# (import-class java.awt.event.ActionEvent)
#|kawa:16|# ActionEvent
class java.awt.event.ActionEvent
During compilation, even if the define-syntax comes before any usage
in the file:
[kawa] java.lang.NullPointerException
[kawa] at gnu.expr.ReferenceExp.apply(ReferenceExp.java:155)
[kawa] at gnu.mapping.CallContext.runUntilDone(CallContext.java:
251)
[kawa] at
gnu.mapping.CallContext.getFromContext(CallContext.java:280)
[kawa] at gnu.expr.Expression.eval(Expression.java:26)
[kawa] at gnu.expr.ApplyExp.apply(ApplyExp.java:63)
[kawa] at gnu.mapping.CallContext.runUntilDone(CallContext.java:
251)
[kawa] at
gnu.mapping.CallContext.getFromContext(CallContext.java:280)
[kawa] at gnu.expr.Expression.eval(Expression.java:26)
[kawa] at gnu.expr.LetExp.apply(LetExp.java:52)
[kawa] at gnu.expr.LetExp.apply(LetExp.java:64)
[kawa] at gnu.expr.LetExp.apply(LetExp.java:64)
[kawa] at gnu.expr.IfExp.apply(IfExp.java:34)
[kawa] at gnu.mapping.CallContext.runUntilDone(CallContext.java:
251)
[kawa] at
gnu.mapping.CallContext.getFromContext(CallContext.java:280)
[kawa] at gnu.expr.Expression.eval(Expression.java:26)
[kawa] at gnu.expr.BlockExp.apply(BlockExp.java:50)
[kawa] at gnu.expr.LetExp.apply(LetExp.java:64)
[kawa] at gnu.expr.Closure.apply(LambdaExp.java:2111)
[kawa] at gnu.mapping.CallContext.runUntilDone(CallContext.java:
251)
[kawa] at
gnu.mapping.CallContext.runUntilValue(CallContext.java:315)
[kawa] at gnu.mapping.MethodProc.applyN(MethodProc.java:105)
[kawa] at gnu.mapping.ProcedureN.apply1(ProcedureN.java:31)
[kawa] at kawa.lang.Macro.expand(Macro.java:178)
[kawa] at kawa.lang.Macro.scanForm(Macro.java:206)
[kawa] at kawa.lang.Translator.scanForm(Translator.java:1054)
[kawa] at
gnu.kawa.lispexpr.LispLanguage.parse(LispLanguage.java:69)
[kawa] at gnu.expr.Language.parse(Language.java:503)
[kawa] at gnu.expr.Language.parse(Language.java:467)
[kawa] at kawa.repl.compileFiles(repl.java:763)
[kawa] at kawa.repl.processArgs(repl.java:457)
[kawa] at kawa.repl.main(repl.java:866)
[kawa] (compiling foo.scm)
[kawa] foo.scm:15:1: evaluating syntax transformer 'import-
class' threw java.lang.NullPointerException
The top of foo.scm has some comments and then the macro definition and
then, on line 15,
(import-class java.awt.event.ActionEvent).
I think I did see the "only allowed in a body" message when I had the
macro definition further down in the file.
-Jamie
--
Jamison Hope
The PTR Group
www.theptrgroup.com