Skip to content

Commit 9327f8d

Browse files
authored
Add support for multi operator expressions (pyccel#2083)
Add support for multi operator expressions by extending the syntactic stage. Fixes pyccel#2081
1 parent a0ee291 commit 9327f8d

File tree

2 files changed

+44
-29
lines changed

2 files changed

+44
-29
lines changed

pyccel/parser/syntactic.py

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -692,37 +692,38 @@ def _visit_BoolOp(self, stmt):
692692
severity='error')
693693

694694
def _visit_Compare(self, stmt):
695-
if len(stmt.ops)>1:
696-
return errors.report(PYCCEL_RESTRICTION_MULTIPLE_COMPARISONS,
697-
symbol = stmt,
698-
severity='error')
699-
700695
first = self._visit(stmt.left)
701-
second = self._visit(stmt.comparators[0])
702-
op = stmt.ops[0]
703-
704-
if isinstance(op, ast.Eq):
705-
return PyccelEq(first, second)
706-
if isinstance(op, ast.NotEq):
707-
return PyccelNe(first, second)
708-
if isinstance(op, ast.Lt):
709-
return PyccelLt(first, second)
710-
if isinstance(op, ast.Gt):
711-
return PyccelGt(first, second)
712-
if isinstance(op, ast.LtE):
713-
return PyccelLe(first, second)
714-
if isinstance(op, ast.GtE):
715-
return PyccelGe(first, second)
716-
if isinstance(op, ast.Is):
717-
return PyccelIs(first, second)
718-
if isinstance(op, ast.IsNot):
719-
return PyccelIsNot(first, second)
720-
if isinstance(op, ast.In):
721-
return PyccelIn(first, second)
696+
comparison = None
697+
for comparators, op in zip(stmt.comparators, stmt.ops):
698+
second = self._visit(comparators)
699+
700+
if isinstance(op, ast.Eq):
701+
expr = PyccelEq(first, second)
702+
elif isinstance(op, ast.NotEq):
703+
expr = PyccelNe(first, second)
704+
elif isinstance(op, ast.Lt):
705+
expr = PyccelLt(first, second)
706+
elif isinstance(op, ast.Gt):
707+
expr = PyccelGt(first, second)
708+
elif isinstance(op, ast.LtE):
709+
expr = PyccelLe(first, second)
710+
elif isinstance(op, ast.GtE):
711+
expr = PyccelGe(first, second)
712+
elif isinstance(op, ast.Is):
713+
expr = PyccelIs(first, second)
714+
elif isinstance(op, ast.IsNot):
715+
expr = PyccelIsNot(first, second)
716+
elif isinstance(op, ast.In):
717+
expr = PyccelIn(first, second)
718+
else:
719+
return errors.report(PYCCEL_RESTRICTION_UNSUPPORTED_SYNTAX,
720+
symbol = stmt,
721+
severity='error')
722722

723-
return errors.report(PYCCEL_RESTRICTION_UNSUPPORTED_SYNTAX,
724-
symbol = stmt,
725-
severity='error')
723+
first = second
724+
comparison = PyccelAnd(comparison, expr) if comparison else expr
725+
726+
return comparison
726727

727728
def _visit_Return(self, stmt):
728729
results = self._visit(stmt.value)

tests/epyccel/test_compare_expressions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ def mod_neq_pow(a : int, m : int, n : int):
1111
def idiv_gt_add(a : int, m : int, n : int):
1212
return a//m > n+1
1313

14+
def in_range(a : float, b : float, c : float):
15+
return a <= b < c
16+
1417
#==============================================================================
1518
def test_mod_eq_pow(language):
1619
test = epyccel_test(mod_eq_pow, lang=language)
@@ -44,3 +47,14 @@ def test_idiv_gt_add(language):
4447
test.compare_epyccel(10, 3, 2)
4548
test.compare_epyccel(8, 2, 3)
4649
test.compare_epyccel(16, 3, 5)
50+
51+
def test_in_range(language):
52+
test = epyccel_test(in_range, lang=language)
53+
# True
54+
test.compare_epyccel(0.0, 1.0, 2.0)
55+
test.compare_epyccel(-2.0, -1.0, 2.0)
56+
test.compare_epyccel(-2.0, -1.3, -1.0)
57+
# False
58+
test.compare_epyccel(0.0, 10.0, 2.0)
59+
test.compare_epyccel(-2.0, -10.0, 2.0)
60+
test.compare_epyccel(-2.0, -0.3, -1.0)

0 commit comments

Comments
 (0)