11# -*- coding: utf-8 -*-
22
3- from typing import Any , FrozenSet , Tuple
3+ from typing import FrozenSet , Optional , Tuple
44
55from mathics_scanner .feed import LineFeeder
6+ from mathics_scanner .location import ContainerKind , SourceRange
67
8+ from mathics .core .definitions import Definitions
9+ from mathics .core .element import BaseElement
710from mathics .core .parser .convert import convert
811from mathics .core .parser .feed import MathicsSingleLineFeeder
912from mathics .core .parser .parser import Parser
1215parser = Parser ()
1316
1417
15- def parse (definitions , feeder : LineFeeder ) -> Any :
18+ def parse (definitions , feeder : LineFeeder ) -> BaseElement :
1619 """
1720 Parse input (from the frontend, -e, input files, ToExpression etc).
1821 Look up symbols according to the Definitions instance supplied.
@@ -22,7 +25,9 @@ def parse(definitions, feeder: LineFeeder) -> Any:
2225 return parse_returning_code (definitions , feeder )[0 ]
2326
2427
25- def parse_incrementally_by_line (definitions , feeder : LineFeeder ) -> Any :
28+ def parse_incrementally_by_line (
29+ definitions : Definitions , feeder : LineFeeder
30+ ) -> Optional [BaseElement ]:
2631 """Parse input incrementally by line. This is in contrast to parse() or
2732 parser_returning_code(), which parse the *entire*
2833 input which could be many line.
@@ -50,19 +55,40 @@ def parse_incrementally_by_line(definitions, feeder: LineFeeder) -> Any:
5055 return convert (ast , definitions )
5156
5257
53- def parse_returning_code (definitions , feeder : LineFeeder ) -> Tuple [Any , str ]:
54- """
55- Parse input (from the frontend, -e, input files, ToExpression etc).
58+ def parse_returning_code (
59+ definitions : Definitions , feeder : LineFeeder
60+ ) -> Tuple [BaseElement , str ]:
61+ """Parse input (from the frontend, -e, input files, ToExpression etc).
5662 Look up symbols according to the Definitions instance supplied.
5763
58- Feeder must implement the feed and empty methods, see core/parser/feed.py.
64+ ``feeder`` must implement the ``feed()`` and ``empty()``
65+ methods. See the mathics_scanner.feed module.
66+
5967 """
68+ from mathics .core .expression import Expression
69+
6070 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
71+
72+ # For expressions which make their way to
73+ # FunctionApplyRule, saving a position here is
74+ # extraneous because teh FunctionApplyRule an get
75+ # the position. But deal with this redundancy
76+ # after the dust settles, and we have experience
77+ # on what is desired.
78+ location = (
79+ feeder .container
80+ if feeder .container_kind == ContainerKind .PYTHON
81+ else SourceRange (0 , parser .tokeniser .pos , feeder .container_index )
82+ )
83+ source_text = parser .tokeniser .source_text
84+
85+ if ast is None :
86+ return None , source_text
87+
88+ converted = convert (ast , definitions )
89+ if isinstance (converted , Expression ):
90+ converted .location = location
91+ return converted , source_text
6692
6793
6894class SystemDefinitions :
@@ -111,9 +137,12 @@ def lookup_name(self, name):
111137 return ensure_context (name , context )
112138
113139
114- def parse_builtin_rule (string , definitions = SystemDefinitions ()):
140+ def parse_builtin_rule (string , definitions = SystemDefinitions (), location = None ):
115141 """
116142 Parse rules specified in builtin docstrings/attributes. Every symbol
117143 in the input is created in the System` context.
118144 """
119- return parse (definitions , MathicsSingleLineFeeder (string , "<builtin_rules>" ))
145+ return parse (
146+ definitions ,
147+ MathicsSingleLineFeeder (string , location , ContainerKind .PYTHON ),
148+ )
0 commit comments