Ok, here is a first attempt:

(define to-last
  (lambda (lst)
    (let next ((l lst))
      (cond
        ((null? l) '())
        ((null? (cdr l)) l)
        (else
          (next (cdr l)))))))

(define-macro (push! stack val)
  (let ((gval (gensym)))
    `(let ((,gval ,val))
       (set! ,stack (cons ,gval ,stack))
       ,gval)))

(define-macro (bconc! #!rest rst)
  (let ((gr (gensym)) (gb (gensym)))
    `(let loop ((,gr (list ,@rst)) 
                (,gb (if (null? *b-end*) *b-head* *b-end*)))
       (cond
         ((null? ,gr) 
           (set! *b-end* ,gb) 
           (if (or (null? ,gb) (eq? ,gb *b-head*)) ,gb (cdr ,gb)))
         ((null? ,gb) 
           (set! ,gb (car ,gr))
           (set! *b-head* ,gb)
           (loop (cdr ,gr) ,gb))
         (else
           (set! ,gb (to-last ,gb))
           (set-cdr! ,gb (car ,gr))
           (loop (cdr ,gr) ,gb))))))
                      
(define-macro (blink! e)
  (let ((ge (gensym)))
    `(let ((,ge ,e))
       (bconc! (list ,ge))
       ,ge))) 

(define-macro (bpush! e)
  `(push! *b-head* ,e))

(define-macro (bbuilt! #!optional lst)
  (let ((gl (gensym)))
    `(let ((,gl ,lst))
       (if (list? ,gl)
           (begin
             (set! *b-head* ,gl)
             (set! *b-end* ,gl)
             ,gl)
           *b-head*))))
       
(define-macro (build-list! #!rest body)
  `(let ((*b-head* '()) (*b-end* '()))
     (begin ,@body)
     *b-head*))

and here is a silly test:

(build-list! 
  (blink! -2 )
  (bpush! -1) 
  (display (bbuilt!)) 
  (display (bconc! '(1 2 3))) 
  (display (bpush! 0)) 
  (display (bbuilt!'(a b)))  
  (display (bconc! '(4 5 6) '(7 8 9))) 
  (blink! 10))


Ok I have changed the original names, as make makes you think about compiling and push and conc are clearer (in my opinion). Because the code cannot escape assignments (set!, etc.), I have chosen to keep the same destructive concatenation. Nevertheless, the blink! and bpush! macros allow to create new cons cells (and maybe they should loose their !)


Of course, *b-head* *b-end* should not be used. But this is what I would like to solve.


****************************************


About using threads. If I started a thread with an infinite quantum, after a call to (thread-yield!), would it run again with the same infinite quantum or the default value?


Thanks,


Denis

From: denis.prog@hotmail.com
To: gambit-list@iro.umontreal.ca
Date: Fri, 9 May 2014 12:49:20 -0400
Subject: [gambit-list] macros sharing variables?

Hello,

My first goal is to get in gambit something similar to the make, chain, link yoke instructions in PicoLisp. This has nothing to do with makefiles, it is about building lists. See : 

http://software-lab.de/doc/refM.html#make
http://picolisp.com/5000/!wiki?home

I have found this of interest because it often makes the code shorter and cleaner.

So the basic idea would be to write macros that would shamelessly use the same captured variables, with all the associated troubles.

I have been thinking of writing something like (define macro-var (gensym)), but I am afraid of some troubles if the files is included more than once. 

I believe (as this is actually programming with coroutines), it could be done with two threads and parameters : one thread would run the code and the chain, link function would send lists or elements to the other thread that would concatenate all them at the end.

What are you thinking about all this?

Thanks,

Denis 

_______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list