From: Kenny Tilton
Subject: Translate this!
Date: 
Message-ID: <bbixf.396$MN4.192@news-wrt-01.rdc-nyc.rr.com>
Speaking of translating from C to Lisp, how would you like to see this 
artificial case translated?:

int testif (int one, int two, int three, int four) {
	if (one)
		return 0;
	if (two)
		return 1;
	else
		return 2;
	if (three)
		if (four)
			return 3;
		else if (two)
			return 4;
		else
			return 5;
	else if (one && two)
		if (three) {
			return 6;
		} else {
			return 7;
		}
	else
		return 8;
}

I know, it does not make any sense, but the preprocessor does not know 
that so I can get output for the whole thing.

Please vote for option 1, 2, or 3, or offer your own.

Note that I do expect to have to debug mightily after the translation 
has been made, but I face a self-imposed penalty of death if I start 
refactoring the thing, so really I just have to be able to read the code.

#+option1
;; almost literal xlation
(defun testif (one two three four)

   (when one
     (return-from testif 0))

   (if two
     (return-from testif 1)
     (return-from testif 2))

   (if three
       (if four
           (return-from testif 3)
         (if two
             (return-from testif 4)
           (return-from testif 5)))
     (if (and one two)
         (if three
             (return-from testif 6)
           (return-from testif 7))
       (return-from testif 8))))

#+option2
;; we have cond, use it! The Lisp Way, but is option1 more readable?
(defun testif (one two three four)

   (when one
     (return-from testif 0))

   (if two
     (return-from testif 1)
     (return-from testif 2))

   (cond
    (three (cond
            (four (return-from testif 3))
            (two (return-from testif 4))
            (t (return-from testif 5))))
    ((and one two)
     (if three
         (return-from testif 6)
       (return-from testif 7)))
    (t (return-from testif 8))))

#+option3
;; all cond all the time! (easier xlation)
(defun testif (one two three four)
   (cond
    (one (return-from testif 0)))

   (cond
    (two (return-from testif 1))
    (t (return-from testif 2)))

   (cond
    (three (cond
            (four (return-from testif 3))
            (two (return-from testif 4))
            (t (return-from testif 5))))
    ((and one two)
     (cond
      (three (return-from testif 6))
      (t (return-from testif 7))))
    (t (return-from testif 8))))

thx for voting, kenny

From: Joe Marshall
Subject: Re: Translate this!
Date: 
Message-ID: <1137039849.088067.14290@g49g2000cwa.googlegroups.com>
Kenny Tilton wrote:
> Speaking of translating from C to Lisp, how would you like to see this
> artificial case translated?:
>
> int testif (int one, int two, int three, int four) {
> 	if (one)
> 		return 0;
> 	if (two)
> 		return 1;
> 	else
> 		return 2;
> 	if (three)
> 		if (four)
> 			return 3;
> 		else if (two)
> 			return 4;
> 		else
> 			return 5;
> 	else if (one && two)
> 		if (three) {
> 			return 6;
> 		} else {
> 			return 7;
> 		}
> 	else
> 		return 8;
> }
>
> I know, it does not make any sense, but the preprocessor does not know
> that so I can get output for the whole thing.
>
> Please vote for option 1, 2, or 3, or offer your own.

Ok, so my compiler outputs Scheme, but it isn't as a few macros
couldn't make this run in common lisp.  Without optimizations, this is
the output:

(define (testif one two three four)
  (call-with-current-continuation
   (lambda (return)
     (if (zerop one)
         (return 0)
         (begin
          (if (zerop two) (return 1) (return 2))
          (cond
            ((zerop three)
             (cond
               ((zerop four) (return 3))
               ((zerop two) (return 4))
               (else (return 5))))
            ((and (zerop one) (zerop two))
             (if (zerop three) (return 6) (return 7)))
            (else (return 8))))))))

If optimizations were on, I'd expect this:

(define (testif one two three four)
  (cond ((zerop one) 0)
        ((zerop two) 1)
        (t 2)))

I turned off the optimizations because I'm trying to debug the control
flow in loops.
From: Kenny Tilton
Subject: Re: Translate this!
Date: 
Message-ID: <_Ynxf.1307$jh3.455@news-wrt-01.rdc-nyc.rr.com>
Joe Marshall wrote:
> Kenny Tilton wrote:
> 
>>Speaking of translating from C to Lisp, how would you like to see this
>>artificial case translated?:
>>
>>int testif (int one, int two, int three, int four) {
>>	if (one)
>>		return 0;
>>	if (two)
>>		return 1;
>>	else
>>		return 2;
>>	if (three)
>>		if (four)
>>			return 3;
>>		else if (two)
>>			return 4;
>>		else
>>			return 5;
>>	else if (one && two)
>>		if (three) {
>>			return 6;
>>		} else {
>>			return 7;
>>		}
>>	else
>>		return 8;
>>}
>>
>>I know, it does not make any sense, but the preprocessor does not know
>>that so I can get output for the whole thing.
>>
>>Please vote for option 1, 2, or 3, or offer your own.
> 
> 
> Ok, so my compiler outputs Scheme, but it isn't as a few macros
> couldn't make this run in common lisp.  Without optimizations, this is
> the output:
> 
> (define (testif one two three four)
>   (call-with-current-continuation
>    (lambda (return)
>      (if (zerop one)
>          (return 0)
>          (begin
>           (if (zerop two) (return 1) (return 2))
>           (cond
>             ((zerop three)
>              (cond
>                ((zerop four) (return 3))
>                ((zerop two) (return 4))
>                (else (return 5))))
>             ((and (zerop one) (zerop two))
>              (if (zerop three) (return 6) (return 7)))
>             (else (return 8))))))))
> 
> If optimizations were on, I'd expect this:
> 
> (define (testif one two three four)
>   (cond ((zerop one) 0)
>         ((zerop two) 1)
>         (t 2)))
> 
> I turned off the optimizations because I'm trying to debug the control
> flow in loops.
> 

Wow! Awesome. Yer optimizing? Very cool.

Quibble: zero is false in C.
Shouldn't those be (not (zerop ...)) to match my code?

Also, why optimize? Do you suspect the C code has a lot of logically 
unreachable code?


kt
From: Joe Marshall
Subject: Re: Translate this!
Date: 
Message-ID: <1137090391.904088.80060@g47g2000cwa.googlegroups.com>
Kenny Tilton wrote:
>
> Wow! Awesome. Yer optimizing? Very cool.

Hell, yes!  I wouldn't go through all this damn work if it didn't at
least write conditionals.  (And *you* didn't read that crap I spent so
much time writing about handling DeMorgan's law and smart constructors
or you would have known that!)

>
> Quibble: zero is false in C.
> Shouldn't those be (not (zerop ...)) to match my code?

Grrr.  I goofed.  The live output had this:

  (cond ((->boolean one) 0)
       ((->boolean two) 1)
....

Where ->boolean is a rather trivial macro that is expected to be there
at runtime.  When I was transcribing the output to the news reader, I
figured `what the hell' and simply macro-expanded (in my head).  And I
got it wrong of course.

> Also, why optimize? Do you suspect the C code has a lot of logically
> unreachable code?

No, it is the fact that raw output is just *awful*.  The C code was bad
enough (I was translating some programs that had functions that were
literally thousands of lines long.) and I didn't want to end up with a
true nightmare of Scheme code.

The problem with how C does flow control (as you are getting intimately
familiar with) is that with all the non-local exits (return-froms) at
random locations, you can't just pick up an s-expression with emacs,
move it elsewhere, and expect it to continue working.  I wanted to be
able to do that with the output.

------
For those that are interested, the optimization worked like this:  the
compile target language was an intermediate one called `xmodel' which
was tree-structured.  The nodes in the tree were constructed with
`smart' constructors.  So in the example Mr. Tilton provided, we'd
construct leaf nodes like (return 0) and (return 1), and then we'd get
around to constructing the conditional node.

The constructor for the conditional node would (if unoptimized) simply
paste together a two-armed conditional:
   (if (->boolean one)
      (return 0)
      (return 1))

But since the consequent and alternative nodes are `return' nodes, the
constructor for the conditional hoists the return out of both and
constructs a node like this:
   (return
     (if (->boolean one)
         0
         1))

There are several of these trivial rewrites in the xmodel constructors.
 Another one of interest is the one for `begin' (progn) nodes.  If the
first expression in the progn was a return node, we simply discarded
the remaining expressions (dead code).
Finally, there was a more complicated rewrite that handled DeMorgan's
law in conditionals.  You wouldn't think it would be *that* complicated
(I didn't) but you can run DeMorgan's law in both directions (expansion
and contraction) and it turns out that sometimes you want to expand at
the low level in order to facilitate a contraction at the high level.
The problem was that a naive optimizer would immediately remove the
low-level expansion before the high-level contraction could see it.

There was only one kind of conditional node in the `xmodel': the
two-armed if.  The `xmodel' code was translated into `lmodel' which is
sort of an AST for lisp made from CLOS instances.  There was a final
`code emission' step that walked the CLOS objects of the lmodel and
produced s-expressions.  During the code emission step, the two-armed
conditionals were translated into COND, IF, UNLESS, or WHEN as
appropriate.

A longer explanation, sample input and output, and running code (it
runs if you tease it a bit) are available at:
http://home.comcast.net/~prunequallor/Evil_Part_II.zip
From: Edi Weitz
Subject: Re: Translate this!
Date: 
Message-ID: <uk6d5s1ai.fsf@agharta.de>
On 12 Jan 2006 10:26:31 -0800, "Joe Marshall" <··········@gmail.com> wrote:

> A longer explanation, sample input and output, and running code (it
> runs if you tease it a bit) are available at:
> http://home.comcast.net/~prunequallor/Evil_Part_II.zip

  http://home.comcast.net/~prunesquallor/Evil_Part_II.zip

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Kenny Tilton
Subject: Re: Translate this!
Date: 
Message-ID: <iBBxf.38$yE4.17@news-wrt-01.rdc-nyc.rr.com>
Joe Marshall wrote:
> Kenny Tilton wrote:
> 
>>Wow! Awesome. Yer optimizing? Very cool.
> 
> 
> Hell, yes!  I wouldn't go through all this damn work if it didn't at
> least write conditionals.  (And *you* didn't read that crap I spent so
> much time writing about handling DeMorgan's law and smart constructors
> or you would have known that!)

Damn, fifty-four and I am still being assigned homework. Sorry. Didn't 
Edi tell you I cannot read? Anyway, it would be lost on me, I am not 
smart like you guys, just a simple application programmer.

> 
> 
>>Quibble: zero is false in C.
>>Shouldn't those be (not (zerop ...)) to match my code?
> 
> 
> Grrr.  I goofed.  The live output had this:
> 
>   (cond ((->boolean one) 0)
>        ((->boolean two) 1)
> ....
> 
> Where ->boolean is a rather trivial macro that is expected to be there
> at runtime.  When I was transcribing the output to the news reader, I
> figured `what the hell' and simply macro-expanded (in my head).  And I
> got it wrong of course.
> 
> 
>>Also, why optimize? Do you suspect the C code has a lot of logically
>>unreachable code?
> 
> 
> No, it is the fact that raw output is just *awful*.  The C code was bad
> enough (I was translating some programs that had functions that were
> literally thousands of lines long.) and I didn't want to end up with a
> true nightmare of Scheme code.

Oh. I guess I am at least a /good/ application programmer. No functions 
over one hundred lines allowed. I think I am applying Graham's "must fit 
in the head" rule (for languages) to functions.

> 
> The problem with how C does flow control (as you are getting intimately
> familiar with) is that with all the non-local exits (return-froms) at
> random locations, you can't just pick up an s-expression with emacs,
> move it elsewhere, and expect it to continue working.  I wanted to be
> able to do that with the output.

Sounds like you are doing a great job with this. Maybe I should install 
a Scheme and spend a day with your hack. Which Scheme?

Actually, I am making good progress myself. Astonishing how even after 
parsing 20% of my code I can still run into new syntax. Which reminds me 
of why I dumped C++ and eventually found Lisp: I saw the bit where one 
made a function member (terminology?) virtual by assigning zero to it. I 
just laughed and put the book down... very early chapter, too.

> 
> ------
> For those that are interested, the optimization worked like this:  the
> compile target language was an intermediate one called `xmodel' which
> was tree-structured.  The nodes in the tree were constructed with
> `smart' constructors.  So in the example Mr. Tilton provided, we'd
> construct leaf nodes like (return 0) and (return 1), and then we'd get
> around to constructing the conditional node.

Ooooh, you lucky stiff. Turns out the C parser I found falls short in a 
few corners, emitting more of a token stream than a recognized 
structure. Guess who gets to do that? :) But it is a manageable amount 
they left undone.

> 
> The constructor for the conditional node would (if unoptimized) simply
> paste together a two-armed conditional:
>    (if (->boolean one)
>       (return 0)
>       (return 1))
> 
> But since the consequent and alternative nodes are `return' nodes, the
> constructor for the conditional hoists the return out of both and
> constructs a node like this:
>    (return
>      (if (->boolean one)
>          0
>          1))

And I thought I was having fun.

So what has gotten into you? Are you getting ready to port Linux to Lisp 
or something?

kt
From: Gareth McCaughan
Subject: Re: Translate this!
Date: 
Message-ID: <871wzd7yrf.fsf@g.mccaughan.ntlworld.com>
Kenny Tilton wrote:

> Actually, I am making good progress myself. Astonishing how even after
> parsing 20% of my code I can still run into new syntax. Which reminds
> me of why I dumped C++ and eventually found Lisp: I saw the bit where
> one made a function member (terminology?) virtual by assigning zero to
> it. I just laughed and put the book down... very early chapter, too.

"Member function" and "pure virtual". But yes, it's just
deeply sucky. I have a theory that the way C++ was, errrrm,
designed was as follows:

    (loop
      (let ((p (generate-random-token-stream)))
        (multiple-value-bind (ok? failing-toklist)
                             (try-to-parse p)
          (unless ok?
            (add-to-syntax failing-toklist
                           (generate-random-semantics))))))

-- 
Gareth McCaughan
.sig under construc
From: Joe Marshall
Subject: Re: Translate this!
Date: 
Message-ID: <1137172516.747743.277680@g14g2000cwa.googlegroups.com>
Kenny Tilton wrote:

> So what has gotten into you?

As you noticed, C++ is so brain damaged it is easier to teach a
computer how to deal with it than it is to figure it out yourself.  A
hell of a lot more fun, too.
From: Kenny Tilton
Subject: Re: Translate this!
Date: 
Message-ID: <azPxf.1613$cj3.945@news-wrt-01.rdc-nyc.rr.com>
Joe Marshall wrote:
> Kenny Tilton wrote:
> 
>>Wow! Awesome. Yer optimizing? Very cool.
> 
> 
> Hell, yes!  I wouldn't go through all this damn work if it didn't at
> least write conditionals.

You win. Having seen the output now that <woo-hoo!> I am translating all 
23kloc of C into Lisp (with 738 #defines still to hand-translate), I 
think I will look at adding a clean-up pass.

    if (a || b || c || d)

became

    (if (or (or (or a b) c) d)..

eww. and since every non-void function ends with return(x), all the Lisp 
functions end with (return-from <fn> x). ewww.

Not sure if I will try to write conds. Gotta see how often that comes 
up. Hang on... "else if" appears just 170 times. Hmmmm.

The good news being that the cleaner-upper gets to process a proper 
syntax. OK, so I am looking for software that can take a rule like:

     (OR (OR %1 %2) %3) -> (OR %1 %2 %3)

(lispier, of course) and then run all over a tree making it so. Sounds 
like about an hour's work, but... does this exist? One of Edi's 
packages? A Prolog package?

kenny
From: Joe Marshall
Subject: Re: Translate this!
Date: 
Message-ID: <1137174486.924011.225730@g43g2000cwa.googlegroups.com>
Kenny Tilton wrote:
> Joe Marshall wrote:
> > Kenny Tilton wrote:
> >
> >>Wow! Awesome. Yer optimizing? Very cool.
> >
> >
> > Hell, yes!  I wouldn't go through all this damn work if it didn't at
> > least write conditionals.
>
> You win. Having seen the output now that <woo-hoo!> I am translating all
> 23kloc of C into Lisp (with 738 #defines still to hand-translate), I
> think I will look at adding a clean-up pass.
>
>     if (a || b || c || d)
>
> became
>
>     (if (or (or (or a b) c) d)..
>
> eww. and since every non-void function ends with return(x), all the Lisp
> functions end with (return-from <fn> x). ewww.
>
> Not sure if I will try to write conds. Gotta see how often that comes
> up. Hang on... "else if" appears just 170 times. Hmmmm.

Don't forget these, too:

   if (something) {
       ...code...;
    }
    else {
        if (somethingelse) {
          ....more code....;
          }
        else {
        }
    }

> The good news being that the cleaner-upper gets to process a proper
> syntax. OK, so I am looking for software that can take a rule like:
>
>      (OR (OR %1 %2) %3) -> (OR %1 %2 %3)
>
> (lispier, of course) and then run all over a tree making it so. Sounds
> like about an hour's work, but... does this exist? One of Edi's
> packages? A Prolog package?

You'll want to spend more time than an hour.  There's about a dozen
rules you'll want to apply and you need to be careful how you apply
them (or you'll be spinning your wheels as one rewrite undoes the
effect of another).

As I mentioned before, I use `smart constructors' in my compiler.  When
you are creating a "compiled combination" (a function call node), the
compiler peeks at the operator and takes special action if the operator
is AND, OR, or NOT.

In the example you mention, I'm guessing you have a place in your
translator that does the equivalent of this:
    `(OR ,lhs ,rhs)
so you end up with your strange output. My compiler uses CLOS instances
internally and doesn't spit out s-expressions until the last moment, so
you'll that where you have written
`(OR ,lhs ,rhs) I have written (make-disjunction lhs rhs)

Make-disjunction started off as simply making an `(OR ,lhs ,rhs), but
things got more complicated.  Now it walks both the lhs and rhs
arguments.  It `flattens' out the nested OR nodes and applies
DeMorgan's law to the nested (NOT (AND ...)) nodes.  Then it counts how
many of the nested expressions are (NOT ....) expressions to determine
if it should apply DeMorgan's law to the result.

----

I think you're following the same path I did.  I started with a really
simple translator, got tired of the obvious shortcomings, added a few
hacks, added a few more, added a few more, and suddenly noticed that my
translator had morphed into an opmitizing compiler.
From: Kenny Tilton
Subject: Re: Translate this!
Date: 
Message-ID: <K%Xxf.1651$cj3.1226@news-wrt-01.rdc-nyc.rr.com>
Joe Marshall wrote:
> Kenny Tilton wrote:
> 
>>Joe Marshall wrote:
>>
>>>Kenny Tilton wrote:
>>>
>>>
>>>>Wow! Awesome. Yer optimizing? Very cool.
>>>
>>>
>>>Hell, yes!  I wouldn't go through all this damn work if it didn't at
>>>least write conditionals.
>>
>>You win. Having seen the output now that <woo-hoo!> I am translating all
>>23kloc of C into Lisp (with 738 #defines still to hand-translate), I
>>think I will look at adding a clean-up pass.
>>
>>    if (a || b || c || d)
>>
>>became
>>
>>    (if (or (or (or a b) c) d)..
>>
>>eww. and since every non-void function ends with return(x), all the Lisp
>>functions end with (return-from <fn> x). ewww.
>>
>>Not sure if I will try to write conds. Gotta see how often that comes
>>up. Hang on... "else if" appears just 170 times. Hmmmm.
> 
> 
> Don't forget these, too:
> 
>    if (something) {
>        ...code...;
>     }
>     else {
>         if (somethingelse) {
>           ....more code....;
>           }
>         else {
>         }
>     }

A small sample indicates "not much". Besides, I am not that sure I even 
find the corresponding if-else Lisp that much easier to read than COND.

> 
> 
>>The good news being that the cleaner-upper gets to process a proper
>>syntax. OK, so I am looking for software that can take a rule like:
>>
>>     (OR (OR %1 %2) %3) -> (OR %1 %2 %3)
>>
>>(lispier, of course) and then run all over a tree making it so. Sounds
>>like about an hour's work, but... does this exist? One of Edi's
>>packages? A Prolog package?
> 
> 
> You'll want to spend more time than an hour.  There's about a dozen
> rules you'll want to apply and you need to be careful how you apply
> them (or you'll be spinning your wheels as one rewrite undoes the
> effect of another).

yes, apply all the usual multiples for programmer estimates.

Just noticed another easy save. Auto translation produced:

    (not (logand x y))

Easy enough to recognize that and its ilk and produce:

    (not (zerop (logand x y)))

In this i really am using a number as a bitmap and testing if anything 
matches, so I will not lose logand until I decide to refactor (and, 
again, I want to avoid that and Just Ship something).

I don't hate the code I am seeing now, so not sure how much more time I 
want to spend on the translator. My philosophy is that if I have trouble 
with a code during testing I can rewrite locally if I cannot understand 
the code. Do that anyway with Lisp I have written.

I'll just try not to invest time in refactoring until I am sure there is 
not some recurring translation problem driving me nuts such that I will 
want to re-run the translator again.

At some point there will be no turning back.

But you sound as if you are going for the Big Enchilada. Lemme know when 
you can translate ImageMagick into Lisp. <g> Better, maybe Rayiner could 
dump gcc_xml and use Evil for Verrazano.

> I think you're following the same path I did.  I started with a really
> simple translator, got tired of the obvious shortcomings, added a few
> hacks, added a few more, added a few more, and suddenly noticed that my
> translator had morphed into an opmitizing compiler.
> 

the temptation is obvious, but I really do want to re-release this old C 
app and start selling it. Need the bucks pretty soon, or it's back to 
work in tall buildings doing VAX COBOL and Basic... uh-oh.

kt
From: Adrian Kubala
Subject: Re: Translate this!
Date: 
Message-ID: <slrndsisau.4hn.adrian-news@sixfingeredman.net>
On 2006-01-13, Joe Marshall <··········@gmail.com> wrote:
> As I mentioned before, I use `smart constructors' in my compiler.  When
> you are creating a "compiled combination" (a function call node), the
> compiler peeks at the operator and takes special action if the operator
> is AND, OR, or NOT.

I'll second this idea; I did something really similar for a Pascal compiler.
Each operator had a list of patterns and transformations like this:

(define-pascal-operator '-
  ((x 0) x)                            ; x - 0 = x
  ((0 x) (ast `(neg ,x)))              ; 0 - x = -x
  (((pconst x) (pconst y)) (- x y))    ; 1 - 2 = 1
  (args (distribute-minus '+ '- args)) ; (- (+ 3 x) 2) = (+ 1 x)
  ((x y) (numeric-expression '- x y))) ; (- 1.2 x) = (- 1.2 (float x))

This was all applied automatically by the AST function which used the
definitions to simplify and type sexps from the parser. The moral I learned
from this is, pattern matching makes transformations much clearer.
From: Pascal Bourguignon
Subject: Re: Translate this!
Date: 
Message-ID: <87hd883sv1.fsf@thalassa.informatimago.com>
Kenny Tilton <·············@nyc.rr.com> writes:

> Joe Marshall wrote:
>> Kenny Tilton wrote:
>> 
>>>Wow! Awesome. Yer optimizing? Very cool.
>> Hell, yes!  I wouldn't go through all this damn work if it didn't at
>> least write conditionals.
>
> You win. Having seen the output now that <woo-hoo!> I am translating
> all 23kloc of C into Lisp (with 738 #defines still to hand-translate),
> I think I will look at adding a clean-up pass.
>
>     if (a || b || c || d)
>
> became
>
>     (if (or (or (or a b) c) d)..
>
> eww. and since every non-void function ends with return(x), all the
> Lisp functions end with (return-from <fn> x). ewww.
>
> Not sure if I will try to write conds. Gotta see how often that comes
> up. Hang on... "else if" appears just 170 times. Hmmmm.
>
> The good news being that the cleaner-upper gets to process a proper
> syntax. OK, so I am looking for software that can take a rule like:
>
>      (OR (OR %1 %2) %3) -> (OR %1 %2 %3)
>
> (lispier, of course) and then run all over a tree making it so. Sounds
> like about an hour's work, but... does this exist? One of Edi's
> packages? A Prolog package?

There are various code walkers (but most probably you won't even need
them, if you don't generate user macros) and various pattern matching
packages.  Try Far�'s Pattern Matcher.  Or write your own, it's fun.



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

CAUTION: The mass of this product contains the energy equivalent of
85 million tons of TNT per net ounce of weight.
From: Geoffrey Summerhayes
Subject: Re: Translate this!
Date: 
Message-ID: <jRjxf.28546$Pq4.249694@news20.bellglobal.com>
"Kenny Tilton" <·············@nyc.rr.com> wrote in message ······················@news-wrt-01.rdc-nyc.rr.com...
>
> I know, it does not make any sense, but the preprocessor does not know that so I can get output for the whole thing.
>
> Please vote for option 1, 2, or 3, or offer your own.
>

Definitely 2, followed soon by hunting down the C programmer.
I'm convinced this is not a good idea for most code, but
there's always:

(defun testif(one two three four)
  (cond (one 1)
        (two 1)
        (t 2)
        ((and three four) 3)
        ((and three two) 4)
        (three 5)
        ((and one two three) 6)
        ((and one two) 7)
        (t 8)))

--
Geoff
From: John Thingstad
Subject: Re: Translate this!
Date: 
Message-ID: <op.s28rw9e1pqzri1@mjolner.upc.no>
On Thu, 12 Jan 2006 02:22:15 +0100, Kenny Tilton  
<·············@nyc.rr.com> wrote:

If of one argument: when.
if of two aruments: if.
If of several argumets: cond.

So the 'right' function is number 2.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: RPG
Subject: Re: Translate this!
Date: 
Message-ID: <1137031711.939413.133840@g47g2000cwa.googlegroups.com>
Just out of curiosity, why all the unpleasant RETURN-FROMs?  If it's
just a big branching statement, can't you just have the branch
statement (COND or what-have-you) return the value you want, witout any
additional return-froms?  That seems very unlispy to me...
From: John Thingstad
Subject: Re: Translate this!
Date: 
Message-ID: <op.s28tnmwupqzri1@mjolner.upc.no>
On Thu, 12 Jan 2006 03:08:31 +0100, RPG <·········@gmail.com> wrote:

> Just out of curiosity, why all the unpleasant RETURN-FROMs?  If it's
> just a big branching statement, can't you just have the branch
> statement (COND or what-have-you) return the value you want, witout any
> additional return-froms?  That seems very unlispy to me...
>

The whole function is a translation from C.
Wery unlispy..

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Kenny Tilton
Subject: Re: Translate this!
Date: 
Message-ID: <8Tjxf.404$MN4.270@news-wrt-01.rdc-nyc.rr.com>
RPG wrote:
> Just out of curiosity, why all the unpleasant RETURN-FROMs?  If it's
> just a big branching statement, can't you just have the branch
> statement (COND or what-have-you) return the value you want, witout any
> additional return-froms?  That seems very unlispy to me...
> 

Recall that a C "return(value)" gets us clean out of a function, no 
matter where it is in the function. This is Lisp's (return-from 
<fn-name> value)

I /could/ just translate to "value" if and only if I was parsing the 
last form in an execution path, but that would require me to spend 
another week I think on my translator to teach it to analyze the global 
structure and make these decisions.

So it is a trade-off. This whole exercise is a trade-off between 
manually translating all 25kloc (aaaaaaargh!) and fully automatic 
translation (which I believe Mr. Marshall is doing) and what I am doing, 
mostly automatic with a little manual to make the automatic easier than 
what poor Mr. Marshall is wrestling with.

And there is some interesting stuff going on. I got a little macro-happy 
even in C and faked slot accessors with macros. I have hidden those from 
the preprocessor so it is generating function calls where it might have 
been expanding into all sorts of hairy dereferencing and producing 
dotted slot refs I would have to translate anyway. Instead I will 
manually translate the accessing (and other) macros -- to macros or 
functions -- and keep the code clean.

kenny
From: Kenny Tilton
Subject: Re: Translate this!
Date: 
Message-ID: <LXjxf.256$qT.18@news-wrt-01.rdc-nyc.rr.com>
John Thingstad wrote:
> On Thu, 12 Jan 2006 02:22:15 +0100, Kenny Tilton  
> <·············@nyc.rr.com> wrote:
> 
> If of one argument: when.
> if of two aruments: if.
> If of several argumets: cond.
> 
> So the 'right' function is number 2.
> 

I agree, but I posted too soon. Turns out the C parser I use to get 
intermediate output (blessedly lisp-y) converts:

    if else-if else-if else

to

    if
    else
        if
        else
            if
            else

So option1 just falls out for free -- I had a bug stopping it from doing 
so!! And I did not notice the above from a casual glance at the lisp-y 
output. You might understand why:

(defun test-if ()
   (let ((*print-right-margin* 100))
     (pprint (parse-function
              '(NFunctionDef
                (LITERAL_int (:text "int"))
                (NDeclarator
                 (ID (:text "testif"))
                 (NParameterTypeList
                  (NParameterDeclaration
                   (LITERAL_int (:text "int"))
                   (NDeclarator
                    (ID (:text "one"))))
                  (NParameterDeclaration
                   (LITERAL_int (:text "int"))
                   (NDeclarator
                    (ID (:text "two"))))
                  (NParameterDeclaration
                   (LITERAL_int (:text "int"))
                   (NDeclarator
                    (ID (:text "three"))))
                  (NParameterDeclaration
                   (LITERAL_int (:text "int"))
                   (NDeclarator
                    (ID (:text "four"))))))
                (NCompoundStatement (:text "testif")
                  (LITERAL_if (:text "if")
                    (ID (:text "one"))
                    (LITERAL_return (:text "return")
                      (IntOctalConst (:text "0"))))
                  (LITERAL_if (:text "if")
                    (ID (:text "two"))
                    (LITERAL_return (:text "return")
                      (IntIntConst (:text "1")))
                    (LITERAL_else (:text "else"))
                    (LITERAL_return (:text "return")
                      (IntIntConst (:text "2"))))
                  (LITERAL_if (:text "if")
                    (ID (:text "three"))
                    (LITERAL_if (:text "if")
                      (ID (:text "four"))
                      (LITERAL_return (:text "return")
                        (IntIntConst (:text "3")))
                      (LITERAL_else (:text "else"))
                      (LITERAL_if (:text "if")
                        (ID (:text "two"))
                        (LITERAL_return (:text "return")
                          (IntIntConst (:text "4")))
                        (LITERAL_else (:text "else"))
                        (LITERAL_if (:text "if")
                          (ID (:text "one"))
                          (LITERAL_return (:text "return") 

                            (IntIntConst (:text "42")))
                          (LITERAL_else (:text "else"))
                          (LITERAL_return (:text "return") 

                            (IntIntConst (:text "5"))))))
                    (LITERAL_else (:text "else"))
                    (LITERAL_if (:text "if")
                      (LAND (:text "&&")
                        (ID (:text "one"))
                        (ID (:text "two")))
                      (LITERAL_if (:text "if")
                        (ID (:text "three"))
                        (NCompoundStatement (:text "2")
                          (LITERAL_return (:text "return") 

                            (IntIntConst (:text "6"))))
                        (LITERAL_else (:text "else"))
                        (NCompoundStatement (:text "3")
                          (LITERAL_return (:text "return") 

                            (IntIntConst (:text "7")))))
                      (LITERAL_else (:text "else"))
                      (LITERAL_return (:text "return")
                        (IntIntConst (:text "8")))))))))))

:)

kenny
From: John Thingstad
Subject: Re: Translate this!
Date: 
Message-ID: <op.s28tsxtdpqzri1@mjolner.upc.no>
On Thu, 12 Jan 2006 02:22:15 +0100, Kenny Tilton  
<·············@nyc.rr.com> wrote:

hashtable..
seems the lispy way


-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Pascal Bourguignon
Subject: Re: Translate this!
Date: 
Message-ID: <87zmm25gmj.fsf@thalassa.informatimago.com>
Kenny Tilton <·············@nyc.rr.com> writes:

> Speaking of translating from C to Lisp, how would you like to see this
> artificial case translated?:
>
> int testif (int one, int two, int three, int four) {
> 	if (one)
> 		return 0;
> 	if (two)
> 		return 1;
> 	else
> 		return 2;
> 	if (three)
> 		if (four)
> 			return 3;
> 		else if (two)
> 			return 4;
> 		else
> 			return 5;
> 	else if (one && two)
> 		if (three) {
> 			return 6;
> 		} else {
> 			return 7;
> 		}
> 	else
> 		return 8;
> }
>
> I know, it does not make any sense, but the preprocessor does not know
> that so I can get output for the whole thing.

(defun testif (one two three four)
   (unless (zerop one) (return-from test-if 0))
   (if (zerop two)
       (return-from test-if 2)
       (return-from test-if 1)))

would be nice.       

(defun testif (one two three four)
   (cond ((not (zerop one)) 0)
         ((zerop two)       2)
         (t                 1)))

would be great.



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

ATTENTION: Despite any other listing of product contents found
herein, the consumer is advised that, in actuality, this product
consists of 99.9999999999% empty space.
From: Kenny Tilton
Subject: Re: Translate this!
Date: 
Message-ID: <p3kxf.257$qT.148@news-wrt-01.rdc-nyc.rr.com>
Pascal Bourguignon wrote:
> Kenny Tilton <·············@nyc.rr.com> writes:
> 
> 
>>Speaking of translating from C to Lisp, how would you like to see this
>>artificial case translated?:
>>
>>int testif (int one, int two, int three, int four) {
>>	if (one)
>>		return 0;
>>	if (two)
>>		return 1;
>>	else
>>		return 2;
>>	if (three)
>>		if (four)
>>			return 3;
>>		else if (two)
>>			return 4;
>>		else
>>			return 5;
>>	else if (one && two)
>>		if (three) {
>>			return 6;
>>		} else {
>>			return 7;
>>		}
>>	else
>>		return 8;
>>}
>>
>>I know, it does not make any sense, but the preprocessor does not know
>>that so I can get output for the whole thing.
> 
> 
> (defun testif (one two three four)
>    (unless (zerop one) (return-from test-if 0))
>    (if (zerop two)
>        (return-from test-if 2)
>        (return-from test-if 1)))

(a) I tried to warn everyone off looking at the semantics as a compiler 
might in collapsing code. My real code would not reduce like that, so I 
am going to KISS and go with literal translation. The only things I have 
done so far is sneak in WHEN for IF when correct, and reduce (progn 
<form>) to <form>. Thems are easy.

(b) As for ZEROP, <gasp> this is one place I think I will allow Lisp to 
creep in. Most of my code was not branching really on zero, it was 
branching on whether an object existed, and I do intend to use a /Lisp/ 
nil for that as I do a final manual pass through the code.

kenny
From: John Thingstad
Subject: Re: Translate this!
Date: 
Message-ID: <op.s28u8yq7pqzri1@mjolner.upc.no>
On Thu, 12 Jan 2006 03:23:16 +0100, Pascal Bourguignon  
<····@mouse-potato.com> wrote:


> (defun testif (one two three four)
>    (unless (zerop one) (return-from test-if 0))
>    (if (zerop two)
>        (return-from test-if 2)
>        (return-from test-if 1)))
>
> would be nice.
>
> (defun testif (one two three four)
>    (cond ((not (zerop one)) 0)
>          ((zerop two)       2)
>          (t                 1)))
>
> would be great.
>
>
>

??!

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Antonio Menezes Leitao
Subject: Re: Translate this!
Date: 
Message-ID: <87fyn4w3fm.fsf@gia.ist.utl.pt>
Kenny Tilton <·············@nyc.rr.com> writes:

> Speaking of translating from C to Lisp, how would you like to see this
> artificial case translated?:
>
> int testif (int one, int two, int three, int four) {
> 	if (one)
> 		return 0;
> 	if (two)
> 		return 1;
> 	else
> 		return 2;
> 	if (three)
> 		if (four)
> 			return 3;
> 		else if (two)
> 			return 4;
> 		else
> 			return 5;
> 	else if (one && two)
> 		if (three) {
> 			return 6;
> 		} else {
> 			return 7;
> 		}
> 	else
> 		return 8;
> }
>

Java and C have similar syntaxes so I tested your fragment with Jnil.
I had to change a datatype (ints become booleans) and remove the
obvious dead-code because that's not allowed in Java.

The modifed code is:

public int testif (boolean one, boolean two, boolean three, boolean four) {
	if (one)
		return 0;
	if (two)
		return 1;
	else
		System.err.println(2);
	if (three)
		if (four)
			return 3;
		else if (two)
			return 4;
		else
			return 5;
	else if (one && two)
		if (three) {
			return 6;
		} else {
			return 7;
		}
	else
		return 8;
}

Translating the result to Common Lisp using Jnil produces:

(defmethod testif ((this test0) one two three four)
  (when one
    (return-from testif 0))
  (if two
      (return-from testif 1)
    (princ 2 *error-output*))
  (cond (three
         (cond (four
                3)
               (two
                4)
               (t 5)))
        ((and one two)
         (cond (three
                6)
               (t 7)))
        (t 8)))

This seems to be similar to your #2 suggestion but avoiding unneded
return forms.

> #+option2
> ;; we have cond, use it! The Lisp Way, but is option1 more readable?
> (defun testif (one two three four)
>
>   (when one
>     (return-from testif 0))
>
>   (if two
>     (return-from testif 1)
>     (return-from testif 2))
>
>   (cond
>    (three (cond
>            (four (return-from testif 3))
>            (two (return-from testif 4))
>            (t (return-from testif 5))))
>    ((and one two)
>     (if three
>         (return-from testif 6)
>       (return-from testif 7)))
>    (t (return-from testif 8))))

Regards,

Ant�nio Leit�o.
From: John Thingstad
Subject: Re: Translate this!
Date: 
Message-ID: <op.s4aom0c9pqzri1@mjolner.upc.no>
On Tue, 31 Jan 2006 21:25:01 +0100, Antonio Menezes Leitao  
<···@aleph.local> wrote:

> Kenny Tilton <·············@nyc.rr.com> writes:
>
>> Speaking of translating from C to Lisp, how would you like to see this
>> artificial case translated?:
>>
>> int testif (int one, int two, int three, int four) {
>> 	if (one)
>> 		return 0;
>> 	if (two)
>> 		return 1;
>> 	else
>> 		return 2;
>> 	if (three)
>> 		if (four)
>> 			return 3;
>> 		else if (two)
>> 			return 4;
>> 		else
>> 			return 5;
>> 	else if (one && two)
>> 		if (three) {
>> 			return 6;
>> 		} else {
>> 			return 7;
>> 		}
>> 	else
>> 		return 8;
>> }
>>

Personally I think IF* is best here as it gives a near literal translation
(less work for you)

(defin testif (one two three four)
    (check-type one integer) ...
     (if* one then
        (return-from testif 1))
     (if* two  then
        (return-from testif 1)
      else
        (return-from testif 2))
   ...

Of course you would need to include the macro with C->LISP
for non-Allegro users.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: John Thingstad
Subject: Re: Translate this!
Date: 
Message-ID: <op.s4ao2a0ppqzri1@mjolner.upc.no>
On Wed, 01 Feb 2006 13:50:50 +0100, John Thingstad  
<··············@chello.no> wrote:

>
> Personally I think IF* is best here as it gives a near literal  
> translation
> (less work for you)
>
> (defin testif (one two three four)
>     (check-type one integer) ...
>      (if* one then
>         (return-from testif 1))
>      (if* two  then
>         (return-from testif 1)
>       else
>         (return-from testif 2))
>    ...
>
> Of course you would need to include the macro with C->LISP
> for non-Allegro users.
>

Ah I already see one problem.
In C "if one" is false if one is 0.
The equivalent in lisp is nil which the check-type would catch.
So the test would have to be (not (= one 0)) etc.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/