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
"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
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
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
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
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>
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! |
( -. | `-----------------------'
| ) |
(`-. '--.)
`. )----'
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.
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
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é
--
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>