Re: Lex, Yacc, and Lisp...



Ulrich Hobelmann <u.hobelmann@xxxxxx> writes:
> Translating code as it is should be enough if the target language
> allows low-level code to be written (I think CL does to a reasonable
> degree). Maybe the biggest problem would be performance of array
> accesses due to bounds-checks, but that's no worse than Java.

This would be the easiest. The biggest problem would be the
greenspuning when "translating" CL to C, and the usual bugs when
"translating" C to CL. Some kind of inverse greenspuning. For
example, when you see unsigned int x; {x++;}, you cannot translate to
(incf x), you have to do it bug for bug, and translate to:
(setf x (mod (1+ x) (expt 2 32)))

How do you "translate":
(defun fact (x) (if (< 1 x) (* x (fact (1- x))) 1))
to C?
int fact(int x){if(1<x){return(x*fact(x-1));}else{return(1);}}
is plain wrong.

[70]> (fact 12.34)
1.2730496E9
[71]> (fact 100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000



On the other hand, to implement:

[pjb@thalassa pjb]$ cat fact.c
#include <stdio.h>
int fact(int x){if(1<x){return(x*fact(x-1));}else{return(1);}}
int main(void){int i;for(i=0;i<30;i++){printf("%d!=%d\n",i,fact(i));}return(0);}
[pjb@thalassa pjb]$ gcc -o fact fact.c
[pjb@thalassa pjb]$ ./fact
0!=1
1!=1
2!=2
3!=6
4!=24
5!=120
6!=720
7!=5040
8!=40320
9!=362880
10!=3628800
11!=39916800
12!=479001600
13!=1932053504
14!=1278945280
15!=2004310016
16!=2004189184
17!=-288522240
18!=-898433024
19!=109641728
20!=-2102132736
21!=-1195114496
22!=-522715136
23!=862453760
24!=-775946240
25!=2076180480
26!=-1853882368
27!=1484783616
28!=-1375731712
29!=-1241513984
[pjb@thalassa pjb]$


You have to write:

(defun c2*32 (x y) ;; inverse greenspuning
(let ((p (logand (1- (expt 2 32)) (* x y))))
(if (<= (expt 2 31) p)
(- p (expt 2 32))
p)))

(defun c-fact (x)
(declare (type x (integer (- (expt 2 31)) (1- (expt 2 31)))))
(if (< 1 x)
(c2*32 x (fact (1- x) #|we've infered that x>-2^31|#))
1))


(defun main ()
(loop for i from 0 below 30 do (format t "~D!=~D~%" i (c-fact i)))
0)


[91]> (main)
0!=1
1!=1
2!=2
3!=6
4!=24
5!=120
6!=720
7!=5040
8!=40320
9!=362880
10!=3628800
11!=39916800
12!=479001600
13!=1932053504
14!=1278945280
15!=2004310016
16!=2004189184
17!=-288522240
18!=-898433024
19!=109641728
20!=-2102132736
21!=-1195114496
22!=-522715136
23!=862453760
24!=-775946240
25!=2076180480
26!=-1853882368
27!=1484783616
28!=-1375731712
29!=-1241513984
0


--
__Pascal Bourguignon__ http://www.informatimago.com/
The rule for today:
Touch my tail, I shred your hand.
New rule tomorrow.
.



Relevant Pages

  • Re: Lex, Yacc, and Lisp...
    ... >> Translating code as it is should be enough if the target language ... Maybe the biggest problem would be performance of array ... >, you have to do it bug for bug, and translate to: ... package with Lisp implementations of all C primitives. ...
    (comp.lang.lisp)
  • Re: Lex, Yacc, and Lisp...
    ... >> Translating code as it is should be enough if the target language ... >, you have to do it bug for bug, and translate to: ... also illustrates why Lisp gives higher programmer productivity than C. ...
    (comp.lang.lisp)
  • Re: Can anyone translate English to Aramaic?
    ... > between two languages, or computers would be able to do translating. ... > in a Hebrew or Syriac font and those are the characters they ... > The biggest problem, as I also indicated, is that you want to talk about ...
    (sci.lang)
  • Re: Bug in testing abiword package?
    ... > immediatedly because (unfortunately I'm translating from Italian into ... > found a bug or there's something I can't catch? ...
    (Debian-User)