Skip to content

Instantly share code, notes, and snippets.

@gavinwahl
Created September 22, 2012 22:44
Show Gist options
  • Save gavinwahl/3768115 to your computer and use it in GitHub Desktop.
Save gavinwahl/3768115 to your computer and use it in GitHub Desktop.
simple python-like expressions
import ast
import operator
ops = {
ast.Add: operator.add,
ast.Mult: operator.mul,
ast.Sub: operator.sub,
ast.Div: operator.truediv,
ast.FloorDiv: operator.floordiv,
ast.Mod: operator.mod,
# unary
ast.USub: operator.neg,
ast.UAdd: operator.pos,
}
fns = {
'min': min,
'max': max,
}
def eval_in(env):
return lambda expr: eval(expr, env)
def eval(expr, env):
if isinstance(expr, ast.Expr):
return eval(expr.value, env)
elif isinstance(expr, ast.Name):
return env[expr.id]
elif isinstance(expr, ast.Num):
return expr.n
elif isinstance(expr, ast.UnaryOp):
op = ops[type(expr.op)]
return op(eval(expr.operand, env))
elif isinstance(expr, ast.BinOp):
op = ops[type(expr.op)]
return op(eval(expr.left, env), eval(expr.right, env))
elif isinstance(expr, ast.Call):
fn = fns[expr.func.id]
if expr.kwargs:
raise Exception('kwargs not supported')
return fn(*map(eval_in(env), expr.args))
else:
raise Exception("I don't understand %s" % expr)
def eval_expr(str, env={}):
module = ast.parse(str)
if not isinstance(module, ast.Module):
raise Exception("I don't understand")
body = module.body
if len(body) != 1:
raise Exception("One and only one expression is supported")
expr = body[0]
if not isinstance(expr, ast.Expr):
raise Exception("Only expressions are supported")
return eval(expr, env)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment