Python to FOCAL Compiler
|
10-05-2015, 10:58 PM
Post: #1
|
|||
|
|||
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): This will compile to byte-code which then can be disassembled: Code: 2 0 LOAD_GLOBAL 0 (pi) The goal is to generate the following FOCAL-program: Code: LBL "CIRCLE" 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): Code: LBL "FAHRENH" But can we deal with complex expressions involving mathematical functions? Spherical Law of Cosines Code: def spherical_law_of_cosines(a, C, b): Code: LBL "SPHERIC" 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(): Code: LBL "MACH" 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): Code: LBL "QE" 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): Code: LBL "FIZBUZ" 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): Code: LBL "GCD" 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" Conditionals How would you translate the following conditional? Code: def conditional(n): Isn't it nice that you can let the compiler do the hard work? Code: LBL "CONDITI" Nested loop and break This primitive program lists all prime factors of a given number: Code: def factor(n): Here again we have to replace AVIEW by VIEW X: Code: LBL "FACTOR" Mutual Inductunce of Coil Pair This example stems from a recent thread: Code: def mutind(r, R, x): We assume that we can use functions to calculate the complete elliptic integrals. For this we have to add a customized mapping: Code: function = { The generated code has some similarities to the listing for the HP-67 in APPENDIX A: Code: LBL "MUTIND" Conclusions There are some limitations:
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 To translate the examples in examples.py just run: python compiler.py The result is listed in examples.hp. |
|||
10-06-2015, 03:36 AM
Post: #2
|
|||
|
|||
RE: Python to FOCAL Compiler
This is incredible.
Now I need an HP-41CL! |
|||
10-06-2015, 05:50 AM
Post: #3
|
|||
|
|||
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
|
|||
|
|||
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:
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 "To live or die by your own sword one must first learn to wield it aptly." |
|||
10-06-2015, 03:58 PM
Post: #5
|
|||
|
|||
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:
Code:
|
|||
10-06-2015, 07:11 PM
(This post was last modified: 10-06-2015 07:15 PM by Thomas Klemm.)
Post: #6
|
|||
|
|||
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): And that's the generated FOCAL program using 113 bytes: Code: LBL "ELLIPSE" But we can easily bring this down to 77 bytes: Code: LBL "ELLIPSE" 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 |
|||
10-06-2015, 07:55 PM
(This post was last modified: 10-06-2015 08:09 PM by Thomas Klemm.)
Post: #7
|
|||
|
|||
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__) And then you can compare it with the disassembled byte-code: Code: >>> dis.dis(gcd) Of course you can also just use a function: Code: >>> gcd(91, 35) 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
|
|||
|
|||
RE: Python to FOCAL Compiler
(10-06-2015 07:11 PM)Thomas Klemm Wrote: [quote='Gerson W. Barbosa' pid='43596' dateline='1444147083'] Here's a Python program based on Hugh's implementation: Code: def ellipse(a, b): And that's the generated FOCAL program using 113 bytes: Code: LBL "ELLIPSE" But we can easily bring this down to 77 bytes: Code: LBL "ELLIPSE" 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:
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
|
|||
|
|||
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
|
|||
|
|||
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 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
|
|||
|
|||
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 Cheers Thomas |
|||
10-07-2015, 05:38 AM
Post: #12
|
|||
|
|||
RE: Python to FOCAL Compiler
(10-07-2015 04:34 AM)Thomas Klemm Wrote:Quote:Do Not Copy-Paste 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
|
|||
|
|||
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 { 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" 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: 5 Guest(s)