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:
+56
-33
@@ -1,16 +1,12 @@
|
|||||||
import ptoken
|
import ptoken
|
||||||
import tokenizer
|
import tokenizer
|
||||||
import queue
|
|
||||||
import copy
|
import copy
|
||||||
import collections.deque
|
from collections import deque
|
||||||
|
|
||||||
debug = True
|
debug = True
|
||||||
|
|
||||||
def calculate_results(tokens):
|
def calculate_results(tokens):
|
||||||
q = convert_to_queue(tokens)
|
return process_tokens(convert_to_deque(tokens), True)
|
||||||
tokenizer.print_token_list(tokens)
|
|
||||||
|
|
||||||
return process_tokens(q, True)
|
|
||||||
|
|
||||||
def process_tokens(tokens, top_level = False):
|
def process_tokens(tokens, top_level = False):
|
||||||
pending_operations = []
|
pending_operations = []
|
||||||
@@ -19,12 +15,23 @@ def process_tokens(tokens, top_level = False):
|
|||||||
p_ops_ran = False
|
p_ops_ran = False
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if tokens.empty():
|
if not tokens:
|
||||||
break
|
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 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
|
break
|
||||||
|
|
||||||
if token.type == ptoken.TokenType.exp_start:
|
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))
|
pending_operations.append(ptoken.Token(tmp, ptoken.TokenType.constant))
|
||||||
|
|
||||||
elif token.type == ptoken.TokenType.power:
|
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))
|
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:
|
elif token.type == ptoken.TokenType.add or token.type == ptoken.TokenType.subtract:
|
||||||
if len(pending_operations) > 0 and p_ops_ran:
|
if pending_operations and p_ops_ran:
|
||||||
tmp = convert_to_queue(pending_operations)
|
tmp = convert_to_deque(pending_operations)
|
||||||
previous_token = None
|
previous_token = None
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if tmp.empty():
|
if not tmp:
|
||||||
break
|
break
|
||||||
|
|
||||||
tmp_token = tmp.get()
|
tmp_token = tmp.popleft()
|
||||||
|
|
||||||
if tmp_token.type == ptoken.TokenType.constant:
|
if tmp_token.type == ptoken.TokenType.constant:
|
||||||
previous_token = tmp_token
|
previous_token = tmp_token
|
||||||
elif tmp_token.type == ptoken.TokenType.add or tmp_token.type == ptoken.TokenType.subtract:
|
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)
|
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 = []
|
||||||
pending_operations.append(previous_token)
|
pending_operations.append(previous_token)
|
||||||
pending_operations.append(token)
|
pending_operations.append(token)
|
||||||
#tokenizer.print_token_list(pending_operations)
|
|
||||||
p_ops_ran = False
|
p_ops_ran = False
|
||||||
|
|
||||||
elif token.type == ptoken.TokenType.constant:
|
elif token.type == ptoken.TokenType.constant:
|
||||||
@@ -67,12 +73,22 @@ def process_tokens(tokens, top_level = False):
|
|||||||
p_ops_ran = False
|
p_ops_ran = False
|
||||||
|
|
||||||
elif token.type == ptoken.TokenType.multiply or token.type == ptoken.TokenType.divide:
|
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:
|
if look_ahead.type == ptoken.TokenType.exp_start:
|
||||||
look_ahead = ptoken.Token(process_tokens(tokens), ptoken.TokenType.constant)
|
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)
|
running_total = operate(look_behind.value, look_ahead.value, token.type)
|
||||||
|
|
||||||
@@ -81,25 +97,27 @@ def process_tokens(tokens, top_level = False):
|
|||||||
|
|
||||||
#tokenizer.print_token_list(pending_operations)
|
#tokenizer.print_token_list(pending_operations)
|
||||||
|
|
||||||
if len(pending_operations) > 0:
|
if pending_operations and power == 0:
|
||||||
running_total = handle_pending(convert_to_queue(pending_operations))
|
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
|
return running_total
|
||||||
|
#handle add/sub
|
||||||
def handle_pending(tokens):
|
def handle_pending(tokens):
|
||||||
running_total = 0
|
running_total = 0
|
||||||
previous_token = None
|
previous_token = None
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if tokens.empty():
|
if not tokens:
|
||||||
break
|
break
|
||||||
|
|
||||||
tmp_token = tokens.get()
|
tmp_token = tokens.popleft()
|
||||||
|
|
||||||
if tmp_token.type == ptoken.TokenType.constant:
|
if tmp_token.type == ptoken.TokenType.constant:
|
||||||
previous_token = tmp_token
|
previous_token = tmp_token
|
||||||
elif tmp_token.type == ptoken.TokenType.add or tmp_token.type == ptoken.TokenType.subtract:
|
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)
|
running_total = operate(previous_token.value, look_ahead.value, tmp_token.type)
|
||||||
|
|
||||||
@@ -107,13 +125,22 @@ def handle_pending(tokens):
|
|||||||
|
|
||||||
return running_total
|
return running_total
|
||||||
|
|
||||||
def convert_to_queue(tokens):
|
'''def convert_to_queue(tokens):
|
||||||
q = queue.Queue()
|
q = queue.Queue()
|
||||||
|
|
||||||
for tk in tokens:
|
for tk in tokens:
|
||||||
q.put(ptoken.Token(tk.value, tk.type))
|
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):
|
def operate(n1, n2, tokenType):
|
||||||
n1 = float(n1)
|
n1 = float(n1)
|
||||||
@@ -138,15 +165,11 @@ def operate(n1, n2, tokenType):
|
|||||||
raise TypeError("Invalid operator value " + str(tokenType) + ".", tokenType)
|
raise TypeError("Invalid operator value " + str(tokenType) + ".", tokenType)
|
||||||
|
|
||||||
def print_t(tokens):
|
def print_t(tokens):
|
||||||
tmp = queue.Queue()
|
tmp = copy.deepcopy(tokens)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if tokens.empty():
|
if not tmp:
|
||||||
break
|
break
|
||||||
token = tokens.get()
|
token = tmp.popleft()
|
||||||
|
|
||||||
print("%s" %(token.value), end = "")
|
print("%s" %(token.value), end = "")
|
||||||
tmp.put(token)
|
|
||||||
print()
|
print()
|
||||||
|
|
||||||
return tmp
|
|
||||||
|
|||||||
Reference in New Issue
Block a user