From: parumaru
Subject: linj macro generating JAVA setter calls using keys
Date: 
Message-ID: <daf2og$7am$1@news.cs.tu-berlin.de>
Hi,

I'm experimenting with linj and tried to create some macros which shall help
me working with swing and maybe building up a higher abstraction of
swing :)
But unfortunately using macros in linj isn't that easy.
First of all, I wasn't able to create recursive macros :( thus I had to
write functions doing the recursive expansion.
Here are macros /functions I've written:

(defun strip-type (x)
  (values (intern 
            (let* ((name (symbol-name x))
                   (pos (position #\/ name)))
              (if pos
                (subseq name 0 pos)
                name)))))

(defun mkstr (&rest args)
  (with-output-to-string (s)
    (dolist (a args) (princ a s))))

(defun symb (&rest args)
  (values (intern (apply #'mkstr args))))

(defmacro def-util (name &key (pkg 'util))
  `(def-macro ,(symb pkg "." name) (&rest args)
              `(in (the ,',pkg)
                   (,',name ,@args))))

(defmacro export-utils (pkg &rest names)
  `(progn ,@(loop for elem in names
                  collect `(def-util ,elem :pkg ,pkg))))

(defun my-split-if (fn lst)
  (let ((acc ()))
    (do ((src lst (cdr src)))
      ((or (null src) (funcall fn (car src)))
       (values (nreverse acc) src))
      (push (car src) acc))))

(defun group-list (source n)
  (if (endp source)
    '()
    (let ((rest (nthcdr n source)))
      (cons (if (consp rest) (subseq source 0 n) source)
            (group-list rest n)))))

(def-macro with-swing ((&rest args) &body body)
           (build-swing-let args body))

(def-macro setter-call (setter)
           (symb 'set- setter))

(defun build-swing-let (args body)
  (if args
    (let ((component-def (car args))
          (args-rest (cdr args)))
      (if (listp component-def)
        (build-initializing-swing-let component-def 
                                      args-rest 
                                      body)
        `(let (,component-def)
           ,(build-swing-let args-rest body))))
    `(progn ,@body)))

(defun build-initializing-swing-let (component-def args-rest body)
  (multiple-value-bind (constructor keyword-list) (my-split-if #'keywordp 
                                                               (cadr
component-def))
    (let ((setters (mapcar #'(lambda (x)
                               `(send 
                                  ,(car component-def) ;class
                                  (setter-call ,(car x))
                                  ,@(cdr x)))
                           (group-list keyword-list 2)))
          (constructor `(new ',(car constructor) ,@(cdr constructor))))
      `(let ((,(car component-def) ,constructor))
         ,@setters
         ,(build-swing-let args-rest body)))))

The macros and functions are loaded via cmucl using (in-package :linj) (load
"macros.linj"), that's why i used (def-macro ... ) instead of
(defmacro ...), since only macros defined with (def-macro ...)  are
available when linj is trnaslating the file later. 
The Problem is the macro (setter-call ...), which takes a symbol and
prepands 'set-. Thus (setter-call :text) is translated into SET-TEXT.
Now using the macro (with-swing ...) I can write :
(with-swing ((l1 (j-label :text "test"))
             (l2 (j-label :text "test2")))
  (format t "~A~%" l1))

expands into:

(LET ((L1 (new 'j-label)))
  (SEND L1 SET-TEXT "test")
  (LET ((l2 (new 'j-label)))
    (SEND L2 SET-TEXT "test2")
    (PROGN
      (FORMAT T "~A~%" L1))))

But when using (linj2java ...) it yields:
Error in function linj-error:  Couldn't find declaration for set-TEXT

Any suggestion how to solve this problem are very welcome :P
I've just been running out of ideas :(

bye :)
From: Joe Marshall
Subject: Re: linj macro generating JAVA setter calls using keys
Date: 
Message-ID: <8y0klre1.fsf@comcast.net>
parumaru <······@gmx.net> writes:

> The Problem is the macro (setter-call ...), which takes a symbol and
> prepands 'set-. Thus (setter-call :text) is translated into SET-TEXT.

> But when using (linj2java ...) it yields:
> Error in function linj-error:  Couldn't find declaration for set-TEXT

Looks like it might have translated it into set-TEXT rather than
SET-TEXT.  I'm guessing case-sensitivity issues, but it's just a
guess.


-- 
~jrm