diff --git a/mapytex/calculus/core/str2.py b/mapytex/calculus/core/str2.py index 0024d06..0630db0 100644 --- a/mapytex/calculus/core/str2.py +++ b/mapytex/calculus/core/str2.py @@ -11,7 +11,7 @@ Converting a string with coroutines """ from functools import partial -from decimal import Decimal +from decimal import Decimal, InvalidOperation from .coroutine import * from .operator import is_operator from .MO import moify @@ -420,13 +420,13 @@ def lookforNumbers(target): ... str2list.send(i) Traceback (most recent call last): ... - mapytex.calculus.core.str2.ParsingError: Can't build a number with 2 dots (current is 12.3) + mapytex.calculus.core.str2.ParsingError: Can't build decimal with '12.3' >>> str2list = lookforNumbers(list_sink) >>> for i in ".34*67": ... a = str2list.send(i) Traceback (most recent call last): ... - mapytex.calculus.core.str2.ParsingError: Can't build a number starting with a dot + mapytex.calculus.core.str2.ParsingError: Can't build decimal with '' >>> str2list = lookforNumbers(list_sink) >>> for i in "12-34": @@ -468,31 +468,58 @@ def lookforNumbers(target): int(tok) except ValueError: if tok == '.': - if "." in current: - raise ParsingError(f"Can't build a number with 2 dots (current is {current})") - elif not current: - raise ParsingError(f"Can't build a number starting with a dot") - else: + if current.replace("-", "", 1).isdigit(): current += tok + else: + raise ParsingError(f"Can't build decimal with '{current}'") elif tok == '-': - if current: - target_.send(typifiy_numbers(current)) - target_.send('+') - current = tok - else: - if current == '-': + if current == "": + current = tok + elif current == ("("): target_.send(current) - current = "" - elif current: - target_.send(typifiy_numbers(current)) - current = "" - target_.send(tok) + current = "-" + elif is_operator(current): + if current == "-": + current = "+" + else: + target_.send(current) + current = "-" + else: + try: + target_.send(typifiy_numbers(current)) + except InvalidOperation: + target_.send(current) + target_.send('+') + current = tok + else: + if current == "": + current = tok + elif is_operator(current) and is_operator(tok): + raise ParsingError(f"Can't parse with 2 operators next to each other") + else: + try: + target_.send(typifiy_numbers(current)) + except InvalidOperation: + target_.send(current) + current = tok else: - current += tok + if current == "": + current = tok + elif current == "-": + current += tok + elif current.replace(".", "", 1).replace("-", "", 1).isdigit(): + # make sure no double dotted number can't reach this place! + current += tok + else: + target_.send(current) + current = tok except STOOOP as err: if current: - target_.send(typifiy_numbers(current)) + try: + target_.send(typifiy_numbers(current)) + except InvalidOperation: + target_.send(current) yield target_.throw(err) def typifiy_numbers(number): @@ -681,6 +708,14 @@ def str2(sink, convert_to_mo=True): > - | > None | > a + + >>> exp = "a - 3" + >>> t = str2tree(exp) + >>> print(t) + + + > a + > -3 + >>> exp = "1-(3+4)" >>> t = str2tree(exp) >>> print(t) diff --git a/mapytex/calculus/core/tree.py b/mapytex/calculus/core/tree.py index e72f489..5a4f4d9 100644 --- a/mapytex/calculus/core/tree.py +++ b/mapytex/calculus/core/tree.py @@ -218,7 +218,7 @@ class Tree(): >>> Tree.from_any_tree(t) Traceback (most recent call last): ... - TypeError: Tree can't have empty node or leaf + TypeError: Tree can't have empty node or leaf. Got node = * and right_value = None >>> t = MutableTree("-", None, 1) >>> print(t) - @@ -243,7 +243,7 @@ class Tree(): if node is None or \ right_value is None: - raise TypeError("Tree can't have empty node or leaf") + raise TypeError(f"Tree can't have empty node or leaf. Got node = {node} and right_value = {right_value}") try: left_value.IMLEAF