This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

define-syntax and define-simple-class


Hi All,

I'm trying to define a (hygienic) macro which uses define-simple-class,
like this:

;MyMacro.scm
(define-syntax define-op
  (syntax-rules ()
    ((define-op (name args ...) body ...)
     (define-simple-class name (<MySuper>)
      ((execute operands :: <java.lang.Object[]>) :: <java.lang.Object>
       (apply (lambda (args ...) body ...) operands))
      ))))

This is a simplified version of a problem from a real project where I'd
like to use Kawa to make it easier to create such "operator" classes.
MySuper is an abstract class that has an abstract execute method that
matches the signature above.

Example use:

;MyAdd.scm
(define-op (MyAdd a b) (+ a b))

I can compile MyAdd.scm with "kawa -f MyMacro.scm -C MyAdd.scm". The
javap output for the produced class is:

public class MyAdd extends MySuper{
    public java.lang.Object execute(java.lang.Object[]);
    public MyAdd();
    static java.lang.Object lambda1(java.lang.Object, java.lang.Object);
}

I try to use the produced class from a simple test program:

;MyAddTest.scm
(define a (MyAdd:new))
(define operands (<java.lang.Object[]> 1 2))
(display (a:execute operands))(newline)

However, running "kawa -f MyAddTest.scm" I get the error:

java.lang.NoSuchFieldError: lambda$Fn1

I'd guess there is some inconsistency in name mangling for the lambda
function.
Similarly, if I try to name the lambda expression "opfunc" in a let
expression inside the execute method I see "lambda1opfunc" in the javap
output and get a NoSuchFieldError relating to "opfunc$Fn1".

I have also tried to write the define-op macro in a number of other
ways, for example:

;MyMacroPrivate.scm
(define-syntax define-op-with-private
  (syntax-rules ()
    ((define-op-with-private (name args ...) body ...)
     (define-simple-class name (<MySuper>)
      ((opfunc args ...) access: 'private
        body ...)
      ((execute operands :: <java.lang.Object[]>) :: <java.lang.Object>
       (apply opfunc operands))
      ))))

;MyAddPrivate.scm
(define-op (MyAddPrivate a b) (+ a b))

When I try to compile with "kawa -f MyMacroPrivate.scm -C
MyAddPrivate.scm" I get the error:

MyAddPrivate.scm:1:1: missing method name

This seems to be related to
http://sourceware.org/ml/kawa/2003-q1/msg00099.html.

I made the following change:

--- kawa/standard/object.java   (revision 5972)
+++ kawa/standard/object.java   (working copy)
@@ -282,6 +282,8 @@
          { // Method declaration.
            Pair mpair = (Pair) pair_car;
            Object mname = mpair.car;
+          while (mname instanceof SyntaxForm)
+               mname = ((SyntaxForm) mname).form;
            if (! (mname instanceof String)
                && ! (mname instanceof Symbol))
              {

Now when I try to compile with "kawa -f MyMacroPrivate.scm -C
MyAddPrivate.scm" I get:

MyAddPrivate.scm:1:1: warning - simple class requiring lexical link -
use define-class instead
MyAddPrivate.scm:1:1: missing implementation for
MySuper.execute(java.lang.Object[])java.lang.Object mname:execute

Looking at the state in a debugger when this error is generated, it
seems that the execute method from MyAddPrivate class has the name
"execute$1", which might explain this. I haven't gone any further down
this route.

If I explicitly define ((opfunc a b) (+ a b)) I can compile, but I get:

java.lang.VerifyError: (class: MyAddPrivate, method: execute signature:
([Ljava/lang/Object;)Ljava/lang/Object;) Accessing value from
uninitialized register 2

This is probably already too much for one mail! I'd be very grateful for
any help to get this working.

Thanks,

David


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]