Skip to content

Instantly share code, notes, and snippets.

@prl900
Created June 25, 2022 11:56
Show Gist options
  • Save prl900/72cf24c6f60f123ed237627867b8a514 to your computer and use it in GitHub Desktop.
Save prl900/72cf24c6f60f123ed237627867b8a514 to your computer and use it in GitHub Desktop.
import numpy as np
opn = {
"+": np.add,
"-": np.subtract,
"*": np.multiply,
"/": np.divide,
"^": np.power,
"==": np.equal,
"!=": np.not_equal,
">=": np.greater_equal,
"<=": np.less_equal,
">": np.greater,
"<": np.less,
}
fn = {
"sin": np.sin,
"cos": np.cos,
"log": np.log,
"abs": np.abs,
"clip": np.clip,
}
def evaluate_stack(s, arrays):
op, num_args = s.pop(), 0
if isinstance(op, tuple):
op, num_args = op
if op == "unary -":
return -evaluate_stack(s, arrays)
elif op == "NaN":
return np.nan
if op in "+-*/^":
# note: operands are pushed onto the stack in reverse order
op2 = evaluate_stack(s, arrays)
op1 = evaluate_stack(s, arrays)
return opn[op](op1, op2)
if op == "==" or op == "!=" or op == ">=" or op == "<=" or op == ">" or op == "<":
op2 = evaluate_stack(s, arrays)
op1 = evaluate_stack(s, arrays)
return opn[op](op1, op2)
elif op in fn:
# note: args are pushed onto the stack in reverse order
args = reversed([evaluate_stack(s, arrays) for _ in range(num_args)])
return fn[op](*args)
else:
return float(op)
def evaluate(expression, context_dict):
exprStack[:] = []
try:
results = BNF().parseString(expression, parseAll=True)
return evaluate_stack(exprStack[:], context_dict)
except ParseException as pe:
print(s, "failed parse:", str(pe))
except Exception as e:
print(s, "failed eval:", str(e), exprStack)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment