Updated the calc_engine to use the deque object for its main token listing. Added more robust support for the power operator.

This commit is contained in:
2020-04-24 01:38:36 -05:00
parent c6d063ea35
commit 85d61366a7
+58 -35
View File
@@ -1,16 +1,12 @@
import ptoken
import tokenizer
import queue
import copy
import collections.deque
from collections import deque
debug = True
def calculate_results(tokens):
q = convert_to_queue(tokens)
tokenizer.print_token_list(tokens)
return process_tokens(q, True)
return process_tokens(convert_to_deque(tokens), True)
def process_tokens(tokens, top_level = False):
pending_operations = []
@@ -19,12 +15,23 @@ def process_tokens(tokens, top_level = False):
p_ops_ran = False
while True:
if tokens.empty():
if not tokens:
break
tokenizer.print_token_list(pending_operations)
token = tokens.get()
token = tokens.popleft()
if not top_level and token.type == ptoken.TokenType.exp_end:
if tokens:
look_ahead = tokens[0]
if look_ahead.type == ptoken.TokenType.power:
tokens.popleft()
two_ahead = tokens.popleft()
tmp = process_tokens(convert_to_deque(pending_operations))
power = 5
running_total = operate(tmp, two_ahead.value, look_ahead.type)
break
if token.type == ptoken.TokenType.exp_start:
@@ -32,25 +39,25 @@ def process_tokens(tokens, top_level = False):
pending_operations.append(ptoken.Token(tmp, ptoken.TokenType.constant))
elif token.type == ptoken.TokenType.power:
look_ahead = tokens.get()
look_ahead = tokens.popleft()
pending_operations.append(ptoken.Token(operate(pending_operations.pop().value, look_ahead.value, token.type), ptoken.TokenType.constant))
elif token.type == ptoken.TokenType.add or token.type == ptoken.TokenType.subtract:
if len(pending_operations) > 0 and p_ops_ran:
tmp = convert_to_queue(pending_operations)
if pending_operations and p_ops_ran:
tmp = convert_to_deque(pending_operations)
previous_token = None
while True:
if tmp.empty():
if not tmp:
break
tmp_token = tmp.get()
tmp_token = tmp.popleft()
if tmp_token.type == ptoken.TokenType.constant:
previous_token = tmp_token
elif tmp_token.type == ptoken.TokenType.add or tmp_token.type == ptoken.TokenType.subtract:
look_ahead = tmp.get()
look_ahead = tmp.popleft()
running_total = operate(previous_token.value, look_ahead.value, tmp_token.type)
@@ -59,7 +66,6 @@ def process_tokens(tokens, top_level = False):
pending_operations = []
pending_operations.append(previous_token)
pending_operations.append(token)
#tokenizer.print_token_list(pending_operations)
p_ops_ran = False
elif token.type == ptoken.TokenType.constant:
@@ -67,39 +73,51 @@ def process_tokens(tokens, top_level = False):
p_ops_ran = False
elif token.type == ptoken.TokenType.multiply or token.type == ptoken.TokenType.divide:
look_ahead = tokens.get()
look_behind = pending_operations.pop()
look_ahead = tokens.popleft()
two_ahead = tokens[0]
if look_ahead.type == ptoken.TokenType.exp_start:
look_ahead = ptoken.Token(process_tokens(tokens), ptoken.TokenType.constant)
look_behind = pending_operations.pop()
if two_ahead.type == ptoken.TokenType.power:
tokens.popleft()
three_ahead = tokens.popleft()
if three_ahead.type != ptoken.TokenType.exp_start:
look_ahead = ptoken.Token(operate(look_ahead.value, three_ahead.value, two_ahead.type), ptoken.TokenType.constant)
else:
tmp = process_tokens(tokens)
look_ahead = ptoken.Token(operate(look_ahead.value, tmp, two_ahead.type), ptoken.TokenType.constant)
running_total = operate(look_behind.value, look_ahead.value, token.type)
pending_operations.append(ptoken.Token(running_total, ptoken.TokenType.constant))
p_ops_ran = True
#tokenizer.print_token_list(pending_operations)
if len(pending_operations) > 0:
running_total = handle_pending(convert_to_queue(pending_operations))
#tokenizer.print_token_list(pending_operations)
if pending_operations and power == 0:
if len(pending_operations) == 1 and power == 0:
return float(pending_operations.pop().value)
return handle_pending(convert_to_deque(pending_operations))
return running_total
#handle add/sub
def handle_pending(tokens):
running_total = 0
previous_token = None
while True:
if tokens.empty():
if not tokens:
break
tmp_token = tokens.get()
tmp_token = tokens.popleft()
if tmp_token.type == ptoken.TokenType.constant:
previous_token = tmp_token
elif tmp_token.type == ptoken.TokenType.add or tmp_token.type == ptoken.TokenType.subtract:
look_ahead = tokens.get()
look_ahead = tokens.popleft()
running_total = operate(previous_token.value, look_ahead.value, tmp_token.type)
@@ -107,13 +125,22 @@ def handle_pending(tokens):
return running_total
def convert_to_queue(tokens):
'''def convert_to_queue(tokens):
q = queue.Queue()
for tk in tokens:
q.put(ptoken.Token(tk.value, tk.type))
return q
return q'''
def convert_to_deque(tokens):
deq = deque()
for tk in tokens:
deq.append(tk)
return deq
def operate(n1, n2, tokenType):
n1 = float(n1)
@@ -138,15 +165,11 @@ def operate(n1, n2, tokenType):
raise TypeError("Invalid operator value " + str(tokenType) + ".", tokenType)
def print_t(tokens):
tmp = queue.Queue()
tmp = copy.deepcopy(tokens)
while True:
if tokens.empty():
if not tmp:
break
token = tokens.get()
token = tmp.popleft()
print("%s" %(token.value), end = "")
tmp.put(token)
print()
return tmp