- 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
class ComputeError(Exception):
pass
def compute(node, left_v, right_v):
"""
Computing a node
@ -20,22 +23,26 @@ def compute(node, left_v, right_v):
>>> compute("+", 1, 2)
3
>>> compute("-", 1, 2)
-1
>>> compute("-", None, 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]
lv = left_v
rv = right_v
if lv is None:
return op["_operate"](rv)()
try:
return op["operate"](lv)(rv)
except NotImplemented:
return op["roperate"](rv)(lv)
if op['arity'] == 1:
if lv is None:
return op["operate"](rv)()
else:
raise ComputeError("left_v need to be None for operator with arity 1")
else:
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.
class OperatorError(Exception):
pass
OPERATORS = {
"+": {'repr': "+",
'arity': 2,
'precedence': 0,
'operate': lambda x: x.__getattribute__("__add__"),
'roperate': lambda x: x.__getattribute__("__radd__"),
},
"-": {'repr': "-",
'arity': 1,
'precedence': 1,
'_operate': lambda x: x.__getattribute__("__neg__"),
'operate': lambda x: x.__getattribute__("__sub__"),
'roperate': lambda x: x.__getattribute__("__rsub__"),
'operate': lambda x: x.__getattribute__("__neg__"),
},
"*": {'repr': "*",
'arity': 2,
'precedence': 2,
'operate': lambda x: x.__getattribute__("__mul__"),
'roperate': lambda x: x.__getattribute__("__rmul__"),
},
"/": {'repr': "/",
'arity': 2,
'precedence': 3,
'operate': lambda x: x.__getattribute__("__div__"),
'roperate': lambda x: x.__getattribute__("__rdiv__"),
},
"^": {'repr': "^",
'arity': 2,
'precedence': 4,
'operate': lambda x: x.__getattribute__("__pow__"),
'roperate': lambda x: x.__getattribute__("__rpow__"),

View File

@ -17,6 +17,10 @@ from .operator import is_operator
__all__ = ["str2", ]
class ParsingError(Exception):
pass
def maybe_it_is(cara):
""" Return a function which return
@ -417,13 +421,38 @@ def lookforNumbers(target):
... str2list.send(i)
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)
>>> for i in ".34*67":
... a = str2list.send(i)
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:
@ -442,13 +471,21 @@ def lookforNumbers(target):
except ValueError:
if tok == '.':
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:
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:
current += tok
elif tok == '-':
if len(current) > 0:
target_.send(typifiy_numbers(current))
target_.send('+')
current = tok
else:
if current:
if current == '-':
target_.send(current)
current = ""
elif current:
target_.send(typifiy_numbers(current))
current = ""
target_.send(tok)
@ -552,6 +589,22 @@ def str2(sink):
>>> t = str2nestedlist(exp)
>>> print(t)
[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
>>> str2tree = str2(MutableTree.sink)
@ -587,6 +640,43 @@ def str2(sink):
> +
| > 3
| > 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)
operator_corout = partial(concurent_broadcast, lookfors = [lfop])

View File

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