diff --git a/mathics/builtin/lists.py b/mathics/builtin/lists.py index 63bdb5f0e0..ab04e57983 100644 --- a/mathics/builtin/lists.py +++ b/mathics/builtin/lists.py @@ -1381,10 +1381,19 @@ class Cases(Builtin): = {2 I, 4 - I} """ rules = { - 'Cases[list_, pattern_]': 'Select[list, MatchQ[#, pattern]&]', 'Cases[pattern_][list_]': 'Cases[list, pattern]', } + def apply(self, items, pattern, evaluation): + 'Cases[items_, pattern_]' + if items.is_atom(): + evaluation.message('Select', 'normal') + return + + from mathics.builtin.patterns import Matcher + match = Matcher(pattern).match + return Expression('List', *[leaf for leaf in items.leaves if match(leaf, evaluation)]) + class DeleteCases(Builtin): """ @@ -1400,9 +1409,15 @@ class DeleteCases(Builtin): = {1, 2, 3} """ - rules = { - 'DeleteCases[list_, pattern_]': 'Select[list, ! MatchQ[#, pattern]&]', - } + def apply(self, items, pattern, evaluation): + 'DeleteCases[items_, pattern_]' + if items.is_atom(): + evaluation.message('Select', 'normal') + return + + from mathics.builtin.patterns import Matcher + match = Matcher(pattern).match + return Expression('List', *[leaf for leaf in items.leaves if not match(leaf, evaluation)]) class Position(Builtin): @@ -1452,10 +1467,13 @@ def apply_level(self, expr, patt, ls, evaluation, options={}): except InvalidLevelspecError: return evaluation.message('Position', 'level', ls) + from mathics.builtin.patterns import Matcher + + match = Matcher(patt).match result = [] + def callback(level, pos): - expr = Expression('MatchQ', level, patt) - if expr.evaluate(evaluation).is_true(): + if match(level, evaluation): result.append(pos) return level diff --git a/mathics/builtin/patterns.py b/mathics/builtin/patterns.py index e974aeb7c2..20efaf88b1 100644 --- a/mathics/builtin/patterns.py +++ b/mathics/builtin/patterns.py @@ -572,19 +572,26 @@ def except_yield_func(vars, rest): self.p.match(yield_func, expression, vars, evaluation) +class Matcher(object): + def __init__(self, form): + self.form = Pattern.create(form) + + def match(self, expr, evaluation): + class StopGenerator_MatchQ(StopGenerator): + pass + + def yield_func(vars, rest): + raise StopGenerator_MatchQ(Symbol("True")) + + try: + self.form.match(yield_func, expr, {}, evaluation) + except StopGenerator_MatchQ: + return True + return False + + def match(expr, form, evaluation): - class StopGenerator_MatchQ(StopGenerator): - pass - - form = Pattern.create(form) - - def yield_func(vars, rest): - raise StopGenerator_MatchQ(Symbol("True")) - try: - form.match(yield_func, expr, {}, evaluation) - except StopGenerator_MatchQ: - return True - return False + return Matcher(form).match(expr, evaluation) class MatchQ(Builtin):