Post Reply 
Python to RPN converter
02-19-2018, 02:29 AM
Post: #21
RE: Python to RPN converter
(02-17-2018 02:33 PM)rprosperi Wrote:  At least half the members here prefer RPN over RPL.

Thanks for the memories.

My first programming "experience" was RPN - and I learned from the books that came with the HP-41. loved it.
Eventually, I bought a 48. Hated RPL.

To this day, I still don't know whether to blame RPL itself, or the documentation that came with the HP-48.
Find all posts by this user
Quote this message in a reply
02-19-2018, 02:54 AM
Post: #22
RE: Python to RPN converter
(02-19-2018 02:29 AM)sa-penguin Wrote:  
(02-17-2018 02:33 PM)rprosperi Wrote:  At least half the members here prefer RPN over RPL.

Thanks for the memories.

My first programming "experience" was RPN - and I learned from the books that came with the HP-41. loved it.
Eventually, I bought a 48. Hated RPL.

To this day, I still don't know whether to blame RPL itself, or the documentation that came with the HP-48.

I have figured out the perfect response when somebody asks me if I prefer RPN or RPL HPs:

"How about that sweet 71b! What a BASIC!"
Find all posts by this user
Quote this message in a reply
02-19-2018, 06:27 AM
Post: #23
RE: Python to RPN converter
(02-19-2018 02:54 AM)polbit Wrote:  "How about that sweet 71b! What a BASIC!"

Not blasphemy - must be heresy.
Find all posts by this user
Quote this message in a reply
02-19-2018, 07:16 AM (This post was last modified: 02-19-2018 07:25 AM by StephenG1CMZ.)
Post: #24
RE: Python to RPN converter
Tcab, I am puzzled when you ask for source code without the line numbers "that I added".
Those line numbers are actually part of your original demo, and were not deleted after pasting here Smile


Attached File(s) Thumbnail(s)
   

Stephen Lewkowicz (G1CMZ)
Visit this user's website Find all posts by this user
Quote this message in a reply
02-19-2018, 07:29 AM
Post: #25
RE: Python to RPN converter
Ah I see what might have happened with your copy paste fragment getting those strange line numbers... Python of course has no line numbers, but there are indeed line numbers in the margin of the Python editor (like in most programming editors) but they are not part of the source code and usually impossible to copy out - at least in desktop browsers and iOS browsers. Somehow you managed to select them and copy them!

It might better to use a desktop browser to become familiar with the site - I haven't tested the site under android yet sorry.
Find all posts by this user
Quote this message in a reply
02-19-2018, 07:48 AM
Post: #26
RE: Python to RPN converter
Its only on this forum the line numbers combine with the source - Convert didn't complain until line 7 of my demo2 so I guess wasn't seeing the line numbers.

Right now, I only have Android available - the PC needs fixing.
Thanks for your help.

Stephen Lewkowicz (G1CMZ)
Visit this user's website Find all posts by this user
Quote this message in a reply
02-19-2018, 08:17 AM
Post: #27
RE: Python to RPN converter
No worries. I've gone ahead and implemented a Clear button and a New Project link - as well as removing the initial demo code from the converter.

Other features released today include a new LBL main start point for programs, allowing access to the Python global scope area - great for sharing variables between functions. Programs written with this paradigm are likely to be more appealing to RPN programmers and look like:
Code:

LBL("main")

length = 10
width = 20

report()

def report():
  print('length is', length, '[LF]width is', width)

Variable references now look outwards from functions into their outer functions (if any)... all the way to global scope - until they find the variable. This is how nested scope works in most programming languages, including Python. Read all about scope in the help file.

Other features released today are the ability to edit and delete cloned example snippets, as well as vote on them. A new simplified menu() command has been added - there are a couple of examples showing how you can rapidly build custom menus and submenus.
Find all posts by this user
Quote this message in a reply
02-19-2018, 11:15 AM
Post: #28
RE: Python to RPN converter
Would be interesting to see how "optimized" is the code generated by the converter (that is not a primary objective here, it is already great to get a conversion).

For example with a summation: http://www.hpmuseum.org/forum/thread-9750.html

Or some array work: http://www.hpmuseum.org/cgi-sys/cgiwrap/...i?read=700

From the last one the code for the dm42 is
Code:

LBL A   CLRG
         8 STO 11
 LBL 00  RCL 00 RCL 11
         X=Y? GTO 04
         ISG 00 DEG
         STO IND 00
 LBL 01  ISG 10 DEG
         RCL 00 STO 09
 LBL 02  DSE 09 DEG
         RCL 09 X=0? GTO 00
         RCL IND 00 RCL IND 09 -
         X=0? GTO 03
         ABS RCL 00 RCL 09 -
         X<>Y? GTO 02
 LBL 03  DSE IND 00 GTO 01
         DSE 00 GTO 03
 LBL 04  RCL 10
         RTN

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
02-19-2018, 07:36 PM
Post: #29
RE: Python to RPN converter
Thanks Tcab, that new UI is now usable on Android...much better.

Stephen Lewkowicz (G1CMZ)
Visit this user's website Find all posts by this user
Quote this message in a reply
02-20-2018, 02:28 PM (This post was last modified: 02-20-2018 02:43 PM by StephenG1CMZ.)
Post: #30
RE: Python to RPN converter
I have a couple of queries, which may be obvious to anyone that has used HP42 before.

First, with any code formatted like this, I am finding that the converted code starts with a label followed by a RTN. I seem to have to delete the RTN for the program to execute.

I presume I am doing something wrong. I tried moving the LBL but so far without success.

Second, if I include LOCAT() in the source, I get a Label Not Found error executing the program.
I guess that means free42's LOCAT is not available to Python.
I am sure there must be some way of using it, but being new to the 42 I haven't yet figured it out.
I tried creating LOC8 which called LOCAT, but haven't figured out the 42 usage yet.
Code:



LBL("H1")

def Here():
  Lat=42
  Lon=24
  Lat,Lon,Elv,XX=LOC8()
  print('Lat',Lat,'Lon',Lon,'Elv',Elv)
  AVIEW()
I am using free42 and Android.

Stephen Lewkowicz (G1CMZ)
Visit this user's website Find all posts by this user
Quote this message in a reply
02-20-2018, 10:39 PM (This post was last modified: 02-20-2018 11:43 PM by tcab.)
Post: #31
RE: Python to RPN converter
The reason your program is not running when you call "H1" is that it is not calling the "Here" function. You have to call Python functions to run them. So your code should be:
Code:

LBL("H1")
Here()

def Here():
  Lat=42
  Lon=24
  Lat,Lon,Elv,XX=LOC8()
  print('Lat',Lat,'Lon',Lon,'Elv',Elv)
  AVIEW()

Another way to write this is to get rid of the LBL and simply
Code:

def Here():
  Lat=42
  Lon=24
  Lat,Lon,Elv,XX=LOC8()
  print('Lat',Lat,'Lon',Lon,'Elv',Elv)
  AVIEW()
in which case the first function name becomes the RPN global label "Here", and you can execute that from your calculator.

Or you can even run your code in the global namespace like this:
Code:

LBL("H1")

Lat=42
Lon=24
Lat,Lon,Elv,XX=LOC8()
print('Lat',Lat,'Lon',Lon,'Elv',Elv)
AVIEW()

As for your calls to LOCAT and LOC8 - they are not defined anywhere and don't exist on the HP42S (see cmd reference) and so are being converted to local label calls starting with single letters e.g. XEQ B - which won't exist if you try to run the code.

Finally - a small point - you don't need the AVIEW after the print() because print() already generates an AVIEW for you. See the section on text and the alpha register in the help page.
Find all posts by this user
Quote this message in a reply
06-01-2018, 01:39 AM
Post: #32
RE: Python to RPN converter
Very nice work!
Find all posts by this user
Quote this message in a reply
06-23-2018, 10:33 PM
Post: #33
RE: Python to RPN converter
Some time ago I wrote this Python to FOCAL Compiler.

This Python program calculates the greatest common divisor of two integers a and b:
Code:
def gcd(a, b):
    while b != 0:
        a, b = b, a % b
    return a

It gets translated to:
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

The generated code by your website is similar but a bit longer:
Code:
LBL "gcd"
XEQ 65          // reorder 2 params for storage
STO 00          // param: a
RDN
STO 01          // param: b
RDN
LBL 00          // while
RCL 01          // b
0
XEQ 86          // compare, return bool
X≠0?            // while true?
GTO 01          // while body
GTO 02          // resume
LBL 01          // while body
RCL 01          // b
RCL 00          // a
RCL 01          // b
MOD
STO 01          // b 
RDN
STO 00          // a 
GTO 00          // while
LBL 02          // resume
RCL 00          // a
RTN             // return
LBL 50          // PyRPN Support Library of
"-Utility Funcs-"
RTN             // ---------------------------
LBL 65          // Reverse params. (a,b) -> (b,a)
X<>Y
RTN
LBL 86          // != (y:a, x:b) -> boolean of a != b
CF 00
X≠Y?
SF 00
XEQ 61
RTN
LBL 61          // Util used by comparison ops. (a,b) -> (boolean) - whether flag 00 is set, plus RDNs
RDN
RDN             // params dropped
FS? 00
1
FC? 00
0
RTN

My program relies on the generated byte-code that has some resemblance to FOCAL since Python uses a stack-machine to interpret it. So it was never more than a quick and dirty hacked together proof of concept. Nothing compared to your listed capabilities. Still I was pleased with the result.

It appears that both implementations don't support recursion as in this case:
Code:
def gcd(a, b):
    return a if b == 0 else gcd(b, a % b)

Just out of curiosity: Does your program rely on the Python compiler as well or did you write one on your own?
Find all posts by this user
Quote this message in a reply
06-24-2018, 10:56 PM
Post: #34
RE: Python to RPN converter
Hi Thomas,

How interesting that you built something similar! You program scans Python generated Bytecode whilst my program works earlier in the pipeline, at the AST stage:

[Image: hacking-python-asts-pycon-de-2017-suhas-...1513846800]

So yes, my program does rely on the Python compiler. Specifically my approach has been to use Python's built in ability to parse itself into an AST Abstract Syntax Tree, then to traverse this tree using the visitor design pattern to generate the RPN.

For example, the following Python code:
Code:
import ast
import astunparse
print(astunparse.dump(ast.parse('x = 1 + 2')))
will generate the following AST data structure representing x = 1 + 2:
Code:
Module(body=[Assign(
  targets=[Name(
    id='x',
    ctx=Store())],
  value=BinOp(
    left=Num(n=1),
    op=Add(),
    right=Num(n=2)))])

If you are interested, here are the slides of a recent talk I gave to a local Python User Group in Melbourne, Australia, about how I used the Python AST capabilities to build the Python to Rpn converter. The reception to the talk was good, but became fun and buoyant once the audience realised I had targeted an old HP calculator with this fancy Python technology - especially when I pulled out my HP calcs for all to see and touch.

-Andy Bulka
Find all posts by this user
Quote this message in a reply
06-25-2018, 07:13 AM
Post: #35
RE: Python to RPN converter
Hi all,

Reading this thread reactivated an idea I had but never had the courage to implement: build the algebraic equation parser and solver from the HP-27S into the 42S.

Since Thomas won't build this kind of far-off feature in free42, the only way to do it... is FOCAL. While in theory FOCAL is Turing-complete and should be able to implement anything, especially with the virtually unlimited speed and memory of Free42, in practice this is pretty heavy stuff. I thought of using matrices as nodes to build trees, using their variable names as pointers, but you need a strong stomach...

Then I saw this Python to RPN thing and thought "wow ! In Python this is almost trivial to do !". Then I read the converter documentation and my enthousiasm scaled down... It seems that the converter still relied on the 4-level stack to evaluate expressions, without using registers to store temporary computations, and that therefore too complex algebraic computations are doomed to failure. And since I want to do recursive tree evaluation...

I don't want to start this if this has no chance of success. What do you think ?

Thanks in advance and cheers,

Vincent
Find all posts by this user
Quote this message in a reply
06-25-2018, 05:00 PM (This post was last modified: 06-28-2018 03:07 PM by Thomas Klemm.)
Post: #36
RE: Python to RPN converter
(06-24-2018 10:56 PM)tcab Wrote:  If you are interested, here are the slides of a recent talk I gave to a local Python User Group in Melbourne, Australia, about how I used the Python AST capabilities to build the Python to Rpn converter.

Thanks a lot for your answer and sharing the slides. I guess I'll have to dive a bit deeper into the innards of Python.
I published the program here and to my astonishment it's still present.

Cheers
Thomas
Find all posts by this user
Quote this message in a reply
06-28-2018, 04:07 PM (This post was last modified: 06-28-2018 05:19 PM by Thomas Klemm.)
Post: #37
RE: Python to RPN converter
Just watched the talk Hy: A Lisp that transforms itself into the Python AST that you mentioned in the slides.
This made me wonder if I could translate hy to FOCAL as well?

Let's give it a try with a function that calculates the area of circle given the radius r:
Code:
(defn circle [r]
    (* pi (** r 2)))

Code:
hy 0.14.0+196.g4de18d3 using CPython(default) 2.7.10 on Darwin
=> (import [compiler [translate]])
=> (import [math [pi]])
=> (defn circle [r] (* pi (** r 2)))
=> (circle 5)
78.53981633974483
=> (translate circle.__code__)
LBL "CIRCLE"
STO 00 ; r
RDN
PI
RCL 00 ; r
2
Y↑X
*
RTN

How cool is that?

Since hy produces an AST I assume it would be easy to provide a frontend for your application.

For those of you who want to try hy.
   
Find all posts by this user
Quote this message in a reply
06-28-2018, 08:04 PM
Post: #38
RE: Python to RPN converter
While the syntax of hy is similar to Clojure we can still use a while-loop and mutate local variables.
This makes the translation from Python straight forward.
We can even break out of a loop.

I've translated a few of the other examples:

Celsius to Fahrenheit
Code:
(defn fahrenheit [celsius]
  (+ (/ (* 9 celsius) 5) 32))

Quadratic Equation
Code:
(defn qe [a b c]
  (setv
    p (/ b a -2)
    q (/ c a)
    D (sqrt (- (** p 2) q)))
  [(+ p D) (- p D)])

Greatest Common Divisor
Code:
(defn gcd [a b]
  (while (!= b 0)
    (setv 
      r (% a b)
      a b
      b r))
  a)

Factors of a Number
Code:
(defn factor [n]
  (setv p 2)
  (while (> n 1)
    (if (> (** p 2) n)
      (do
        (print n)
        (break)))
    (while (= (% n p) 0)
      (do
        (print p)
        (setv n (// n p))))
    (setv p (+ p 1))))

Circumference of an Ellipse
Code:
(defn ellipse [a b]
  (setv
    u 1
    v (/ b a)
    s (/ (+ 1 (** v 2)) 2)
    t 1)
  (while (= 0 0)
    (setv m (/ (+ u v) 2))
    (if (= m u)
      (break))
    (setv
      w (/ (- u v) 2)
      v (sqrt (* u v))
      u m
      s (- s (* t (** w 2)))
      t (* t 2)))
  (/ (* 2 pi a s) u))


It appears that print is handled as a function in hy.
Thus I had to extend the compiler a bit.
Otherwise translating the factor function would lead to errors.

It is mapped to AVIEW:
Code:
function = {
    # built-in
    'abs' : 'ABS',
    'int' : 'INT',
    'round' : 'RND',
    'print' : 'AVIEW',
    # math
(...)
Find all posts by this user
Quote this message in a reply
Post Reply 




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