From: Kenny Tilton
Subject: tagbody mystery
Date: 
Message-ID: <FZoyf.579$yE4.141@news-wrt-01.rdc-nyc.rr.com>
Here is my Lisp version of a C "for":

(defmacro c-for ((init test post) &body body)
   (let ((iterate (gensym))
         (continue (gensym)))
     (declare (ignorable continue))
     `(macrolet ((c-continue () `(go ,',continue)))
        (block nil
          ,init
          (tagbody
            ,iterate
            (when (not ,test)
              (return))
            ,@body
            (c-continue) ;; ick
            ,continue
            ,post
            (go ,iterate))))))

If the user does not code (c-continue), I get an "unreferenced tag" 
warning from AllegroCL. Homey don't play warnings.

I tried a declare-ignorable on the tag as the first form in the tagbody, 
but CL don't play that.

No choice but the bogus forced go-continue?

kt

From: Geoffrey Summerhayes
Subject: Re: tagbody mystery
Date: 
Message-ID: <HNqyf.28$924.789@news20.bellglobal.com>
"Kenny Tilton" <·············@nyc.rr.com> wrote in message ······················@news-wrt-01.rdc-nyc.rr.com...
> Here is my Lisp version of a C "for":
>
> (defmacro c-for ((init test post) &body body)
>   (let ((iterate (gensym))
>         (continue (gensym)))
>     (declare (ignorable continue))
>     `(macrolet ((c-continue () `(go ,',continue)))
>        (block nil
>          ,init
>          (tagbody
>            ,iterate
>            (when (not ,test)
>              (return))
>            ,@body
>            (c-continue) ;; ick
>            ,continue
>            ,post
>            (go ,iterate))))))
>

(defmacro c-for ((init test post) &body body)
  (when (null test) (setf test t))
  `(progn ,init
     (loop while ,test do
           (progn
             ,@body
             ,post))))

Am I overlooking something?

--
Geoff 
From: Geoffrey Summerhayes
Subject: Re: tagbody mystery
Date: 
Message-ID: <UYwyf.2189$xk1.50245@news20.bellglobal.com>
"Geoffrey Summerhayes" <·······@NhOoStPmAaMil.com> wrote in message ·····················@news20.bellglobal.com...
>
> (defmacro c-for ((init test post) &body body)
>  (when (null test) (setf test t))
>  `(progn ,init
>     (loop while ,test do
>           (progn
>             ,@body
>             ,post))))
>
> Am I overlooking something?
>

Arrgh. Too damn obvious. I blaim lack of sleep and an
internal prejudice against continue. It hit me about
one minute after I posted. It's the one keyword I've
never used in ~20 years of C/C++ coding. I've always
just if-else'd the body. It just seemed a lot clearer.

--
Geoff
 
From: Kenny Tilton
Subject: Re: tagbody mystery
Date: 
Message-ID: <JAyyf.596$yE4.529@news-wrt-01.rdc-nyc.rr.com>
Geoffrey Summerhayes wrote:
> "Geoffrey Summerhayes" <·······@NhOoStPmAaMil.com> wrote in message ·····················@news20.bellglobal.com...
> 
>>(defmacro c-for ((init test post) &body body)
>> (when (null test) (setf test t))
>> `(progn ,init
>>    (loop while ,test do
>>          (progn
>>            ,@body
>>            ,post))))
>>
>>Am I overlooking something?
>>
> 
> 
> Arrgh. Too damn obvious. I blaim lack of sleep and an
> internal prejudice against continue. It hit me about
> one minute after I posted. It's the one keyword I've
> never used in ~20 years of C/C++ coding. I've always
> just if-else'd the body. It just seemed a lot clearer.

And I am a biggggg fan of structured programming, but in a lot of this 
code I would have two three or four reasons for punting on an iteration 
before possibly accepting an element for final processing, and in this 
case it seemed clearer to code:

     if <bad idea> continue;

     chomp;

     chomp;

     if <bad idea now> continue;

     <etc>

     ok-do-it;


I mean, that syntactically expresses what is going on better, possibly 
because of the imperative leanings of C.... ok, this is 15 year-old 
code, monitors weren't so big then, had to keep lines short. :)

kenny
From: M Jared Finder
Subject: Re: tagbody mystery
Date: 
Message-ID: <zdmdnaIgR4uUG1feRVn-ig@speakeasy.net>
Kenny Tilton wrote:
> Here is my Lisp version of a C "for":
> 
> (defmacro c-for ((init test post) &body body)
>   (let ((iterate (gensym))
>         (continue (gensym)))
>     (declare (ignorable continue))
>     `(macrolet ((c-continue () `(go ,',continue)))
>        (block nil
>          ,init
>          (tagbody
>            ,iterate
>            (when (not ,test)
>              (return))
>            ,@body
>            (c-continue) ;; ick
>            ,continue
>            ,post
>            (go ,iterate))))))
> 
> If the user does not code (c-continue), I get an "unreferenced tag" 
> warning from AllegroCL. Homey don't play warnings.
> 
> I tried a declare-ignorable on the tag as the first form in the tagbody, 
> but CL don't play that.
> 
> No choice but the bogus forced go-continue?

I don't have ACL available, so I can't test if this would work, but what 
about if you used flet instead of macrolet?  You could declare the 
c-continue function ignorable then:

(defmacro c-for ((init test post) &body body)
   (let ((iterate (gensym))
         (continue (gensym)))
     `(block nil
        ,init
        (tagbody
           ,iterate
           (when (not ,test) (return))
           (flet ((c-continue () (go ,continue)))
             (declare (ignorable #'c-continue))
             ,@body)
           ,continue
           ,post
           (go ,iterate)))))

   -- MJF
From: tichy
Subject: Re: tagbody mystery
Date: 
Message-ID: <dqdc6l$7c4$1@nemesis.news.tpi.pl>
Hi. Why not:

CL-USER> (defmacro c-for-2 ((init test post) &body body)
	   `(macrolet ((c-continue () ',(list 'go '#1=#:continue)))
	      ,(append
		`(prog ,init #0=#:iterate (unless ,test (return)))
		body
		`(#1# ,post (go #0#)))))
C-FOR-2
CL-USER> (c-for-2 (((i 0)) (< i 5) (incf i)) (print i))

0
1
2
3
4
NIL
CL-USER> (c-for-2 (((i 0)) (< i 5) (incf i)) (print i) (print "xxx"))

0
"xxx"
1
"xxx"
2
"xxx"
3
"xxx"
4
"xxx"
NIL
CL-USER> (c-for-2 (((i 0)) (< i 5) (incf i)) (print i) (c-continue) (print "xxx"))

0
1
2
3
4
NIL

Regards, Szymon.
From: tichy
Subject: Re: tagbody mystery
Date: 
Message-ID: <dqdchj$8ec$1@atlantis.news.tpi.pl>
Hi. Another version:

CL-USER> (defmacro c-for-3 ((init test post) &body body)
	   `(macrolet ((c-continue () ',(list 'go '#1=#:continue)))
	      (block #3=#:block
		(let ,init
		  (tagbody
		     #0=#:iterate
		     (unless ,test (return-from #3#))
		     ,@body
		     #1#
		     ,post
		     (go #0#))))))
C-FOR-3
CL-USER> (c-for-3 (((i 0)) (< i 5) (incf i)) (print i))

0
1
2
3
4

NIL
CL-USER> (c-for-3 (((i 0)) (< i 5) (incf i)) (print i) (print "xxx"))

0
"xxx"
1
"xxx"
2
"xxx"
3
"xxx"
4
"xxx"
NIL
CL-USER> (c-for-3 (((i 0)) (< i 5) (incf i)) (print i) (c-continue) (print "xxx"))

0
1
2
3
4
NIL

Reagrds, Szymon.
From: tichy
Subject: Re: tagbody mystery
Date: 
Message-ID: <dqde0k$dft$1@atlantis.news.tpi.pl>
Kenny Tilton wrote:
> Here is my Lisp version of a C "for":
> 
> (defmacro c-for ((init test post) &body body)
>   (let ((iterate (gensym))
>         (continue (gensym)))
>     (declare (ignorable continue))
>     `(macrolet ((c-continue () `(go ,',continue)))
>        (block nil
>          ,init
>          (tagbody
>            ,iterate
>            (when (not ,test)
>              (return))
>            ,@body
>            (c-continue) ;; ick
>            ,continue
>            ,post
>            (go ,iterate))))))

I added LET, RETURN-FROM to this:

(defmacro c-for ((init test post) &body body)
   (let ((iterate (gensym))
         (continue (gensym))
         (block (gensym)))
     `(macrolet ((c-continue () `(go ,',continue)))
        (block ,block
          (let ,init
            (tagbody
             ,iterate
             (when (not ,test)
               (return-from ,block))
             ,@body
             ,continue
             ,post
             (go ,iterate)))))))

> If the user does not code (c-continue), I get an "unreferenced tag" 
> warning from AllegroCL. Homey don't play warnings.

SBCL remains silent with yours code. Use MUFFLE-WARNING ;)

Regards, Szymon.
From: Kenny Tilton
Subject: Re: tagbody mystery
Date: 
Message-ID: <KHzyf.597$yE4.256@news-wrt-01.rdc-nyc.rr.com>
tichy wrote:
> Kenny Tilton wrote:
> 
>> Here is my Lisp version of a C "for":
>>
>> (defmacro c-for ((init test post) &body body)
>>   (let ((iterate (gensym))
>>         (continue (gensym)))
>>     (declare (ignorable continue))
>>     `(macrolet ((c-continue () `(go ,',continue)))
>>        (block nil
>>          ,init
>>          (tagbody
>>            ,iterate
>>            (when (not ,test)
>>              (return))
>>            ,@body
>>            (c-continue) ;; ick
>>            ,continue
>>            ,post
>>            (go ,iterate))))))
> 
> 
> I added LET, RETURN-FROM to this:

My C is rusty, but I did check this under classic K&R C (the way the 
code was developed):

int test ( void ) {
     int x;

     for ( x=5; x < 10; ++x );

     return(x);
}

...returns 10. So, unfortunately, a C for has to expand into SETFs just 
as the C "for" init does assigns.

I'll play with the other versions, thx.

> 
> (defmacro c-for ((init test post) &body body)
>   (let ((iterate (gensym))
>         (continue (gensym))
>         (block (gensym)))
>     `(macrolet ((c-continue () `(go ,',continue)))
>        (block ,block
>          (let ,init
>            (tagbody
>             ,iterate
>             (when (not ,test)
>               (return-from ,block))
>             ,@body
>             ,continue
>             ,post
>             (go ,iterate)))))))
> 
>> If the user does not code (c-continue), I get an "unreferenced tag" 
>> warning from AllegroCL. Homey don't play warnings.
> 
> 
> SBCL remains silent with yours code.

Yeah, I think AllegroCL is blowing this one. Where are the CL language 
lawyers when we need them?

> Use MUFFLE-WARNING ;)

Hey, the applications I ship silently trap all runtime errors, why not?

kenny
From: Brian Downing
Subject: Re: tagbody mystery
Date: 
Message-ID: <u87zf.495940$084.9875@attbi_s22>
In article <·················@news-wrt-01.rdc-nyc.rr.com>,
Kenny Tilton  <·············@nyc.rr.com> wrote:
> Here is my Lisp version of a C "for":

[relatively simple tagbody translation]

So how are you going to translate some of the more delightful
possibilities of the C language?  :-)

:; cat kenny.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    int i = 7;

    if (atoi(argv[1])) goto shortcut;

    for (i = 0; i < 10; i++) {
        printf("pre ");
    shortcut:
        printf("%d post\n", i);
    }

    return 0;
}
:; gcc -Wall -o kenny kenny.c
:; ./kenny 0                 
pre 0 post
pre 1 post
pre 2 post
pre 3 post
pre 4 post
pre 5 post
pre 6 post
pre 7 post
pre 8 post
pre 9 post
:; ./kenny 1                 
7 post
pre 8 post
pre 9 post

Replace with a switch and case for extra fun.

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Thomas F. Burdick
Subject: Re: tagbody mystery
Date: 
Message-ID: <xcv3bjm3jjb.fsf@conquest.OCF.Berkeley.EDU>
Brian Downing <·············@lavos.net> writes:

> In article <·················@news-wrt-01.rdc-nyc.rr.com>,
> Kenny Tilton  <·············@nyc.rr.com> wrote:
> > Here is my Lisp version of a C "for":
> 
> [relatively simple tagbody translation]
> 
> So how are you going to translate some of the more delightful
> possibilities of the C language?  :-)

Since Kenny wrote the app he's translating, I have a suspicion that
this won't come up.  However...

> :; cat kenny.c
> #include <stdio.h>
> #include <stdlib.h>
> 
> int main(int argc, char **argv)
> {
>     int i = 7;
> 
>     if (atoi(argv[1])) goto shortcut;
> 
>     for (i = 0; i < 10; i++) {
>         printf("pre ");
>     shortcut:
>         printf("%d post\n", i);
>     }
> 
>     return 0;
> }
>
> :; gcc -Wall -o kenny kenny.c
> :; ./kenny 0                 
> pre 0 post
> pre 1 post
> pre 2 post
> pre 3 post
> pre 4 post
> pre 5 post
> pre 6 post
> pre 7 post
> pre 8 post
> pre 9 post
> :; ./kenny 1                 
> 7 post
> pre 8 post
> pre 9 post

Yeah, CL's GO is really a structured-programming goto, unlike C's.
However, I suspect that LAMBDA is the Ultimate Go-To Statement.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Joe Marshall
Subject: Re: tagbody mystery
Date: 
Message-ID: <1137529745.752935.63740@g14g2000cwa.googlegroups.com>
Brian Downing wrote:
> So how are you going to translate some of the more delightful
> possibilities of the C language?  :-)
>
> :; cat kenny.c
> #include <stdio.h>
> #include <stdlib.h>
>
> int main(int argc, char **argv)
> {
>     int i = 7;
>
>     if (atoi(argv[1])) goto shortcut;
>
>     for (i = 0; i < 10; i++) {
>         printf("pre ");
>     shortcut:
>         printf("%d post\n", i);
>     }
>
>     return 0;
> }

I used the simple expedient of outlawing such code in my compiler.
From: Kenny Tilton
Subject: Re: tagbody mystery
Date: 
Message-ID: <lrjzf.819$yE4.589@news-wrt-01.rdc-nyc.rr.com>
Joe Marshall wrote:
> Brian Downing wrote:
> 
>>So how are you going to translate some of the more delightful
>>possibilities of the C language?  :-)
>>
>>:; cat kenny.c
>>#include <stdio.h>
>>#include <stdlib.h>
>>
>>int main(int argc, char **argv)
>>{
>>    int i = 7;
>>
>>    if (atoi(argv[1])) goto shortcut;
>>
>>    for (i = 0; i < 10; i++) {
>>        printf("pre ");
>>    shortcut:
>>        printf("%d post\n", i);
>>    }
>>
>>    return 0;
>>}
> 
> 
> I used the simple expedient of outlawing such code in my compiler.
> 

I am worse. I detected a point of diminishing return and now mercilessly 
slay in the original C the few things that my parser cannot handle. 
Fortunately the VC++ preprocessor gleefully ignores the resulting 
atrocities and Just Preprocesses (ok, duh, obviously now that I think of 
it).

When the CL compiler whines I will deal with it. As Thomas said, I have 
the luxury of just worrying about one pile of C source. Which now 
successfully all translates, successful defined as "not backtracing". 
Next step is to clean up bugs like generating:

      (make-array (2 3) :element-type Byte)

oops.

kt
From: André Thieme
Subject: Re: tagbody mystery
Date: 
Message-ID: <1137587414.649069.229170@g47g2000cwa.googlegroups.com>
Brian Downing schrieb:

> In article <·················@news-wrt-01.rdc-nyc.rr.com>,
> Kenny Tilton  <·············@nyc.rr.com> wrote:
> > Here is my Lisp version of a C "for":
>
> [relatively simple tagbody translation]
>
> So how are you going to translate some of the more delightful
> possibilities of the C language?  :-)
>
> :; cat kenny.c
> #include <stdio.h>
> #include <stdlib.h>
>
> int main(int argc, char **argv)
> {
>     int i = 7;
>
>     if (atoi(argv[1])) goto shortcut;
>
>     for (i = 0; i < 10; i++) {
>         printf("pre ");
>     shortcut:
>         printf("%d post\n", i);
>     }
>
>     return 0;
> }
> :; gcc -Wall -o kenny kenny.c
> :; ./kenny 0
> pre 0 post
> pre 1 post
> pre 2 post
> pre 3 post
> pre 4 post
> pre 5 post
> pre 6 post
> pre 7 post
> pre 8 post
> pre 9 post
> :; ./kenny 1
> 7 post
> pre 8 post
> pre 9 post
>
> Replace with a switch and case for extra fun.

Are you talking about Duffs device?

send(to, from, count)
register short *to, *from;
register count;
{
	register n=(count+7)/8;
	switch(count%8){
	case 0:	do{	*to = *from++;
	case 7:		*to = *from++;
	case 6:		*to = *from++;
	case 5:		*to = *from++;
	case 4:		*to = *from++;
	case 3:		*to = *from++;
	case 2:		*to = *from++;
	case 1:		*to = *from++;
		}while(--n>0);
	}
}


André
--
From: Brian Downing
Subject: Re: tagbody mystery
Date: 
Message-ID: <aQtzf.740957$xm3.176986@attbi_s21>
In article <························@g47g2000cwa.googlegroups.com>,
Andr� Thieme <······························@justmail.de> wrote:
> Are you talking about Duffs device?

The same basic principle allows Duff's device to work, but it's useful
for other (more useful) things, like coroutines.  This behavior is
specified in ANSI C.

Yes, I have shamelessly exploited this in embedded system code; I hate
writing state machines.

-bcd
--
*** Brian Downing <bdowning at lavos dot net>