diff --git a/calculator.py b/calculator.py
index 82b41e2..9f8ef75 100644
--- a/calculator.py
+++ b/calculator.py
@@ -1,4 +1,6 @@
from dataclasses import dataclass,make_dataclass
+from collections import deque
+from math import factorial
@dataclass
class Number:
@@ -52,7 +54,7 @@ def Tokenize(s: str) -> [Token]:
def Expression(e: [Token]) -> (int, [Token]):
r, e = Term(e)
while len(e) > 0:
- match e.pop(0):
+ match e.popleft():
case AddOp():
x, e = Term(e)
r += x
@@ -67,7 +69,7 @@ def Expression(e: [Token]) -> (int, [Token]):
def Term(e: [Token]) -> (int, [Token]):
r, e = Factor(e)
while len(e) > 0:
- match e.pop(0):
+ match e.popleft():
case ModOp():
x, e = Factor(e)
r %= x
@@ -96,27 +98,27 @@ def Term(e: [Token]) -> (int, [Token]):
def Factor(e: [Token]) -> (int, [Token]):
assert len(e) > 0
- match e.pop(0):
+ match e.popleft():
case NegOp():
r, e = Factor(e)
- r = -r
+ return -r, e
case Number(n):
- r = n
+ if e and isinstance(e[0], FacOp):
+ e.popleft()
+ return float(factorial(int(n))), e
+ return n, e
case ParenOpen():
r, e = Expression(e)
- assert isinstance(e.pop(0), ParenClose)
-
- if len(e) > 0 and isinstance(e[0], FacOp):
- from math import factorial
- e.pop(0)
- r = float(factorial(int(r)))
-
- # cancer
- assert 'r' in locals()
- return r, e
+ assert isinstance(e.popleft(), ParenClose)
+ if e and isinstance(e[0], FacOp):
+ e.popleft()
+ r = float(factorial(int(r)))
+ return r, e
+ case e:
+ raise SyntaxError(f"invalid syntax: {e}")
# where is my compose
-Evaluate = lambda x: Expression(Tokenize(x))[0]
+Evaluate = lambda x: Expression(deque(Tokenize(x)))[0]
if __name__ == '__main__':
while True:
|