|
16 | 16 | ast.BitAnd: op.and_,
|
17 | 17 | ast.BitOr: op.or_,
|
18 | 18 | ast.Invert: op.invert,
|
19 |
| - ast.And: op.and_, |
| 19 | + ast.And: lambda a, b: 1 if a and b else 0, |
| 20 | + ast.Or: lambda a, b: 1 if a or b else 0, |
| 21 | + ast.Not: lambda a: 0 if a else 1, |
20 | 22 | }
|
21 | 23 |
|
22 | 24 | # TODO: restructure args to provide more info, generate hint based on args to save duplication
|
|
66 | 68 | "call": lambda a = None: int(a),
|
67 | 69 | "hint": "number"
|
68 | 70 | },
|
| 71 | + "iif": { |
| 72 | + "args": (3, 3), |
| 73 | + "call": lambda a, b, c = None: b if a else c, |
| 74 | + "hint": "value, truepart, falsepart" |
| 75 | + }, |
69 | 76 | }
|
70 | 77 |
|
71 | 78 | autocompleteWords = list({
|
@@ -150,15 +157,20 @@ def evaluate(self, expression, prompt, extra_pnginfo={}, a=None, b=None, c=None)
|
150 | 157 |
|
151 | 158 | lookup = {"a": a, "b": b, "c": c}
|
152 | 159 |
|
| 160 | + def eval_op(l, r): |
| 161 | + l = eval_expr(l) |
| 162 | + r = eval_expr(r) |
| 163 | + l = l if isinstance(l, int) else float(l) |
| 164 | + r = r if isinstance(r, int) else float(r) |
| 165 | + return operators[type(node.op)](l, r) |
| 166 | + |
153 | 167 | def eval_expr(node):
|
154 |
| - if isinstance(node, ast.Num): |
| 168 | + if isinstance(node, ast.Constant) or isinstance(node, ast.Num): |
155 | 169 | return node.n
|
156 | 170 | elif isinstance(node, ast.BinOp):
|
157 |
| - l = eval_expr(node.left) |
158 |
| - r = eval_expr(node.right) |
159 |
| - l = l if isinstance(l, int) else float(l) |
160 |
| - r = r if isinstance(r, int) else float(r) |
161 |
| - return operators[type(node.op)](l, r) |
| 171 | + return eval_op(node.left, node.right) |
| 172 | + elif isinstance(node, ast.BoolOp): |
| 173 | + return eval_op(node.values[0], node.values[1]) |
162 | 174 | elif isinstance(node, ast.UnaryOp):
|
163 | 175 | return operators[type(node.op)](eval_expr(node.operand))
|
164 | 176 | elif isinstance(node, ast.Attribute):
|
@@ -192,6 +204,23 @@ def eval_expr(node):
|
192 | 204 | args.append(eval_expr(arg))
|
193 | 205 | return fn["call"](*args)
|
194 | 206 | raise NameError(f"Invalid function call: {node.func.id}")
|
| 207 | + elif isinstance(node, ast.Compare): |
| 208 | + l = eval_expr(node.left) |
| 209 | + r = eval_expr(node.comparators[0]) |
| 210 | + if isinstance(node.ops[0], ast.Eq): |
| 211 | + return 1 if l == r else 0 |
| 212 | + if isinstance(node.ops[0], ast.NotEq): |
| 213 | + return 1 if l != r else 0 |
| 214 | + if isinstance(node.ops[0], ast.Gt): |
| 215 | + return 1 if l > r else 0 |
| 216 | + if isinstance(node.ops[0], ast.GtE): |
| 217 | + return 1 if l >= r else 0 |
| 218 | + if isinstance(node.ops[0], ast.Lt): |
| 219 | + return 1 if l < r else 0 |
| 220 | + if isinstance(node.ops[0], ast.LtE): |
| 221 | + return 1 if l <= r else 0 |
| 222 | + raise NotImplementedError( |
| 223 | + "Operator " + node.ops[0].__class__.__name__ + " not supported.") |
195 | 224 | else:
|
196 | 225 | raise TypeError(node)
|
197 | 226 |
|
|
0 commit comments