Code Analyzer for HP Calculators - Printable Version +- HP Forums (https://www.hpmuseum.org/forum) +-- Forum: Not HP Calculators (/forum-7.html) +--- Forum: Not quite HP Calculators - but related (/forum-8.html) +--- Thread: Code Analyzer for HP Calculators (/thread-18245.html) Code Analyzer for HP Calculators - Thomas Klemm - 04-10-2022 07:25 PM The Simulator This Python program simulates an HP calculator: Code: X, Y, Z, T, L = [0] * 5 R = [0] * 10 SYMBOLIC = None def trace(operation):     def fmt(s):         return str(s)          def wrapper(*args):         operation(*args)         params = ' '.join(map(str, args))         if SYMBOLIC:             print((               f"X: {fmt(X):<50s}    "               f"Y: {fmt(Y):<50s}    "               f"Z: {fmt(Z):<50s}    "               f"T: {fmt(T):<50s}    "               f"L: {fmt(L):<50s}    "               f": {operation.__name__} {params}"             ))         else:             print((               f"X: {X:< 20.12e}    "               f"Y: {Y:< 20.12e}    "               f"Z: {Z:< 20.12e}    "               f"T: {T:< 20.12e}    "               f"L: {L:< 20.12e}    "               f": {operation.__name__} {params}"             ))     return wrapper # operations @trace def CHS(): # +/-     global X, Y, Z, T, L     X = -X @trace def ADD(): # +     global X, Y, Z, T, L     X, Y, Z, L = Y + X, Z, T, X @trace def SUB(): # -     global X, Y, Z, T, L     X, Y, Z, L = Y - X, Z, T, X @trace def MUL(): # *     global X, Y, Z, T, L     X, Y, Z, L = Y * X, Z, T, X @trace def DIV(): # /     global X, Y, Z, T, L     X, Y, Z, L = Y / X, Z, T, X @trace def MOD():     global X, Y, Z, T, L     X, Y, Z, L = Y % X, Z, T, X @trace def YTX(): # Y^X     global X, Y, Z, T, L     X, Y, Z, L = Y ** X, Z, T, X # functions @trace def RECIPROCAL(): # 1/X     global X, Y, Z, T, L     X, L = 1 / X, X @trace def FACT(): # X!     global X, Y, Z, T, L     X, L = factorial(X), X @trace def XT2(): # X^2     global X, Y, Z, T, L     X, L = X ** 2, X @trace def SQRT():     global X, Y, Z, T, L     X, L = sqrt(X), X @trace def EXP(): # E^X     global X, Y, Z, T, L     X, L = exp(X), X @trace def LN():     global X, Y, Z, T, L     X, L = log(X), X @trace def TENTX(): # 10^X     global X, Y, Z, T, L     X, L = 10 ** X, X @trace def LOG():     global X, Y, Z, T, L     X, L = log(X) / log(10), X # trigonometry     @trace def PI():     global X, Y, Z, T, L     X, Y, Z, T = pi, X, Y, Z @trace def SIN():     global X, Y, Z, T, L     X, L = sin(X), X @trace def ASIN():     global X, Y, Z, T, L     X, L = asin(X), X @trace def COS():     global X, Y, Z, T, L     X, L = cos(X), X @trace def ACOS():     global X, Y, Z, T, L     X, L = acos(X), X @trace def TAN():     global X, Y, Z, T, L     X, L = tan(X), X @trace def ATAN():     global X, Y, Z, T, L     X, L = atan(X), X # hyperbolic @trace def SINH():     global X, Y, Z, T, L     X, L = sinh(X), X @trace def ASINH():     global X, Y, Z, T, L     X, L = asinh(X), X @trace def COSH():     global X, Y, Z, T, L     X, L = cosh(X), X @trace def ACOSH():     global X, Y, Z, T, L     X, L = acosh(X), X @trace def TANH():     global X, Y, Z, T, L     X, L = tanh(X), X @trace def ATANH():     global X, Y, Z, T, L     X, L = atanh(X), X # stack @trace def number(n):     global X, Y, Z, T, L     X, Y, Z, T = n, X, Y, Z @trace def SWAP(): # X<>Y     global X, Y, Z, T, L     X, Y = Y, X @trace def DUP(): # ENTER     global X, Y, Z, T, L     Y, Z, T = X, Y, Z @trace def RUP(): # R^     global X, Y, Z, T, L     X, Y, Z, T = T, X, Y, Z @trace def RDN(): # Rv     global X, Y, Z, T, L     X, Y, Z, T = Y, Z, T, X @trace def LASTX():     global X, Y, Z, T, L     X, Y, Z, T = L, X, Y, Z @trace def CLST():     global X, Y, Z, T, L     X, Y, Z, T, L = [0] * 5 # register @trace def CLRG():     global X, Y, Z, T, L     R = [0] * 10 @trace def STO(n):     global X, Y, Z, T, L     R[n] = X @trace def RCL(n):     global X, Y, Z, T, L     X, Y, Z, T = R[n], X, Y, Z The stack and the use of registers is implemented. Also the most common functions are provided. Writing Programs It is straight forward to write a program using these functions. Area of a Circle This program calculates the area of a circle based on the radius $$r$$: $$A = \pi r^2$$ Code: def area(r):     global X, Y, Z, T, L     X = r     XT2()       # X^2     PI()        # PI     MUL()       # * Quadratic Equation This program calculates the solution of the quadratic equation based on the coefficients $$a$$, $$b$$ and $$c$$: $$a x^2 + b x + c = 0$$ Code: def quadratic_equation(a, b, c):     global X, Y, Z, T, L     X, Y, Z = c, b, a     DUP()       # ENTER     RUP()       # R^     DIV()       # /     RUP()       # R^     LASTX()     # LASTX     DIV()       # /     number(-2)  # -2     DIV()       # /     DUP()       # ENTER     DUP()       # ENTER     XT2()       # X^2     RUP()       # R^     SUB()       # -     SQRT()      # SQRT     SUB()       # -     SWAP()      # X<>Y     LASTX()     # LASTX     ADD()       # + Numeric Evaluation Import the math Library If we want to analyze the numeric values we import the math library: Code: from math import (     pi,     sqrt,     factorial,     exp,     log,     sin,     asin,     cos,     acos,     tan,     atan,     sinh,     asinh,     cosh,     acosh,     tanh,     atanh, ) SYMBOLIC = False CLST() X:  0.000000000000e+00     Y:  0.000000000000e+00     Z:  0.000000000000e+00     T:  0.000000000000e+00     L:  0.000000000000e+00     : CLST  Area of a Circle Code: r = 4 area(r) X:  1.600000000000e+01     Y:  0.000000000000e+00     Z:  0.000000000000e+00     T:  0.000000000000e+00     L:  4.000000000000e+00     : XT2  X:  3.141592653590e+00     Y:  1.600000000000e+01     Z:  0.000000000000e+00     T:  0.000000000000e+00     L:  4.000000000000e+00     : PI  X:  5.026548245744e+01     Y:  0.000000000000e+00     Z:  0.000000000000e+00     T:  0.000000000000e+00     L:  3.141592653590e+00     : MUL  Quadratic Equation Code: a, b, c = 1, -1, -1 quadratic_equation(a, b, c) X: -1.000000000000e+00     Y: -1.000000000000e+00     Z: -1.000000000000e+00     T:  1.000000000000e+00     L:  0.000000000000e+00     : DUP  X:  1.000000000000e+00     Y: -1.000000000000e+00     Z: -1.000000000000e+00     T: -1.000000000000e+00     L:  0.000000000000e+00     : RUP  X: -1.000000000000e+00     Y: -1.000000000000e+00     Z: -1.000000000000e+00     T: -1.000000000000e+00     L:  1.000000000000e+00     : DIV  X: -1.000000000000e+00     Y: -1.000000000000e+00     Z: -1.000000000000e+00     T: -1.000000000000e+00     L:  1.000000000000e+00     : RUP  X:  1.000000000000e+00     Y: -1.000000000000e+00     Z: -1.000000000000e+00     T: -1.000000000000e+00     L:  1.000000000000e+00     : LASTX  X: -1.000000000000e+00     Y: -1.000000000000e+00     Z: -1.000000000000e+00     T: -1.000000000000e+00     L:  1.000000000000e+00     : DIV  X: -2.000000000000e+00     Y: -1.000000000000e+00     Z: -1.000000000000e+00     T: -1.000000000000e+00     L:  1.000000000000e+00     : number -2 X:  5.000000000000e-01     Y: -1.000000000000e+00     Z: -1.000000000000e+00     T: -1.000000000000e+00     L: -2.000000000000e+00     : DIV  X:  5.000000000000e-01     Y:  5.000000000000e-01     Z: -1.000000000000e+00     T: -1.000000000000e+00     L: -2.000000000000e+00     : DUP  X:  5.000000000000e-01     Y:  5.000000000000e-01     Z:  5.000000000000e-01     T: -1.000000000000e+00     L: -2.000000000000e+00     : DUP  X:  2.500000000000e-01     Y:  5.000000000000e-01     Z:  5.000000000000e-01     T: -1.000000000000e+00     L:  5.000000000000e-01     : XT2  X: -1.000000000000e+00     Y:  2.500000000000e-01     Z:  5.000000000000e-01     T:  5.000000000000e-01     L:  5.000000000000e-01     : RUP  X:  1.250000000000e+00     Y:  5.000000000000e-01     Z:  5.000000000000e-01     T:  5.000000000000e-01     L: -1.000000000000e+00     : SUB  X:  1.118033988750e+00     Y:  5.000000000000e-01     Z:  5.000000000000e-01     T:  5.000000000000e-01     L:  1.250000000000e+00     : SQRT  X: -6.180339887499e-01     Y:  5.000000000000e-01     Z:  5.000000000000e-01     T:  5.000000000000e-01     L:  1.118033988750e+00     : SUB  X:  5.000000000000e-01     Y: -6.180339887499e-01     Z:  5.000000000000e-01     T:  5.000000000000e-01     L:  1.118033988750e+00     : SWAP  X:  1.118033988750e+00     Y:  5.000000000000e-01     Z: -6.180339887499e-01     T:  5.000000000000e-01     L:  1.118033988750e+00     : LASTX  X:  1.618033988750e+00     Y: -6.180339887499e-01     Z:  5.000000000000e-01     T:  5.000000000000e-01     L:  1.118033988750e+00     : ADD  Symbolic Evaluation Import the sympy Library If we want to analyze the symbolic values we import the sympy library: Code: from sympy import (     pi,     sqrt,     factorial,     exp,     log,     sin,     asin,     cos,     acos,     tan,     atan,     sinh,     asinh,     cosh,     acosh,     tanh,     atanh,     symbols,     expand,     simplify,     latex, ) SYMBOLIC = True CLST() X: 0                                                     Y: 0                                                     Z: 0                                                     T: 0                                                     L: 0                                                     : CLST   Area of a Circle Code: r = symbols("r") area(r) X: r**2                                                  Y: 0                                                     Z: 0                                                     T: 0                                                     L: r                                                     : XT2  X: pi                                                    Y: r**2                                                  Z: 0                                                     T: 0                                                     L: r                                                     : PI  X: pi*r**2                                               Y: 0                                                     Z: 0                                                     T: 0                                                     L: pi                                                    : MUL  Quadratic Equation Code: a, b, c = symbols("a b c") quadratic_equation(a, b, c) X: c                                                     Y: c                                                     Z: b                                                     T: a                                                     L: 0                                                     : DUP  X: a                                                     Y: c                                                     Z: c                                                     T: b                                                     L: 0                                                     : RUP  X: c/a                                                   Y: c                                                     Z: b                                                     T: b                                                     L: a                                                     : DIV  X: b                                                     Y: c/a                                                   Z: c                                                     T: b                                                     L: a                                                     : RUP  X: a                                                     Y: b                                                     Z: c/a                                                   T: c                                                     L: a                                                     : LASTX  X: b/a                                                   Y: c/a                                                   Z: c                                                     T: c                                                     L: a                                                     : DIV  X: -2                                                    Y: b/a                                                   Z: c/a                                                   T: c                                                     L: a                                                     : number -2 X: -b/(2*a)                                              Y: c/a                                                   Z: c                                                     T: c                                                     L: -2                                                    : DIV  X: -b/(2*a)                                              Y: -b/(2*a)                                              Z: c/a                                                   T: c                                                     L: -2                                                    : DUP  X: -b/(2*a)                                              Y: -b/(2*a)                                              Z: -b/(2*a)                                              T: c/a                                                   L: -2                                                    : DUP  X: b**2/(4*a**2)                                         Y: -b/(2*a)                                              Z: -b/(2*a)                                              T: c/a                                                   L: -b/(2*a)                                              : XT2  X: c/a                                                   Y: b**2/(4*a**2)                                         Z: -b/(2*a)                                              T: -b/(2*a)                                              L: -b/(2*a)                                              : RUP  X: -c/a + b**2/(4*a**2)                                  Y: -b/(2*a)                                              Z: -b/(2*a)                                              T: -b/(2*a)                                              L: c/a                                                   : SUB  X: sqrt(-c/a + b**2/(4*a**2))                            Y: -b/(2*a)                                              Z: -b/(2*a)                                              T: -b/(2*a)                                              L: -c/a + b**2/(4*a**2)                                  : SQRT  X: -sqrt(-c/a + b**2/(4*a**2)) - b/(2*a)                 Y: -b/(2*a)                                              Z: -b/(2*a)                                              T: -b/(2*a)                                              L: sqrt(-c/a + b**2/(4*a**2))                            : SUB  X: -b/(2*a)                                              Y: -sqrt(-c/a + b**2/(4*a**2)) - b/(2*a)                 Z: -b/(2*a)                                              T: -b/(2*a)                                              L: sqrt(-c/a + b**2/(4*a**2))                            : SWAP  X: sqrt(-c/a + b**2/(4*a**2))                            Y: -b/(2*a)                                              Z: -sqrt(-c/a + b**2/(4*a**2)) - b/(2*a)                 T: -b/(2*a)                                              L: sqrt(-c/a + b**2/(4*a**2))                            : LASTX  X: sqrt(-c/a + b**2/(4*a**2)) - b/(2*a)                  Y: -sqrt(-c/a + b**2/(4*a**2)) - b/(2*a)                 Z: -b/(2*a)                                              T: -b/(2*a)                                              L: sqrt(-c/a + b**2/(4*a**2))                            : ADD  Ad Hoc Calculations We can also do some ad hoc calculations: Code: x = symbols("x") CLST() X = x ATAN() SIN() X: 0                                                     Y: 0                                                     Z: 0                                                     T: 0                                                     L: 0                                                     : CLST  X: atan(x)                                               Y: 0                                                     Z: 0                                                     T: 0                                                     L: x                                                     : ATAN  X: x/sqrt(x**2 + 1)                                      Y: 0                                                     Z: 0                                                     T: 0                                                     L: atan(x)                                               : SIN  LaTeX Support These results can be transformed into LaTeX: Code: print(latex(X)) \frac{x}{\sqrt{x^{2} + 1}} $$\frac{x}{\sqrt{x^{2} + 1}}$$ If we want all results printed in LaTeX we can modify the fmt function: Code:     def fmt(s):         return latex(s) Complex Numbers I haven't tried this yet, but we could import the functions from the cmath library. However, the formatting will likely require some adjustments. Caveat LBL and GTO are missing, but we can simulate that with the Python control structures stack lift isn't handled, but that's not usually a problem in programs probably something is still missing Still, I hope this might be useful. RE: Code Analyzer for HP Calculators - Namir - 04-11-2022 09:56 AM Very nice work!! Your Python code is elegant. Namir RE: Code Analyzer for HP Calculators - Thomas Klemm - 04-11-2022 06:08 PM (04-11-2022 09:56 AM)Namir Wrote:  Your Python code is elegant. Well I must admit that I cobbled that together in a Jupyter notebook. And that's probably the best environment to run it. The state of the calculator is stored in these global variables, which I usually avoid. So I had to declare them global in each of the functions. But that along with the trace decorator makes them short and hopefully easy to understand. (04-10-2022 07:25 PM)Thomas Klemm Wrote:  I haven't tried this yet, but we could import the functions from the cmath library. However, the formatting will likely require some adjustments. If we want to analyze complex values we import the cmath library: Code: from cmath import (     pi,     sqrt,     exp,     log,     sin,     asin,     cos,     acos,     tan,     atan,     sinh,     asinh,     cosh,     acosh,     tanh,     atanh, ) SYMBOLIC = False CLST() The trace function needs minor adjustments: Code:             print((               f"X: {X:< 30.6e}    "               f"Y: {Y:< 30.6e}    "               f"Z: {Z:< 30.6e}    "               f"T: {T:< 30.6e}    "               f"L: {L:< 30.6e}    "               f": {operation.__name__} {params}"             )) And now we can also solve a quadratic equation with complex solutions: Code: a, b, c = 1, 1, 1 quadratic_equation(a, b, c) X:  1.000000e+00                     Y:  1.000000e+00                     Z:  1.000000e+00                     T:  1.000000e+00                     L:  0.000000e+00                     : DUP  X:  1.000000e+00                     Y:  1.000000e+00                     Z:  1.000000e+00                     T:  1.000000e+00                     L:  0.000000e+00                     : RUP  X:  1.000000e+00                     Y:  1.000000e+00                     Z:  1.000000e+00                     T:  1.000000e+00                     L:  1.000000e+00                     : DIV  X:  1.000000e+00                     Y:  1.000000e+00                     Z:  1.000000e+00                     T:  1.000000e+00                     L:  1.000000e+00                     : RUP  X:  1.000000e+00                     Y:  1.000000e+00                     Z:  1.000000e+00                     T:  1.000000e+00                     L:  1.000000e+00                     : LASTX  X:  1.000000e+00                     Y:  1.000000e+00                     Z:  1.000000e+00                     T:  1.000000e+00                     L:  1.000000e+00                     : DIV  X: -2.000000e+00                     Y:  1.000000e+00                     Z:  1.000000e+00                     T:  1.000000e+00                     L:  1.000000e+00                     : number -2 X: -5.000000e-01                     Y:  1.000000e+00                     Z:  1.000000e+00                     T:  1.000000e+00                     L: -2.000000e+00                     : DIV  X: -5.000000e-01                     Y: -5.000000e-01                     Z:  1.000000e+00                     T:  1.000000e+00                     L: -2.000000e+00                     : DUP  X: -5.000000e-01                     Y: -5.000000e-01                     Z: -5.000000e-01                     T:  1.000000e+00                     L: -2.000000e+00                     : DUP  X:  2.500000e-01                     Y: -5.000000e-01                     Z: -5.000000e-01                     T:  1.000000e+00                     L: -5.000000e-01                     : XT2  X:  1.000000e+00                     Y:  2.500000e-01                     Z: -5.000000e-01                     T: -5.000000e-01                     L: -5.000000e-01                     : RUP  X: -7.500000e-01                     Y: -5.000000e-01                     Z: -5.000000e-01                     T: -5.000000e-01                     L:  1.000000e+00                     : SUB  X:  0.000000e+00+8.660254e-01j       Y: -5.000000e-01                     Z: -5.000000e-01                     T: -5.000000e-01                     L: -7.500000e-01                     : SQRT  X: -5.000000e-01-8.660254e-01j       Y: -5.000000e-01                     Z: -5.000000e-01                     T: -5.000000e-01                     L:  0.000000e+00+8.660254e-01j       : SUB  X: -5.000000e-01                     Y: -5.000000e-01-8.660254e-01j       Z: -5.000000e-01                     T: -5.000000e-01                     L:  0.000000e+00+8.660254e-01j       : SWAP  X:  0.000000e+00+8.660254e-01j       Y: -5.000000e-01                     Z: -5.000000e-01-8.660254e-01j       T: -5.000000e-01                     L:  0.000000e+00+8.660254e-01j       : LASTX  X: -5.000000e-01+8.660254e-01j       Y: -5.000000e-01-8.660254e-01j       Z: -5.000000e-01                     T: -5.000000e-01                     L:  0.000000e+00+8.660254e-01j       : ADD  RE: Code Analyzer for HP Calculators - Sylvain Cote - 04-11-2022 10:44 PM Interesting ... I have run it inside PyCharm IDE from JetBrains. Thank you Thomas! Sylvain RE: Code Analyzer for HP Calculators - Thomas Klemm - 04-12-2022 11:27 PM Good to know it works for others too. Thanks for checking that. Meanwhile, I posted a simulator for the HP-80 CPU in this other thread. Actually, I wrote that first and then thought to myself that it also fits for the analysis of programs from HP calculators.