🐐 short circuit evaluation
This commit is contained in:
+14
-4
@@ -806,6 +806,20 @@ class BinOp(Node):
|
||||
return f"({self.left.print()} {OP_STR[self.op]} {self.right.print()})"
|
||||
|
||||
def _eval(self, vtable):
|
||||
# Short-circuit for logical operators
|
||||
if self.op == "KEYWORD_AVT":
|
||||
vtable, left = self.left.eval(vtable)
|
||||
if bool(left):
|
||||
return vtable, ValBool(True)
|
||||
vtable, right = self.right.eval(vtable)
|
||||
return vtable, ValBool(bool(right))
|
||||
if self.op == "KEYWORD_ET":
|
||||
vtable, left = self.left.eval(vtable)
|
||||
if not bool(left):
|
||||
return vtable, ValBool(False)
|
||||
vtable, right = self.right.eval(vtable)
|
||||
return vtable, ValBool(bool(right))
|
||||
|
||||
vtable, left = self.left.eval(vtable)
|
||||
vtable, right = self.right.eval(vtable)
|
||||
lv, rv = left.value(), right.value()
|
||||
@@ -874,10 +888,6 @@ class BinOp(Node):
|
||||
(isinstance(left, ValNul) and isinstance(right, ValInt) and rv == 0)):
|
||||
return vtable, ValBool(False)
|
||||
return vtable, ValBool(lv != rv)
|
||||
case "KEYWORD_ET":
|
||||
return vtable, ValBool(bool(left) and bool(right))
|
||||
case "KEYWORD_AVT":
|
||||
return vtable, ValBool(bool(left) or bool(right))
|
||||
case _:
|
||||
raise Exception(self.op)
|
||||
|
||||
|
||||
@@ -93,6 +93,25 @@ def emit_expr(node, ctx):
|
||||
return [f'CentValue {tmp} = cent_scope_get(&_scope, "{node.name}");'], tmp
|
||||
|
||||
if isinstance(node, BinOp):
|
||||
# Short-circuit for logical operators
|
||||
if node.op in ("KEYWORD_AVT", "KEYWORD_ET"):
|
||||
l_lines, l_var = emit_expr(node.left, ctx)
|
||||
r_lines, r_var = emit_expr(node.right, ctx)
|
||||
tmp = ctx.fresh_tmp()
|
||||
if node.op == "KEYWORD_AVT":
|
||||
lines = l_lines + [f"CentValue {tmp};"]
|
||||
lines += [f"if (cent_truthy({l_var})) {{ {tmp} = cent_bool(1); }} else {{"]
|
||||
lines += [f" {l}" for l in r_lines]
|
||||
lines += [f" {tmp} = cent_bool(cent_truthy({r_var}));"]
|
||||
lines += ["}"]
|
||||
else:
|
||||
lines = l_lines + [f"CentValue {tmp};"]
|
||||
lines += [f"if (!cent_truthy({l_var})) {{ {tmp} = cent_bool(0); }} else {{"]
|
||||
lines += [f" {l}" for l in r_lines]
|
||||
lines += [f" {tmp} = cent_bool(cent_truthy({r_var}));"]
|
||||
lines += ["}"]
|
||||
return lines, tmp
|
||||
|
||||
l_lines, l_var = emit_expr(node.left, ctx)
|
||||
r_lines, r_var = emit_expr(node.right, ctx)
|
||||
tmp = ctx.fresh_tmp()
|
||||
|
||||
Reference in New Issue
Block a user