Post Reply 
Code Analyzer for HP Calculators
04-10-2022, 07:25 PM
Post: #1
Code Analyzer for HP Calculators
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.
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
Code Analyzer for HP Calculators - Thomas Klemm - 04-10-2022 07:25 PM



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