- is now a unary operator

This commit is contained in:
Bertrand Benjamin 2018-03-07 16:26:06 +03:00
parent 6aec4be490
commit 313e3a4efc
4 changed files with 122 additions and 21 deletions

View File

@ -12,6 +12,9 @@ Evaluating a binary tree
from .operator import OPERATORS from .operator import OPERATORS
class ComputeError(Exception):
pass
def compute(node, left_v, right_v): def compute(node, left_v, right_v):
""" """
Computing a node Computing a node
@ -20,22 +23,26 @@ def compute(node, left_v, right_v):
>>> compute("+", 1, 2) >>> compute("+", 1, 2)
3 3
>>> compute("-", 1, 2)
-1
>>> compute("-", None, 2) >>> compute("-", None, 2)
-2 -2
>>> compute("-", 1, 2)
Traceback (most recent call last):
...
mapytex.calculus.core.evaluate.ComputeError: left_v need to be None for operator with arity 1
""" """
op = OPERATORS[node] op = OPERATORS[node]
lv = left_v lv = left_v
rv = right_v rv = right_v
if lv is None: if op['arity'] == 1:
return op["_operate"](rv)() if lv is None:
return op["operate"](rv)()
try: else:
return op["operate"](lv)(rv) raise ComputeError("left_v need to be None for operator with arity 1")
except NotImplemented: else:
return op["roperate"](rv)(lv) try:
return op["operate"](lv)(rv)
except NotImplemented:
return op["roperate"](rv)(lv)

View File

@ -6,29 +6,35 @@
# #
# Distributed under terms of the MIT license. # Distributed under terms of the MIT license.
class OperatorError(Exception):
pass
OPERATORS = { OPERATORS = {
"+": {'repr': "+", "+": {'repr': "+",
'arity': 2,
'precedence': 0, 'precedence': 0,
'operate': lambda x: x.__getattribute__("__add__"), 'operate': lambda x: x.__getattribute__("__add__"),
'roperate': lambda x: x.__getattribute__("__radd__"), 'roperate': lambda x: x.__getattribute__("__radd__"),
}, },
"-": {'repr': "-", "-": {'repr': "-",
'arity': 1,
'precedence': 1, 'precedence': 1,
'_operate': lambda x: x.__getattribute__("__neg__"), 'operate': lambda x: x.__getattribute__("__neg__"),
'operate': lambda x: x.__getattribute__("__sub__"),
'roperate': lambda x: x.__getattribute__("__rsub__"),
}, },
"*": {'repr': "*", "*": {'repr': "*",
'arity': 2,
'precedence': 2, 'precedence': 2,
'operate': lambda x: x.__getattribute__("__mul__"), 'operate': lambda x: x.__getattribute__("__mul__"),
'roperate': lambda x: x.__getattribute__("__rmul__"), 'roperate': lambda x: x.__getattribute__("__rmul__"),
}, },
"/": {'repr': "/", "/": {'repr': "/",
'arity': 2,
'precedence': 3, 'precedence': 3,
'operate': lambda x: x.__getattribute__("__div__"), 'operate': lambda x: x.__getattribute__("__div__"),
'roperate': lambda x: x.__getattribute__("__rdiv__"), 'roperate': lambda x: x.__getattribute__("__rdiv__"),
}, },
"^": {'repr': "^", "^": {'repr': "^",
'arity': 2,
'precedence': 4, 'precedence': 4,
'operate': lambda x: x.__getattribute__("__pow__"), 'operate': lambda x: x.__getattribute__("__pow__"),
'roperate': lambda x: x.__getattribute__("__rpow__"), 'roperate': lambda x: x.__getattribute__("__rpow__"),

View File

@ -17,6 +17,10 @@ from .operator import is_operator
__all__ = ["str2", ] __all__ = ["str2", ]
class ParsingError(Exception):
pass
def maybe_it_is(cara): def maybe_it_is(cara):
""" Return a function which return """ Return a function which return
@ -417,13 +421,38 @@ def lookforNumbers(target):
... str2list.send(i) ... str2list.send(i)
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: Can't build a number with 2 dots (current is 12.3) mapytex.calculus.core.str2.ParsingError: Can't build a number with 2 dots (current is 12.3)
>>> str2list = lookforNumbers(list_sink) >>> str2list = lookforNumbers(list_sink)
>>> for i in ".34*67": >>> for i in ".34*67":
... a = str2list.send(i) ... a = str2list.send(i)
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: Can't build a number starting with a dot mapytex.calculus.core.str2.ParsingError: Can't build a number starting with a dot
>>> str2list = lookforNumbers(list_sink)
>>> for i in "12-34":
... str2list.send(i)
>>> a = str2list.throw(STOOOP)
>>> print(a)
[12, '+', -34]
>>> str2list = lookforNumbers(list_sink)
>>> for i in "-12+34":
... str2list.send(i)
>>> a = str2list.throw(STOOOP)
>>> print(a)
[-12, '+', 34]
>>> str2list = lookforNumbers(list_sink)
>>> for i in "3-1.2":
... str2list.send(i)
>>> a = str2list.throw(STOOOP)
>>> print(a)
[3, '+', Decimal('-1.2')]
>>> str2list = lookforNumbers(list_sink)
>>> for i in "3-(1.2)":
... str2list.send(i)
>>> a = str2list.throw(STOOOP)
>>> print(a)
[3, '+', '-', '(', Decimal('1.2'), ')']
""" """
try: try:
@ -442,13 +471,21 @@ def lookforNumbers(target):
except ValueError: except ValueError:
if tok == '.': if tok == '.':
if "." in current: if "." in current:
raise ValueError(f"Can't build a number with 2 dots (current is {current})") raise ParsingError(f"Can't build a number with 2 dots (current is {current})")
elif len(current) == 0: elif len(current) == 0:
raise ValueError(f"Can't build a number starting with a dot") raise ParsingError(f"Can't build a number starting with a dot")
else: else:
current += tok current += tok
elif tok == '-':
if len(current) > 0:
target_.send(typifiy_numbers(current))
target_.send('+')
current = tok
else: else:
if current: if current == '-':
target_.send(current)
current = ""
elif current:
target_.send(typifiy_numbers(current)) target_.send(typifiy_numbers(current))
current = "" current = ""
target_.send(tok) target_.send(tok)
@ -552,6 +589,22 @@ def str2(sink):
>>> t = str2nestedlist(exp) >>> t = str2nestedlist(exp)
>>> print(t) >>> print(t)
[2, '*', 'a', '*', [3, '+', 4]] [2, '*', 'a', '*', [3, '+', 4]]
>>> exp = "-12(3-4)"
>>> t = str2nestedlist(exp)
>>> print(t)
[-12, '*', [3, '+', -4]]
>>> exp = "-a(3-4)"
>>> t = str2nestedlist(exp)
>>> print(t)
['-', 'a', '*', [3, '+', -4]]
>>> exp = "3-a"
>>> t = str2nestedlist(exp)
>>> print(t)
[3, '+', '-', 'a']
>>> exp = "1-(3+4)"
>>> t = str2nestedlist(exp)
>>> print(t)
[1, '+', '-', [3, '+', 4]]
>>> from .tree import MutableTree >>> from .tree import MutableTree
>>> str2tree = str2(MutableTree.sink) >>> str2tree = str2(MutableTree.sink)
@ -587,6 +640,43 @@ def str2(sink):
> + > +
| > 3 | > 3
| > 4 | > 4
>>> exp = "-12(3-4)"
>>> t = str2tree(exp)
>>> print(t)
*
> -12
> +
| > 3
| > -4
>>> exp = "-a(3-4)"
>>> t = str2tree(exp)
>>> print(t)
-
> None
> *
| > a
| > +
| | > 3
| | > -4
>>> exp = "3-a"
>>> t = str2tree(exp)
>>> print(t)
+
> 3
> -
| > None
| > a
>>> exp = "1-(3+4)"
>>> t = str2tree(exp)
>>> print(t)
+
> 1
> -
| > None
| > +
| | > 3
| | > 4
""" """
lfop = lookfor(is_operator) lfop = lookfor(is_operator)
operator_corout = partial(concurent_broadcast, lookfors = [lfop]) operator_corout = partial(concurent_broadcast, lookfors = [lfop])

View File

@ -607,9 +607,7 @@ class MutableTree(Tree):
* *
> 4 > 4
> + > +
| > - | > -2
| | > None
| | > 2
| > 3 | > 3
""" """
str2mutTree = str2(cls.sink) str2mutTree = str2(cls.sink)