From d93de4d3d6ebc29c898f46467095a99eecdf3548 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Fri, 24 Apr 2020 02:22:05 -0500 Subject: [PATCH] Fixed a bug in the calc_engine where an expression '(a)^(b), where 'a' and 'b' are any float, would cause a crash and patched the tokenizer to better handle negative numbers. --- calc_engine.py | 28 ++++++++++++++++------------ tokenizer.py | 11 ++++++++--- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/calc_engine.py b/calc_engine.py index e981078..eb198eb 100644 --- a/calc_engine.py +++ b/calc_engine.py @@ -6,6 +6,7 @@ from collections import deque debug = True def calculate_results(tokens): + tokenizer.print_token_list(tokens) return process_tokens(convert_to_deque(tokens), True) def process_tokens(tokens, top_level = False): @@ -21,26 +22,34 @@ def process_tokens(tokens, top_level = False): 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: + if look_ahead.type == ptoken.TokenType.power: tokens.popleft() two_ahead = tokens.popleft() tmp = process_tokens(convert_to_deque(pending_operations)) + + if two_ahead.type == ptoken.TokenType.exp_start: + two_ahead = ptoken.Token(process_tokens(tokens), ptoken.TokenType.constant) + power = 5 running_total = operate(tmp, two_ahead.value, look_ahead.type) + break if token.type == ptoken.TokenType.exp_start: tmp = process_tokens(tokens) + pending_operations.append(ptoken.Token(tmp, ptoken.TokenType.constant)) - elif token.type == ptoken.TokenType.power: + elif token.type == ptoken.TokenType.power: look_ahead = tokens.popleft() + #if look_ahead.type == ptoken.TokenType.exp_start: + # look_ahead = ptoken.Token(process_tokens(tokens), 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: @@ -95,7 +104,7 @@ def process_tokens(tokens, top_level = False): pending_operations.append(ptoken.Token(running_total, ptoken.TokenType.constant)) p_ops_ran = True - #tokenizer.print_token_list(pending_operations) + tokenizer.print_token_list(pending_operations) if pending_operations and power == 0: if len(pending_operations) == 1 and power == 0: @@ -108,6 +117,9 @@ def handle_pending(tokens): running_total = 0 previous_token = None + if len(tokens) == 1: + return float(tokens[0].value) + while True: if not tokens: break @@ -125,14 +137,6 @@ def handle_pending(tokens): return running_total -'''def convert_to_queue(tokens): - q = queue.Queue() - - for tk in tokens: - q.put(ptoken.Token(tk.value, tk.type)) - - return q''' - def convert_to_deque(tokens): deq = deque() diff --git a/tokenizer.py b/tokenizer.py index a76119e..71c276e 100644 --- a/tokenizer.py +++ b/tokenizer.py @@ -27,14 +27,19 @@ def get_tokens_from_expression_string(expression_string): elif c == '-' and not parsing_number: if expression_string[i + 1] == '.' or expression_string[i + 1].isdigit(): - if tokens[-1].type == token.TokenType.exp_end: + if token.TokenType.get_operator(tokens[-1].value) == token.TokenType.unknown:#tokens[-1].type == token.TokenType + print(tokens[-1].value) + tokens.append(token.Token('+', token.TokenType.add)) + parsing_number = True + tmp = "-" + '''if tokens[-1].type == token.TokenType.exp_end: tokens.append(token.Token(c, token.TokenType.get_operator(c))) parsing_number = False tmp = "" else: - tokens.append(token.Token('+', token.TokenType.add)) + #tokens.append(token.Token('+', token.TokenType.add)) tmp = "-" - parsing_number = True + parsing_number = True''' else: tokens.append(token.Token(c, token.TokenType.get_operator(c))) parsing_number = False