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] |
> One idea is to rewrite > > (lambda (&optional (var init-form supplied-p)) > body) > > to > > (lambda (#!optional (tmp-var <unbound-marker>)) > (let ((var (if (eq tmp-var <unbound-marker) > init-form > tmp-var))) > body)) > > where <unbound-marker> is some special value that the user can usually > not create, e.g. some of those in gnu.expr.Special. I got the writeExternal stuff working a while ago, then ran into another cross-language bug that took me ages to find. The problem was that with DEFMACRO being defined in Scheme, and using a Scheme instantiated Lambda, it wasn't recognising &optional as the symbol I'd expect, instead it was just binding COMMON-LISP:&OPTIONAL as an ordinary var. Given that my entry point was wondering why DEFPACKAGE was throwing very strange "Syntax transform threw blah blah blah" it took me a day or so to notice that until DEFMACRO is moved in the CL ecosystem, with a more friendly Lambda, we'll have to use the Scheme #! syntax in macro lambda lists... I got a chance to do the transformation tonight, I have it working, using an algorithm that generalises fairly easy to multiple LL keywords, but wanted to check that the approach is sane (this is currently just for &optional). Bascially I have this: #|kawa:1|# ((lambda (x &optional (y 2 ysupp)) (list x y ysupp t)) 1 2) (Lambda/2/fl:0 line:1:10 (x/3/fl:40040(ignorable) #!optional (GS.2/6/fl:40040(ignorable) (Quote #!undefined))) (Let#3 (({COMMON-LISP}:YSUPP/7/fl:40(ignorable) = (If (Apply (Quote #<procedure eq?>) (Ref/2/Declaration[GS.2/6]) (Quote #!undefined)) (Quote ()) (Quote t)))) (Let#4 (({COMMON-LISP}:Y/5/fl:40040(ignorable) = (If (Apply (Quote #<procedure eq?>) (Ref/3/{COMMON-LISP}:YSUPP/Declaration[{COMMON-LISP}:YSUPP/7]) (Quote t)) (Ref/4/Declaration[GS.2/6]) (Quote 2)))) (Apply line:1:36 (Ref/10/Declaration[applyToArgs/2]) (Ref/6/list) (Ref/7/Declaration[x/3]) (Ref/8/{COMMON-LISP}:Y/Declaration[{COMMON-LISP}:Y/5]) (Ref/9/{COMMON-LISP}:YSUPP/Declaration[{COMMON-LISP}:YSUPP/7]) (Quote t)))))] (1 2 t t) ; you get (1 2 () t) if you don't supply an argument too The implementation is attached - that file is generally a bit of a mess, and the implementation of the above has some obvious initialisation/destruction errors. The rewriteAuxiallary method is called from Lambda#rewriteBody (line 586) where the default is to just call Translator#rewrite_body. This is the approach in english: 1) Scan the form looking for a supplied-p argument. If not found, carry on as normal (currently two unnecessary LETs are created, easy fix). Other wise, populate the next four entries of the rewriteHelper array with the given variable, a default value, a supplied-p declaration and a temporary declaration. This data structure is used to generate the abstract syntax in #rewriteAuxillary 2) Create two LETs. The outer let holds all the supplied-p vars, the inner let holds all the given variables which use the outer supplied-p's to get their values. There might be some weird ANSI issues, since IIUC, the supplied-p forms are allowed to assume supplied-p forms appearing before them have been bound. Kind regards, Charles.
Attachment:
OrdinaryLambda.java
Description: Binary data
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |