Add and or not

Add `iif(v, t, f)`
Add `==` `!=` `<` `<=` `>` `>=`
This commit is contained in:
pythongosssss
2024-05-16 21:57:33 +01:00
parent 4244e2cd03
commit 8a77dcae71
+36 -7
View File
@@ -16,7 +16,9 @@ operators = {
ast.BitAnd: op.and_,
ast.BitOr: op.or_,
ast.Invert: op.invert,
ast.And: op.and_,
ast.And: lambda a, b: 1 if a and b else 0,
ast.Or: lambda a, b: 1 if a or b else 0,
ast.Not: lambda a: 0 if a else 1,
}
# TODO: restructure args to provide more info, generate hint based on args to save duplication
@@ -66,6 +68,11 @@ functions = {
"call": lambda a = None: int(a),
"hint": "number"
},
"iif": {
"args": (3, 3),
"call": lambda a, b, c = None: b if a else c,
"hint": "value, truepart, falsepart"
},
}
autocompleteWords = list({
@@ -150,15 +157,20 @@ class MathExpression:
lookup = {"a": a, "b": b, "c": c}
def eval_op(l, r):
l = eval_expr(l)
r = eval_expr(r)
l = l if isinstance(l, int) else float(l)
r = r if isinstance(r, int) else float(r)
return operators[type(node.op)](l, r)
def eval_expr(node):
if isinstance(node, ast.Num):
if isinstance(node, ast.Constant) or isinstance(node, ast.Num):
return node.n
elif isinstance(node, ast.BinOp):
l = eval_expr(node.left)
r = eval_expr(node.right)
l = l if isinstance(l, int) else float(l)
r = r if isinstance(r, int) else float(r)
return operators[type(node.op)](l, r)
return eval_op(node.left, node.right)
elif isinstance(node, ast.BoolOp):
return eval_op(node.values[0], node.values[1])
elif isinstance(node, ast.UnaryOp):
return operators[type(node.op)](eval_expr(node.operand))
elif isinstance(node, ast.Attribute):
@@ -192,6 +204,23 @@ class MathExpression:
args.append(eval_expr(arg))
return fn["call"](*args)
raise NameError(f"Invalid function call: {node.func.id}")
elif isinstance(node, ast.Compare):
l = eval_expr(node.left)
r = eval_expr(node.comparators[0])
if isinstance(node.ops[0], ast.Eq):
return 1 if l == r else 0
if isinstance(node.ops[0], ast.NotEq):
return 1 if l != r else 0
if isinstance(node.ops[0], ast.Gt):
return 1 if l > r else 0
if isinstance(node.ops[0], ast.GtE):
return 1 if l >= r else 0
if isinstance(node.ops[0], ast.Lt):
return 1 if l < r else 0
if isinstance(node.ops[0], ast.LtE):
return 1 if l <= r else 0
raise NotImplementedError(
"Operator " + node.ops[0].__class__.__name__ + " not supported.")
else:
raise TypeError(node)