diff --git a/Makefile b/Makefile index f206257a26..8b1998ea05 100644 --- a/Makefile +++ b/Makefile @@ -4,12 +4,19 @@ # These comments before the targets start with #: # remake --tasks to shows the targets and the comments +DOCKER_COMPOSE ?= docker-compose +DOCKER_COMPOSE_FILE = GIT2CL ?= admin-tools/git2cl PYTHON ?= python3 PIP ?= pip3 RM ?= rm -.PHONY: all build check clean develop dist doc doc-data gstest pytest test djangotest rmChangeLog +.PHONY: all build \ + check clean \ + develop dist doc doc-data djangotest docker \ + gstest pytest \ + rmChangeLog \ + test #: Default target - same as "develop" all: develop @@ -22,6 +29,10 @@ build: develop: $(PIP) install -e . +#: Build docker image +docker-image: + $(DOCKER_COMPOSE) $(DOCKER_COMPOSE_FILE) build + #: Install mathics install: $(PYTHON) setup.py install diff --git a/admin-tools/make-dist.sh b/admin-tools/make-dist.sh index eee7978153..3ff1460c9a 100755 --- a/admin-tools/make-dist.sh +++ b/admin-tools/make-dist.sh @@ -1,5 +1,5 @@ #!/bin/bash -PACKAGE=mathics +PACKAGE=mathicsscript # FIXME put some of the below in a common routine function finish { diff --git a/app/requirements-mathicsscript.txt b/app/requirements-mathicsscript.txt index 312140e590..f02b00c3d4 100644 --- a/app/requirements-mathicsscript.txt +++ b/app/requirements-mathicsscript.txt @@ -1,4 +1,4 @@ mathics colorama pygments -git+https://github.com/Mathics3/mathicsscript +mathicsscript diff --git a/mathics/builtin/patterns.py b/mathics/builtin/patterns.py index 3654357354..1adb90e9a6 100644 --- a/mathics/builtin/patterns.py +++ b/mathics/builtin/patterns.py @@ -36,7 +36,7 @@ from mathics.builtin.base import Builtin, BinaryOperator, PostfixOperator -from mathics.builtin.base import PatternObject +from mathics.builtin.base import PatternObject, PatternError from mathics.builtin.lists import python_levelspec, InvalidLevelspecError from mathics.core.expression import ( @@ -206,6 +206,8 @@ def apply_levelspec(self, expr, rules, ls, evaluation, options): return result except InvalidLevelspecError: evaluation.message('General', 'level', ls) + except PatternError as e: + evaluation.message('Replace','reps', rules) class ReplaceAll(BinaryOperator): @@ -267,13 +269,16 @@ class ReplaceAll(BinaryOperator): def apply(self, expr, rules, evaluation): 'ReplaceAll[expr_, rules_]' + try: + rules, ret = create_rules(rules, expr, 'ReplaceAll', evaluation) - rules, ret = create_rules(rules, expr, 'ReplaceAll', evaluation) - if ret: - return rules + if ret: + return rules - result, applied = expr.apply_rules(rules, evaluation) - return result + result, applied = expr.apply_rules(rules, evaluation) + return result + except PatternError as e: + evaluation.message('Replace','reps', rules) class ReplaceRepeated(BinaryOperator): @@ -309,8 +314,12 @@ class ReplaceRepeated(BinaryOperator): def apply_list(self, expr, rules, evaluation): 'ReplaceRepeated[expr_, rules_]' + try: + rules, ret = create_rules(rules, expr, 'ReplaceRepeated', evaluation) + except PatternError as e: + evaluation.message('Replace','reps', rules) + return None - rules, ret = create_rules(rules, expr, 'ReplaceRepeated', evaluation) if ret: return rules @@ -374,9 +383,13 @@ def apply(self, expr, rules, max, evaluation): if max_count is None or max_count < 0: evaluation.message('ReplaceList', 'innf', 3) return + try: + rules, ret = create_rules( + rules, expr, 'ReplaceList', evaluation, extra_args=[max]) + except PatternError as e: + evaluation.message('Replace','reps', rules) + return None - rules, ret = create_rules( - rules, expr, 'ReplaceList', evaluation, extra_args=[max]) if ret: return rules @@ -1114,7 +1127,8 @@ def init(self, expr, min=1): self.min = min if len(expr.leaves) == 2: leaf_1 = expr.leaves[1] - if (leaf_1.has_form('List', 1, 2) and all(leaf.get_int_value() for leaf in leaf_1.leaves)): + allnumbers = all(not (leaf.get_int_value() is None) for leaf in leaf_1.get_leaves()) + if (leaf_1.has_form('List', 1, 2) and allnumbers ): self.max = leaf_1.leaves[-1].get_int_value() self.min = leaf_1.leaves[0].get_int_value() elif leaf_1.get_int_value(): diff --git a/mathics/core/expression.py b/mathics/core/expression.py index 34c2febe3f..76ca76c809 100644 --- a/mathics/core/expression.py +++ b/mathics/core/expression.py @@ -345,9 +345,10 @@ def do_format(self, evaluation, form): try: expr = self head = self.get_head_name() + leaves = self.get_leaves() include_form = False - if head in formats and len(self.get_leaves()) == 1: - expr = self.leaves[0] + if head in formats and len(leaves) == 1: + expr = leaves[0] if not (form == 'System`OutputForm' and head == 'System`StandardForm'): form = head @@ -367,6 +368,29 @@ def format_expr(expr): return None if form != 'System`FullForm': + # Repeated and RepeatedNull confuse the formatter, + # so we need to hardlink their format rules: + if head == "System`Repeated": + if len(leaves)==1: + return Expression("System`HoldForm", + Expression("System`Postfix", + Expression( + "System`List", + leaves[0] + ),"..",170)) + else: + return Expression("System`HoldForm",expr) + elif head == "System`RepeatedNull": + if len(leaves)==1: + return Expression("System`HoldForm", + Expression("System`Postfix", + Expression( + "System`List", + leaves[0] + ),"...",170)) + else: + return Expression("System`HoldForm",expr) + formatted = format_expr(expr) if formatted is not None: result = formatted.do_format(evaluation, form) diff --git a/mathics/core/parser/tokeniser.py b/mathics/core/parser/tokeniser.py index 5d05ae3414..37d652a650 100644 --- a/mathics/core/parser/tokeniser.py +++ b/mathics/core/parser/tokeniser.py @@ -122,7 +122,7 @@ ('RuleDelayed', r' (\:\>)|\uF51F '), ('UndirectedEdge', r' (\<\-\>)|\u29DF '), ('ReplaceRepeated', r' \/\/\. '), - ('ReplaceAll', r' (\/\.)(?=[^0-9]) '), + ('ReplaceAll', r' \/\. '), ('Postfix', r' \/\/ '),