Skip to content

Commit 253e925

Browse files
authored
Lesser changes and possible bugs encountered adding location information #1413 (#1414)
These are changes and slight bugs encounted in PR #1413 As a separate PR, this should reduce the size and effort for dealing with #1413, which I'll rebase after this is merged
1 parent 620049d commit 253e925

9 files changed

Lines changed: 63 additions & 20 deletions

File tree

mathics/builtin/patterns/basic.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from mathics.core.builtin import PatternObject
1111
from mathics.core.evaluation import Evaluation
1212
from mathics.core.expression import Expression
13+
from mathics.core.symbols import BaseElement
1314

1415
# This tells documentation how to sort this module
1516
sort_order = "mathics.builtin.rules-and-patterns.basic"
@@ -89,7 +90,7 @@ class Blank(_Blank):
8990
}
9091
summary_text = "match to any single expression"
9192

92-
def match(self, expression: Expression, pattern_context: dict):
93+
def match(self, expression: BaseElement, pattern_context: dict):
9394
vars_dict = pattern_context["vars_dict"]
9495
yield_func = pattern_context["yield_func"]
9596

mathics/core/definitions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from mathics.core.attributes import A_NO_ATTRIBUTES
1919
from mathics.core.convert.expression import to_mathics_list
2020
from mathics.core.element import BaseElement, fully_qualified_symbol_name
21-
from mathics.core.load_builtin import definition_contribute, mathics3_builtins_modules
2221
from mathics.core.rules import BaseRule, Rule
2322
from mathics.core.symbols import Atom, Symbol, strip_context
2423
from mathics.core.util import canonic_filename
@@ -1066,6 +1065,10 @@ def load_builtin_definitions(
10661065
"""
10671066
Load definitions from Builtin classes, autoload files and extension modules.
10681067
"""
1068+
from mathics.core.load_builtin import (
1069+
definition_contribute,
1070+
mathics3_builtins_modules,
1071+
)
10691072
from mathics.eval.files_io.files import get_file_time
10701073
from mathics.eval.pymathics import PyMathicsLoadException, load_pymathics_module
10711074
from mathics.session import autoload_files

mathics/core/expression.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ def eval_range(indices):
11931193
recompute_properties = False
11941194
for index in indices:
11951195
element = elements[index]
1196-
if not element.has_form("Unevaluated", 1):
1196+
if not (element.is_literal or element.has_form("Unevaluated", 1)):
11971197
if isinstance(element, EvalMixin):
11981198
new_value = element.evaluate(evaluation)
11991199
# We need id() because != by itself is too permissive
@@ -1209,7 +1209,7 @@ def rest_range(indices):
12091209
return
12101210
for index in indices:
12111211
element = elements[index]
1212-
if element.has_form("Evaluate", 1):
1212+
if not element.is_literal and element.has_form("Evaluate", 1):
12131213
if isinstance(element, EvalMixin):
12141214
new_value = element.evaluate(evaluation)
12151215
# We need id() because != by itself is too permissive

mathics/core/parser/convert.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from mathics.core.atoms import Integer, MachineReal, PrecisionReal, Rational, String
1212
from mathics.core.convert.expression import to_expression, to_mathics_list
13+
from mathics.core.element import BaseElement
1314
from mathics.core.number import RECONSTRUCT_MACHINE_PRECISION_DIGITS
1415
from mathics.core.parser.ast import (
1516
Filename as AST_Filename,
@@ -189,7 +190,7 @@ class Converter(GenericConverter):
189190
def __init__(self):
190191
self.definitions = None
191192

192-
def convert(self, node, definitions):
193+
def convert(self, node, definitions) -> BaseElement:
193194
self.definitions = definitions
194195
result = self.do_convert(node)
195196
self.definitions = None

mathics/core/parser/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
# FIXME: should rework so we don't have to do this
5050
# We have the character name ImaginaryI and ImaginaryJ, but we should
5151
# have the *operator* name, "I".
52-
special_symbols["\uF74F"] = special_symbols["\uF74E"] = "I"
52+
special_symbols["\uf74f"] = special_symbols["\uf74e"] = "I"
5353

5454

5555
# An operator precedence value that will ensure that whatever operator

mathics/core/parser/util.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# -*- coding: utf-8 -*-
22

3-
from typing import Any, FrozenSet, Tuple
3+
from typing import FrozenSet, Optional, Tuple
44

55
from mathics_scanner.feed import LineFeeder
66

7+
from mathics.core.definitions import Definitions
8+
from mathics.core.element import BaseElement
79
from mathics.core.parser.convert import convert
810
from mathics.core.parser.feed import MathicsSingleLineFeeder
911
from mathics.core.parser.parser import Parser
@@ -12,7 +14,7 @@
1214
parser = Parser()
1315

1416

15-
def parse(definitions, feeder: LineFeeder) -> Any:
17+
def parse(definitions, feeder: LineFeeder) -> Optional[BaseElement]:
1618
"""
1719
Parse input (from the frontend, -e, input files, ToExpression etc).
1820
Look up symbols according to the Definitions instance supplied.
@@ -22,7 +24,9 @@ def parse(definitions, feeder: LineFeeder) -> Any:
2224
return parse_returning_code(definitions, feeder)[0]
2325

2426

25-
def parse_incrementally_by_line(definitions, feeder: LineFeeder) -> Any:
27+
def parse_incrementally_by_line(
28+
definitions: Definitions, feeder: LineFeeder
29+
) -> Optional[BaseElement]:
2630
"""Parse input incrementally by line. This is in contrast to parse() or
2731
parser_returning_code(), which parse the *entire*
2832
input which could be many line.
@@ -50,19 +54,28 @@ def parse_incrementally_by_line(definitions, feeder: LineFeeder) -> Any:
5054
return convert(ast, definitions)
5155

5256

53-
def parse_returning_code(definitions, feeder: LineFeeder) -> Tuple[Any, str]:
54-
"""
55-
Parse input (from the frontend, -e, input files, ToExpression etc).
57+
def parse_returning_code(
58+
definitions: Definitions, feeder: LineFeeder
59+
) -> Tuple[Optional[BaseElement], str]:
60+
"""Parse input (from the frontend, -e, input files, ToExpression etc).
5661
Look up symbols according to the Definitions instance supplied.
5762
58-
Feeder must implement the feed and empty methods, see core/parser/feed.py.
63+
``feeder`` must implement the ``feed()`` and ``empty()``
64+
methods. See the mathics_scanner.feed module.
65+
5966
"""
67+
from mathics.core.expression import Expression
68+
6069
ast = parser.parse(feeder)
61-
source_code = parser.tokeniser.code if hasattr(parser.tokeniser, "code") else ""
62-
if ast is not None:
63-
return convert(ast, definitions), source_code
64-
else:
65-
return None, source_code
70+
71+
source_text = parser.tokeniser.source_text
72+
73+
if ast is None:
74+
return None, source_text
75+
76+
converted = convert(ast, definitions)
77+
78+
return converted, source_text
6679

6780

6881
class SystemDefinitions:

mathics/core/pattern.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,12 @@ def get_match_count(self, vars_dict: Optional[dict] = None) -> Tuple[int, int]:
399399
"""The number of matches"""
400400
return (1, 1)
401401

402+
@property
403+
def short_name(self) -> str:
404+
return (
405+
self.atom.short_name if hasattr(self.atom, "short_name") else str(self.atom)
406+
)
407+
402408

403409
# class StopGenerator_ExpressionPattern_match(StopGenerator):
404410
# pass

mathics/core/symbols.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ def evaluate(self, evaluation):
495495
for rule in rules:
496496
result = rule.apply(self, evaluation, fully=True)
497497
if result is not None and not result.sameQ(self):
498+
if result.is_literal:
499+
return result
498500
return result.evaluate(evaluation)
499501
return self
500502

@@ -743,7 +745,12 @@ class BooleanType(SymbolConstant):
743745
the constant is either SymbolTrue or SymbolFalse.
744746
"""
745747

746-
pass
748+
@property
749+
def is_literal(self) -> bool:
750+
"""
751+
We don't allow changing Boolean values True and False.
752+
"""
753+
return True
747754

748755

749756
def symbol_set(*symbols: Symbol) -> FrozenSet[Symbol]:

mathics/eval/tracing.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,18 @@ def skip_trivial_evaluation(expr, status: str, orig_expr=None) -> bool:
2626
* the evaluation is a literal that evaluates to the same thing,
2727
* evaluating a Symbol which the Symbol.
2828
* Showing the return value of a ListExpression literal
29+
* Evaluating Pattern[] which define a pattern.
2930
"""
31+
from mathics.core.expression import Expression
3032
from mathics.core.symbols import Symbol, SymbolConstant
33+
from mathics.core.systemsymbols import SymbolBlank, SymbolPattern
34+
35+
if isinstance(expr, tuple):
36+
expr = expr[0]
37+
38+
if isinstance(expr, Expression):
39+
if expr.head in (SymbolPattern, SymbolBlank):
40+
return True
3141

3242
if status == "Returning":
3343
if (
@@ -39,7 +49,9 @@ def skip_trivial_evaluation(expr, status: str, orig_expr=None) -> bool:
3949
return True
4050
pass
4151
if isinstance(expr, Symbol) and not isinstance(expr, SymbolConstant):
42-
# Evaluation of a symbol, like Plus isn't that interesting
52+
# Evaluation of a symbol, like Plus isn't that interesting.
53+
# Right now, SymbolConstant are not literals. If this
54+
# changes, we don't need this clause.
4355
return True
4456

4557
else:

0 commit comments

Comments
 (0)