summary refs log tree commit diff
path: root/calculator.py
diff options
context:
space:
mode:
authortzlil <tzlils@protonmail.com>2023-11-19 05:26:34 +0200
committertzlil <tzlils@protonmail.com>2023-11-19 05:26:34 +0200
commit3ae98c4b53a09ce89eb1bf87a7b027fa5023ad71 (patch)
tree947e5d2d09d14d166a76e61e7bc94239e89631da /calculator.py
parentfa69a2f1bdd6824adf91620db26c9902f9eb1698 (diff)
switch to deque HEAD master
Diffstat (limited to 'calculator.py')
-rw-r--r--calculator.py34
1 files changed, 18 insertions, 16 deletions
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: