- is now a unary operator
This commit is contained in:
parent
6aec4be490
commit
313e3a4efc
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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__"),
|
||||||
|
@ -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])
|
||||||
|
@ -607,9 +607,7 @@ class MutableTree(Tree):
|
|||||||
*
|
*
|
||||||
> 4
|
> 4
|
||||||
> +
|
> +
|
||||||
| > -
|
| > -2
|
||||||
| | > None
|
|
||||||
| | > 2
|
|
||||||
| > 3
|
| > 3
|
||||||
"""
|
"""
|
||||||
str2mutTree = str2(cls.sink)
|
str2mutTree = str2(cls.sink)
|
||||||
|
Loading…
Reference in New Issue
Block a user