Python to FOCAL Compiler
10-05-2015, 10:58 PM
Post: #1
 Thomas Klemm Senior Member Posts: 1,447 Joined: Dec 2013
Python to FOCAL Compiler
Python Byte-Code

Ever since I noticed the similarity of the generated byte-code of a Python-program with a FOCAL program I wondered if this could be used to create programs for the HP-41C.
Let's start with an example that calculates the area of a circle with radius r:

Code:
def circle(r):     return pi * r ** 2

This will compile to byte-code which then can be disassembled:

Code:
  2           0 LOAD_GLOBAL              0 (pi)               3 LOAD_FAST                0 (r)               6 LOAD_CONST               1 (2)               9 BINARY_POWER                      10 BINARY_MULTIPLY                   11 RETURN_VALUE

The goal is to generate the following FOCAL-program:

Code:
LBL "CIRCLE" STO 00 ; r RDN PI RCL 00 ; r 2 Y↑X * RTN

Of course this can't work in general due to the limitations of the HP-41C. But nonetheless the results so far are promising:

Celsius to Fahrenheit conversion

Code:
def fahrenheit(celsius):     return 9 * celsius / 5 + 32

Code:
LBL "FAHRENH" STO 00 ; celsius RDN 9 RCL 00 ; celsius * 5 / 32 + RTN

But can we deal with complex expressions involving mathematical functions?

Spherical Law of Cosines

Code:
def spherical_law_of_cosines(a, C, b):     return acos(cos(a)*cos(b)+sin(a)*sin(b)*cos(C))

Code:
LBL "SPHERIC" STO 02 ; b RDN STO 01 ; C RDN STO 00 ; a RDN RCL 00 ; a COS RCL 02 ; b COS * RCL 00 ; a SIN RCL 02 ; b SIN * RCL 01 ; C COS * + ACOS RTN

Mach Number

Sometimes we have to rearrange the expression a little to avoid stack-overflow as with the famous formula for the mach number:

Code:
def mach():     # original: Sqrt(5*(((((1+.2*(350/661.5)^2)^3.5-1)*(1-6.875E-6*25500)^-5.2656)+1)^.286-1))     return sqrt((((((.2*(350/661.5)**2+1)**3.5-1)*(1-6.875E-6*25500)**-5.2656)+1)**.286-1)*5)

Code:
LBL "MACH" 0.2 350 661.5 / 2 Y↑X * 1 + 3.5 Y↑X 1 - 1 0.1753125 - -5.2656 Y↑X * 1 + 0.286 Y↑X 1 - 5 * SQRT RTN

You may notice that the result isn't exactly how it is solved in the HP-67 manual as the expression 6.875E-6*25500 is simplified to 0.1753125.

Or then we can avoid stack-overflow by using local variables.

Quadratic Equation

Code:
def qe(a, b, c):     p = b / a / -2     q = c / a     D = sqrt(p**2 - q)     return p + D, p - D

Code:
LBL "QE" STO 02 ; c RDN STO 01 ; b RDN STO 00 ; a RDN RCL 01 ; b RCL 00 ; a / -2 / STO 03 ; p RDN RCL 02 ; c RCL 00 ; a / STO 04 ; q RDN RCL 03 ; p 2 Y↑X RCL 04 ; q - SQRT STO 05 ; D RDN RCL 03 ; p RCL 05 ; D + RCL 03 ; p RCL 05 ; D - RTN

In some cases the RDN command after each STO command could be removed but not in all. Thus the generated code isn't optimized but that can easily be done manually to shave off a byte here and there.

Fizz Buzz

The famous simple coding interview question:

Code:
def fizbuz(n):     if n % 15 == 0:         print 'FIZZBUZZ'     elif n % 3 == 0:         print 'FIZZ'     elif n % 5 == 0:         print 'BUZZ'     else:         print n

Code:
LBL "FIZBUZ" STO 00 ; n RDN RCL 00 ; n 15 MOD 0 X#Y? GTO 00 "FIZZBUZZ" AVIEW GTO 03 LBL 00 RCL 00 ; n 3 MOD 0 X#Y? GTO 01 "FIZZ" AVIEW GTO 03 LBL 01 RCL 00 ; n 5 MOD 0 X#Y? GTO 02 "BUZZ" AVIEW GTO 03 LBL 02 RCL 00 ; n AVIEW LBL 03 RTN

A print statement is currently just mapped to the AVIEW command. But the last one should be VIEW X instead. I didn't come up with a simple solution for this but think this can easily be fixed manually. You may notice that all branches go to LBL 03 as a common exit-point. You can of course just use RTN instead.

Greatest Common Divisor

What about loops, you may wonder.

Code:
def gcd(a, b):     while b != 0:         a, b = b, a % b     return a

Code:
LBL "GCD" STO 01 ; b RDN STO 00 ; a RDN LBL 00 RCL 01 ; b 0 X=Y? GTO 01 RCL 01 ; b RCL 00 ; a RCL 01 ; b MOD X<>Y STO 00 ; a RDN STO 01 ; b RDN GTO 00 LBL 01 LBL 02 RCL 00 ; a RTN

While the code is correct we can certainly remove LBL 02 as it isn't used. And then there's no need to swap a and b before storing them. Of course we're far away from the optimized solution below but it might be a good starting point.

Code:
LBL "GCD" LBL 00 X=0? GTO 01 STO Z MOD GTO 00 LBL 01 RDN END

Conditionals

How would you translate the following conditional?

Code:
def conditional(n):     if 0 <= n and n < 13 or n % 3 == 0:         print 'FOUND'     else:         print 'NOT FOUND'

Isn't it nice that you can let the compiler do the hard work?

Code:
LBL "CONDITI" STO 00 ; n RDN 0 RCL 00 ; n X<Y? GTO 00 RCL 00 ; n 13 X>Y? GTO 01 LBL 00 RCL 00 ; n 3 MOD 0 X#Y? GTO 02 LBL 01 "FOUND" AVIEW GTO 03 LBL 02 "NOT FOUND" AVIEW LBL 03 RTN

Nested loop and break

This primitive program lists all prime factors of a given number:

Code:
def factor(n):     p = 2     while n > 1:         if p**2 > n:             print n             break         while n % p == 0:             print p             n /= p         p += 1

Here again we have to replace AVIEW by VIEW X:

Code:
LBL "FACTOR" STO 00 ; n RDN 2 STO 01 ; p RDN LBL 00 RCL 00 ; n 1 X>=Y? GTO 05 RCL 01 ; p 2 Y↑X RCL 00 ; n X>=Y? GTO 01 RCL 00 ; n AVIEW GTO 06 ; break GTO 01 LBL 01 LBL 02 RCL 00 ; n RCL 01 ; p MOD 0 X#Y? GTO 03 RCL 01 ; p AVIEW RCL 00 ; n RCL 01 ; p / STO 00 ; n RDN GTO 02 LBL 03 LBL 04 RCL 01 ; p 1 + STO 01 ; p RDN GTO 00 LBL 05 LBL 06 RTN

Mutual Inductunce of Coil Pair

This example stems from a recent thread:

Code:
def mutind(r, R, x):     m = 4*r*R/((R+r)**2+x**2)     k = sqrt(m)     K = EllipticF(m)     E = EllipticE(m)     return ((1-m/2)*K-E)*8*pi*1e-7*sqrt(r*R)/k

We assume that we can use functions to calculate the complete elliptic integrals. For this we have to add a customized mapping:

Code:
function = {     (...)     # custom     'EllipticE' : 'ELLIPE',     'EllipticF' : 'ELLIPF', }

The generated code has some similarities to the listing for the HP-67 in APPENDIX A:

Code:
LBL "MUTIND" STO 02 ; x RDN STO 01 ; R RDN STO 00 ; r RDN 4 RCL 00 ; r * RCL 01 ; R * RCL 01 ; R RCL 00 ; r + 2 Y↑X RCL 02 ; x 2 Y↑X + / STO 03 ; m RDN RCL 03 ; m SQRT STO 04 ; k RDN RCL 03 ; m ELLIPF STO 05 ; K RDN RCL 03 ; m ELLIPE STO 06 ; E RDN 1 RCL 03 ; m 2 / - RCL 05 ; K * RCL 06 ; E - 8 * PI * 1e-07 * RCL 00 ; r RCL 01 ; R * SQRT * RCL 04 ; k / RTN

Conclusions

There are some limitations:
• Runs only with Python 2.7.
• For-loop isn't supported.
• All functions use the same registers counting from 00.
• Recursion doesn't work.
• Probably a lot of things I'm not aware of.

It was fun to tinker a little with Python byte-code. I hope the result may be inspiring.

Kind regards
Thomas

Code:
Archive:  python_to_focal_compiler.zip   Length      Date    Time    Name ---------  ---------- -----   ----      5744  10-06-2015 00:01   compiler.py      1482  10-05-2015 23:40   examples.py      1951  10-05-2015 23:41   examples.hp ---------                     -------      9177                     3 files

To translate the examples in examples.py just run:

python compiler.py

The result is listed in examples.hp.

Attached File(s)
python_to_focal_compiler.zip (Size: 3.58 KB / Downloads: 21)
10-06-2015, 03:36 AM
Post: #2
 Sukiari Member Posts: 162 Joined: Dec 2014
RE: Python to FOCAL Compiler
This is incredible.

Now I need an HP-41CL!
10-06-2015, 05:50 AM
Post: #3
 Massimo Gnerucci Senior Member Posts: 2,354 Joined: Dec 2013
RE: Python to FOCAL Compiler
Thank you very much Thomas!

I will try to play with it a little.

Greetings,
Massimo

-+×÷ ↔ left is right and right is wrong
10-06-2015, 11:16 AM (This post was last modified: 10-06-2015 11:16 AM by Ángel Martin.)
Post: #4
 Ángel Martin Senior Member Posts: 1,255 Joined: Dec 2013
RE: Python to FOCAL Compiler
Thanks for this one, very well put together - as usual with your contribution Thomas! Maybe I should start using Python, this is a good incentive...

Dont mean to hijaak this thread but the attached code does the calculation of the mutual inductance example using the SandMath's versions of the eliptic integrals (see lines 28 and 32) - just thought it would be fun to try and sure enough works as advertised.

Code:
 01  LBL "MIND" 02  "R1=?" 03  PROMPT 04  STO 06 05  "R2=?" 06  PROMPT 07  STO 07 08  LBL 00 09  "d=?" 10  PROMPT 11  LBL C 12  STO 05 13  RCL 07 14  RCL 06 15  * 16  4 17  * 18  RCL 06 19  RCL 07 20  + 21  X^2 22  RCL 05 23  X^2 24  + 25  / 26  STO 05 27  90 28  ELIPF (SFL# 45) 29  STO 08 30  RCL 05 31  90 32  LEI2  (SFL# 46) 33  STO 09 34  E 35  RCL 05 36  2 37  / 38  - 39  RCL 08 40  * 41  RCL 09 42  - 43  PI 44  * 45  8 E-7 46  * 47  RCL 06 48  RCL 07 49  * 50  RCL 05 51  / 52  SQRT 53  * 54  "MI=" 55  ARCL X 56  PROMPT 57  GTO 00 58  END

I added the text prompts and an entry for repeat calculation at different distances. Should be obvious reading the examples in page 83 of the NASA document.

Cheers,
ÁM
10-06-2015, 03:58 PM
Post: #5
 Gerson W. Barbosa Senior Member Posts: 1,419 Joined: Dec 2013
RE: Python to FOCAL Compiler
(10-06-2015 11:16 AM)Ángel Martin Wrote:  Dont mean to hijaak this thread but the attached code does the calculation of the mutual inductance example using the SandMath's versions of the eliptic integrals (see lines 28 and 32) - just thought it would be fun to try and sure enough works as advertised.

Hola, Ángel, ¿Qué tal?

Wonderful work Thomas Klemm has done! Alas for me python is just a snake. Basic to FOCAL or Pascal to FOCAL would be great, but who cares about these archaic programming languages (going dead?) nowadays?
I don't mean to hijack this thread either, but since you've talked about elliptic integrals and you appear to be in the mood, what about converting the fast algorithm presented by Hugh Steers here to RPN? I should have done this already, but I left it aside for some reason. Perhaps it might be easier from the BASIC version (it's MSX BASIC, where all variables are double precision by default). The FreePascal version was intended to the RPL conversion, which I haven't done yet either.

Thanks,

Gerson.

Code:
 10 CLS 15 INPUT "A, B "; A,B 20 W=A 25 B=B/A: S=(1+B*B)/2: A=1: T=1 30 A1=(A+B)/2 35 IF A=A1 THEN 65 40 C=(A-B)/2 45 B=SQR(A*B) 50 A=A1 55 S=S-T*C*C: T=T+T 60 GOTO 30 65 PI=4*ATN(1) 70 PRINT 2*W*PI*S/A

Code:
 Program Ellipse;                                                                 Uses Crt;                                                                        const PI = 3.14159265358979324;                                                  var a, a1, b, c, s, t, w: double;                                                begin                                                                              ClrScr;                                                                          Write('a b: ');                                                                  ReadLn(a, b);                                                                    w := a;                                                                          b := b/a;                                                                        s := (1 + b*b)/2;                                                                a := 1;                                                                          t := 1;                                                                          repeat                                                                             a1 := (a + b)/2;                                                                 c := (a - b)/2;                                                                  b := Sqrt(a*b);                                                                  a := a1;                                                                         s := s - t*c*c;                                                                  t := t + t                                                                     until c = 0;    WriteLn(2*w*PI*s/a:22:16);                                                       ReadKey;                                                                       end.
10-06-2015, 07:11 PM (This post was last modified: 10-06-2015 07:15 PM by Thomas Klemm.)
Post: #6
 Thomas Klemm Senior Member Posts: 1,447 Joined: Dec 2013
RE: Python to FOCAL Compiler
(10-06-2015 03:58 PM)Gerson W. Barbosa Wrote:  I don't mean to hijack this thread either, but since you've talked about elliptic integrals and you appear to be in the mood, what about converting the fast algorithm presented by Hugh Steers here to RPN?

Here's a Python program based on Hugh's implementation:

Code:
def ellipse(a, b):     u = 1     v = b / a     s = (1 + v**2)/2     t = 1     while 0 == 0:         m = (u + v)/2         if m == u:             break         w = (u - v)/2         v = sqrt(u * v)         u = m         s = s - t * w**2         t = t * 2     return 2 * pi * a * s / u

And that's the generated FOCAL program using 113 bytes:

Code:
LBL "ELLIPSE" STO 01 ; b RDN STO 00 ; a RDN 1 STO 02 ; u RDN RCL 01 ; b RCL 00 ; a / STO 03 ; v RDN 1 RCL 03 ; v 2 Y↑X + 2 / STO 04 ; s RDN 1 STO 05 ; t RDN LBL 00 0 0 X#Y? GTO 02 RCL 02 ; u RCL 03 ; v + 2 / STO 06 ; m RDN RCL 06 ; m RCL 02 ; u X#Y? GTO 01 GTO 03 ; break GTO 01 LBL 01 RCL 02 ; u RCL 03 ; v - 2 / STO 07 ; w RDN RCL 02 ; u RCL 03 ; v * SQRT STO 03 ; v RDN RCL 06 ; m STO 02 ; u RDN RCL 04 ; s RCL 05 ; t RCL 07 ; w 2 Y↑X * - STO 04 ; s RDN RCL 05 ; t 2 * STO 05 ; t RDN GTO 00 LBL 02 LBL 03 2 PI * RCL 00 ; a * RCL 04 ; s * RCL 02 ; u / RTN

But we can easily bring this down to 77 bytes:

Code:
LBL "ELLIPSE" STO 01 ; b RDN STO 00 ; a 1 STO 02 ; u STO 05 ; t RCL 01 ; b RCL 00 ; a / STO 03 ; v X↑2 + 2 / STO 04 ; s LBL 00 RCL 02 ; u RCL 03 ; v + 2 / STO 06 ; m RCL 02 ; u X=Y? GTO 03 ; break RCL 02 ; u RCL 03 ; v - 2 / STO 07 ; w RCL 02 ; u RCL 03 ; v * SQRT STO 03 ; v RCL 06 ; m STO 02 ; u RCL 05 ; t RCL 07 ; w X↑2 * ST- 04 ; s 2 ST* 05 ; t GTO 00 LBL 03 2 PI * RCL 00 ; a * RCL 04 ; s * RCL 02 ; u / RTN

Kind regards
Thomas

PS: We can't use True in conditions as there's no corresponding comparison operator in the HP-41C. That's why I used 0 == 0 instead in the while-loop. The generated code could then be removed in the optimized variant of the program:

Code:
0 0 X#Y? GTO 02
10-06-2015, 07:55 PM (This post was last modified: 10-06-2015 08:09 PM by Thomas Klemm.)
Post: #7
 Thomas Klemm Senior Member Posts: 1,447 Joined: Dec 2013
RE: Python to FOCAL Compiler
(10-06-2015 11:16 AM)Ángel Martin Wrote:  Maybe I should start using Python, this is a good incentive...

You can use Python in your browser if you don't have access to an installation: Python to FOCAL Compiler

Just run the program and the function gcd will be translated. You can create your own functions either in the listing on the left (but then you have to run the program again) or then directly in the REPL in the right window.

You can translate a function to FOCAL:
Code:
>>> translate(gcd.__code__) LBL "GCD" STO 01 ; b RDN STO 00 ; a RDN LBL 00 RCL 01 ; b 0 X=Y? GTO 01 RCL 01 ; b RCL 00 ; a RCL 01 ; b MOD X<>Y STO 00 ; a RDN STO 01 ; b RDN GTO 00 LBL 01 LBL 02 RCL 00 ; a RTN

And then you can compare it with the disassembled byte-code:
Code:
>>> dis.dis(gcd)  27           0 SETUP_LOOP              33 (to 36)         >>    3 LOAD_FAST                1 (b)               6 LOAD_CONST               1 (0)               9 COMPARE_OP               3 (!=)              12 POP_JUMP_IF_FALSE       35  28          15 LOAD_FAST                1 (b)              18 LOAD_FAST                0 (a)              21 LOAD_FAST                1 (b)              24 BINARY_MODULO              25 ROT_TWO              26 STORE_FAST               0 (a)              29 STORE_FAST               1 (b)              32 JUMP_ABSOLUTE            3         >>   35 POP_BLOCK  29     >>   36 LOAD_FAST                0 (a)              39 RETURN_VALUE

Of course you can also just use a function:
Code:
>>> gcd(91, 35) 7 >>> factor(5040) 2 2 2 2 3 3 5 7

Cheers
Thomas
10-06-2015, 08:19 PM (This post was last modified: 10-07-2015 01:41 AM by Gerson W. Barbosa.)
Post: #8
 Gerson W. Barbosa Senior Member Posts: 1,419 Joined: Dec 2013
RE: Python to FOCAL Compiler
(10-06-2015 07:11 PM)Thomas Klemm Wrote:  [quote='Gerson W. Barbosa' pid='43596' dateline='1444147083']
I don't mean to hijack this thread either, but since you've talked about elliptic integrals and you appear to be in the mood, what about converting the fast algorithm presented by Hugh Steers here to RPN?

Here's a Python program based on Hugh's implementation:

Code:
def ellipse(a, b):     u = 1     v = b / a     s = (1 + v**2)/2     t = 1     while 0 == 0:         m = (u + v)/2         if m == u:             break         w = (u - v)/2         v = sqrt(u * v)         u = m         s = s - t * w**2         t = t * 2     return 2 * pi * a * s / u

And that's the generated FOCAL program using 113 bytes:

Code:
LBL "ELLIPSE" STO 01 ; b RDN STO 00 ; a RDN 1 STO 02 ; u RDN RCL 01 ; b RCL 00 ; a / STO 03 ; v RDN 1 RCL 03 ; v 2 Y↑X + 2 / STO 04 ; s RDN 1 STO 05 ; t RDN LBL 00 0 0 X#Y? GTO 02 RCL 02 ; u RCL 03 ; v + 2 / STO 06 ; m RDN RCL 06 ; m RCL 02 ; u X#Y? GTO 01 GTO 03 ; break GTO 01 LBL 01 RCL 02 ; u RCL 03 ; v - 2 / STO 07 ; w RDN RCL 02 ; u RCL 03 ; v * SQRT STO 03 ; v RDN RCL 06 ; m STO 02 ; u RDN RCL 04 ; s RCL 05 ; t RCL 07 ; w 2 Y↑X * - STO 04 ; s RDN RCL 05 ; t 2 * STO 05 ; t RDN GTO 00 LBL 02 LBL 03 2 PI * RCL 00 ; a * RCL 04 ; s * RCL 02 ; u / RTN

But we can easily bring this down to 77 bytes:

Code:
LBL "ELLIPSE" STO 01 ; b RDN STO 00 ; a 1 STO 02 ; u STO 05 ; t RCL 01 ; b RCL 00 ; a / STO 03 ; v X↑2 + 2 / STO 04 ; s LBL 00 RCL 02 ; u RCL 03 ; v + 2 / STO 06 ; m RCL 02 ; u X=Y? GTO 03 ; break RCL 02 ; u RCL 03 ; v - 2 / STO 07 ; w RCL 02 ; u RCL 03 ; v * SQRT STO 03 ; v RCL 06 ; m STO 02 ; u RCL 05 ; t RCL 07 ; w X↑2 * ST- 04 ; s 2 ST* 05 ; t GTO 00 LBL 03 2 PI * RCL 00 ; a * RCL 04 ; s * RCL 02 ; u / RTN

Thank you very much for the HP-41 programs!

As a compensation for my laziness, here is a 163-byte RPL stack-only version of the Pascal program, if you don't mind the off-topic content:

Code:
 %%HP: T(3)A(D)F(.); \<< OVER / DUP SQ 1. + 2. / 1. ROT 1.   DO DUP2 DUP2 * \v/ UNROT - 2. / 4. ROLLD UNROT + 2. / 4. ROLL 4. ROLL DUP2 SQ * NEG 6. ROLL + ROT DUP + SWAP 5. ROLLD 4. ROLLD ABS   UNTIL .00000000001 <   END UNROT DROP2 / * DUP + \pi * \>>

RPL masters might shorten this a bit and do more elegant stack manipulations. It's not an exact implementation of Hugh's algorithm because there is no break from RPL structures.

Best regards,

Gerson .

P.S.: Just tested your second program on my HP-41CV (because it's shorter). Very fast! (less than 5 seconds!). Thanks again!

Edited to add a missing s lest I am given a free grammar lesson :-)
10-06-2015, 08:28 PM
Post: #9
 Thomas Klemm Senior Member Posts: 1,447 Joined: Dec 2013
RE: Python to FOCAL Compiler
(10-06-2015 03:58 PM)Gerson W. Barbosa Wrote:  Basic to FOCAL or Pascal to FOCAL would be great

This HP-41C program compiles BASIC to FOCAL.
10-07-2015, 01:47 AM
Post: #10
 Gerson W. Barbosa Senior Member Posts: 1,419 Joined: Dec 2013
RE: Python to FOCAL Compiler
(10-06-2015 08:28 PM)Thomas Klemm Wrote:
(10-06-2015 03:58 PM)Gerson W. Barbosa Wrote:  Basic to FOCAL or Pascal to FOCAL would be great

This HP-41C program compiles BASIC to FOCAL.

It looks interesting, but it won't take a BASIC source code in text format and return a FOCAL listing, like yours. Easier to learn Python :-)

Regards,

Gerson.
10-07-2015, 04:34 AM
Post: #11
 Thomas Klemm Senior Member Posts: 1,447 Joined: Dec 2013
RE: Python to FOCAL Compiler
(10-07-2015 01:47 AM)Gerson W. Barbosa Wrote:  Easier to learn Python :-)

My recommendation is: Learn Python the Hard Way

Quote:Do Not Copy-Paste
You must type each of these exercises in, manually. If you copy and paste, you might as well not even do them. The point of these exercises is to train your hands, your brain, and your mind in how to read, write, and see code. If you copy-paste, you are cheating yourself out of the effectiveness of the lessons.

Cheers
Thomas
10-07-2015, 05:38 AM
Post: #12
 Massimo Gnerucci Senior Member Posts: 2,354 Joined: Dec 2013
RE: Python to FOCAL Compiler
(10-07-2015 04:34 AM)Thomas Klemm Wrote:
Quote:Do Not Copy-Paste
You must type each of these exercises in, manually. If you copy and paste, you might as well not even do them. The point of these exercises is to train your hands, your brain, and your mind in how to read, write, and see code. If you copy-paste, you are cheating yourself out of the effectiveness of the lessons.

Cheers
Thomas

Ach! You copy-pasted this from the intro! ;)

Greetings,
Massimo

-+×÷ ↔ left is right and right is wrong
10-07-2015, 04:38 PM
Post: #13
 Thomas Klemm Senior Member Posts: 1,447 Joined: Dec 2013
Java to FOCAL Compiler
(10-06-2015 03:58 PM)Gerson W. Barbosa Wrote:  what about converting the fast algorithm presented by Hugh Steers here to RPN?

Since the Java-VM is a stack-machine too we can do a similar thing with the generated byte-code. The original C-code can be used without major changes:

Code:
class Compiler {      double ellipse(double a, double b) {         double u = 1;         double v = b/a;         double s = (1 + v*v)/2;         double t = 1;         for (;;) {             double a1 = (u + v)/2;             if (u == a1)                 break;             double c = (u - v)/2;             v = Math.sqrt(u*v);             u = a1;             s = s - t*c*c;             t = t * 2;         }         return 2*Math.PI*a*s/u;     } }

We compile this to a class-file and use javap to disassemble the code:

javac Compiler.java
javap -c Compiler

This is what we get:
Code:
Compiled from "Compiler.java"                                         class Compiler {   Compiler();     Code:        0: aload_0        1: invokespecial #1                  // Method java/lang/Object."<init>":()V        4: return   double ellipse(double, double);     Code:        0: dconst_1        1: dstore        5        3: dload_3        4: dload_1        5: ddiv        6: dstore        7        8: dconst_1        9: dload         7       11: dload         7       13: dmul       14: dadd       15: ldc2_w        #2                  // double 2.0d       18: ddiv       19: dstore        9       21: dconst_1       22: dstore        11       24: dload         5       26: dload         7       28: dadd       29: ldc2_w        #2                  // double 2.0d       32: ddiv       33: dstore        13       35: dload         5       37: dload         13       39: dcmpl       40: ifne          46       43: goto          95       46: dload         5       48: dload         7       50: dsub       51: ldc2_w        #2                  // double 2.0d       54: ddiv       55: dstore        15       57: dload         5       59: dload         7       61: dmul       62: invokestatic  #4                  // Method java/lang/Math.sqrt:(D)D       65: dstore        7       67: dload         13       69: dstore        5       71: dload         9       73: dload         11       75: dload         15       77: dmul       78: dload         15       80: dmul       81: dsub       82: dstore        9       84: dload         11       86: ldc2_w        #2                  // double 2.0d       89: dmul       90: dstore        11       92: goto          24       95: ldc2_w        #5                  // double 6.283185307179586d       98: dload_1       99: dmul      100: dload         9      102: dmul      103: dload         5      105: ddiv      106: dreturn }

Since a double occupies two registers only odd indexes are used. But we can still see the similarities to the generated FOCAL program using Python. Thus we could probably generate FOCAL programs from class-files as well.

Kind regards
Thomas
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)