Finished porting the calc engine from C# to Python.

This commit is contained in:
2020-04-08 12:29:26 -05:00
parent 528098d913
commit c42c8471c0
2 changed files with 215 additions and 4 deletions
+211
View File
@@ -3,6 +3,217 @@ import token
def calculate_results(tokens):
return 0
def handle_parenthesis(tokens, call_has_priority = False):
running_value = 0
previous_token = CToken("", token.TokenType.unknown)
while True:
if len(tokens) == 0:
break
current_token = tokens.pop()
if current_token.type == token.TokenType.constant:
previous_token = current_token
elif current_token == token.TokenType.exp_start:
running_value = handle_parenthesis(tokens)
elif current_token.type == token.TokenType.add or current_token.type == token.TokenType.subtract:
look_ahead = tokens.pop()
if look_ahead.type == token.TokenType.exp_start:
tmp = handle_parenthesis(tokens)
if running_value == 0:
running_value = operate(previous_token.value, tmp, current_token.type)
else:
running_value = operate(running_value, tmp, current_token.type)
continue
tokens.append(look_ahead)
tokens.append(current_token)
if not previous_token.type == token.TokenType.unknown:
tokens.append(previous_token)
else:
tokens.append(CToken(running_value, token.TokenType.constant))
running_value = handle_add_and_subtract(tokens)
#Set the previous_token to an invalid state so its not used by mistake.
previous_token.type = token.TokenType.unknown
elif current_token.type == token.TokenType.power:
look_ahead = tokens.pop()
if look_ahead.type == token.TokenType.exp_start:
power_of = handle_parenthesis(tokens, True)
running_value = operate(previous_token.value, power_of, current_token.type)
#Set the previous_token to an invalid state so its not used by mistake.
previous_token.type = token.TokenType.unknown
continue
running_value = operate(previous_token.value, look_ahead.value, current_token.type)
#Set the previous_token to an invalid state so its not used by mistake.
previous_token.type = token.TokenType.unknown
elif current_token.type == token.TokenType.multiply or current_token.type == token.TokenType.divide:
look_ahead = peek_list(tokens)
if look_ahead.type == token.TokenType.exp_start:
tokens.pop()
running_value = operate(previous_token.value, handle_parenthesis(tokens), current_token.type)
#Set the previous_token to an invalid state so its not used by mistake.
previous_token.type = token.TokenType.unknown
continue
tokens.append(current_token)
if not previous_token.type == token.TokenType.unknown:
tokens.append(previous_token)
else:
tokens.append(CToken(running_value, token.TokenType.constant))
running_value = handle_multiply_and_division(tokens)
#Set the previous_token to an invalid state so its not used by mistake.
previous_token.type = token.TokenType.unknown
elif current_token.type == token.TokenType.exp_end:
if len(tokens) > 0 and peek_list(tokens).type == token.TokenType.power:
tokens.pop()
running_value = operate(running_value, tokens.pop().value, token.TokenType.power)
if !caller_has_priority and len(tokens) > 0 and (peek_list(tokens).type == token.TokenType.multiply or peek_list(tokens).type == token.TokenType.divide):
operator = tokens.pop()
two_ahead = tokens.pop()
if two_ahead.type == token.TokenType.exp_start:
running_value = operate(running_value, handle_parenthesis(tokens), operator.type)
else:
running_value = operate(running_value, two_ahead.value, operator.type)
break
return running_value
def handle_multiply_and_division(tokens):
running_value = 0
previous_token = CToken("", token.TokenType.unknown)
while True:
if len(tokens) == 0:
break
current_token = peek_list(tokens)
#check to see if we want to deal with this token here, making sure not to consume it just incase we
#don't want to process it here.
if current_token.type != token.TokenType.multiply and current_token.type != token.TokenType.divide and current_token.type != token.TokenType.constant and current_token.type != token.TokenType.variable:
break
#"Commit" the current token.
current_token = tokens.pop()
if current_token.type == token.TokenType.constant:
previous_token = current_token
continue
elif current_token.type == token.TokenType.multiply or current_token.type == token.TokenType.divide:
look_ahead = tokens.pop()
if look_ahead.type == token.TokenType.exp_start:
tmp = handle_parenthesis(tokens, True)
if running_value == 0:
running_value = operate(previous_token.value, tmp, current_token.type)
else:
running_value = operate(running_value, tmp, current_token.type)
#Set the previous_token to an invalid state so its not used by mistake.
previous_token.type = token.TokenType.unknown
continue
if look_ahead.type == token.TokenType.constant:
if running_value == 0:
running_value = operate(previous_token.value, look_ahead.value, current_token.type)
else:
running_value = operate(running_value, look_ahead.value, current_token.type)
#Set the previous_token to an invalid state so its not used by mistake.
previous_token.type = token.TokenType.unknown
return running_value
def handle_add_and_subtract(tokens):
running_value = 0
previous_token = CToken("", token.TokenType.unknown)
while True:
if len(tokens) == 0:
break
current_token = tokens.pop()
if current_token.type == token.TokenType.constant:
previous_token = current_token
continue
if current_token.type == token.TokenType.exp_end:
tokens.append(current_token)
break
if current_token.type == token.TokenType.exp_start:
running_value = handle_parenthesis(tokens)
elif current_token.type == token.TokenType.add or current_token.type == token.TokenType.subtract:
look_ahead = tokens.pop()
if look_ahead.type == token.TokenType.exp_start:
tmp = handle_parenthesis(tokens)
if running_value == 0:
running_value = operate(previous_token.value, tmp, current_token.type)
else:
running_value = operate(running_value, tmp, current_token.type)
previous_token.type = token.TokenType.unknown
if len(tokens) > 0:
two_ahead = peek_list(tokens)
if two_ahead.type == token.TokenType.multiply or two_ahead.type == token.TokenType.divide:
tokens.append(look_ahead)
tmp = handle_multiply_and_division(tokens)
if running_value == 0:
running_value = operate(previous_token.value, tmp, current_token.type)
else:
running_value = operate(running_value, tmp, current_token.type)
previous_token.type = token.TokenType.unknown
else:
if running_value == 0:
running_value = operate(previous_token.value, look_ahead.value, current_token.type)
else:
running_value = operate(running_value, look_ahead.value, current_token.type)
previous_token.type = token.TokenType.unknown
elif current_token.type == token.TokenType.multiply or current_token.type == token.TokenType.divide:
tokens.append(current_token)
if previous_token.type != token.TokenType.unknown:
tokens.append(previous_token)
else:
tokens.append(CToken(running_value, token.TokenType.constant))
running_value = handle_multiply_and_division(tokens)
previous_token.type = token.TokenType.unknown
return running_value
def peek_list(tokens):
if tokens: