Finished porting the calc engine from C# to Python.
This commit is contained in:
+211
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user