Add support for not using spaces, align to sample input, optimizations

This commit is contained in:
2024-01-25 18:31:21 -05:00
parent 606991f78a
commit 6232aae708
3 changed files with 51 additions and 30 deletions
+10
View File
@@ -0,0 +1,10 @@
3 + 5 - -2 - 2
x = 3 + 5 - -2 - 2
y = x - (x - 2)
y
ans = (17 - (5 - 20)) - (1 - 11)
ans
ans = ans - (-42 - ans)
ans
(17-(5-20))-(1-11)
+27 -26
View File
@@ -7,6 +7,8 @@
# System Imports
import sys
import re
class Interpreter:
def __init__(this):
# Init basic local variables
@@ -26,6 +28,8 @@ class Interpreter:
if this.inputRaw != "": this.processAssignments(this.inputRaw)
except EOFError:
break
except KeyboardInterrupt:
break
def processAssignments(this, inputString):
# First Step - Determine if assignment operator present
@@ -37,9 +41,7 @@ class Interpreter:
return
# If there are, we save to the variable, not print
assignmentSplit = inputString.split("=") # First Arg: variable, Second Arg: expression
assignmentSplit[0] = assignmentSplit[0][:-1] # Remove trailing space in variable
assignmentSplit[1] = assignmentSplit[1][1:] # Remove leading space in expression
this.variables[assignmentSplit[0]] = this.processParenthesis(assignmentSplit[1])
this.variables[assignmentSplit[0].strip()] = this.processParenthesis(assignmentSplit[1].strip())
this.inputRaw = " " # Reset input to forgo the \n
else:
# If there are no operators, string is set to be evaluated
@@ -48,7 +50,6 @@ class Interpreter:
def processParenthesis(this,inputString):
# Second Step - Determine if expression contains parenthesis
# Recursively designed function to evaluate parenthesis from left to right, inner to outer until no more remain
# print(inputString)
if inputString.count('(') == 0:
# No parenthesis or all parenthesis evaluated
return this.evaluate(inputString)
@@ -70,32 +71,32 @@ class Interpreter:
def evaluate(this,inputString):
# Evalute the "cleaned" expression
# Stripped out all the assignment operators and parenthesis
expressionMap = inputString.split(" ")
# Proper type conversion / verification
expressionMap = list(filter(None, re.split('([^a-zA-Z0-9])', inputString.replace(" ", ""))))
# Varible substitution
for i in range(len(expressionMap)):
# If there is a variable in the expression, substitute the current value in the proper list slot
if expressionMap[i] in this.variables:
expressionMap[i] = int(this.variables[expressionMap[i]])
elif expressionMap[i][:1] == "-" and len(expressionMap[i]) != 1 and expressionMap[i][1:] in this.variables:
expressionMap[i] = int("-"+this.variables[expressionMap[i][1:]])
elif expressionMap[i] != '+' and expressionMap[i] != '-':
# Verifying all operands are proper ints
if expressionMap[i] in this.variables: expressionMap[i] = this.variables[expressionMap[i]]
total = 0
# If there is math to be done, do math
if len(expressionMap) > 1:
# Move around the expression looking to bind operators to operations
for i in range(len(expressionMap)-1):
# If we are at the start of the line, or there is an operation that is not followed by an operation, bind
if (expressionMap[i] == "+" or expressionMap[i] == "-") and (expressionMap[i+1] != "+" and expressionMap[i+1] != "-") or i == 0:
try:
expressionMap[i] = int(expressionMap[i])
# int allows + and - to be bound to an integer and reflected in its positivity/negation. By doing this, all elements of the string can simple be added
total+=(int(expressionMap[i]+expressionMap[i+1])) if (expressionMap[i] == "+" or expressionMap[i] == "-") and (expressionMap[i+1] != "+" and expressionMap[i+1] != "-") else (int(expressionMap[i]))
except:
# throw an error if something in the string is not an operation or a int
Interpreter.throwError("evaluate",f"Unknown symbol '{expressionMap[i]}'. '{expressionMap[i]}' is not a valid input or an undefined variable.")
return "" # empty string for formatting
# After all items in list are either ints or operations, perform operations
# Properly formatting list has the following structure
# [operand, operation, operand, operation, operand, ...]
# Therefore, operating from left to right, take the first set of three (two operands, one operations)
# and store the result in list slot 0
# Remove list slots 1 and 2, and shift the rest of the list down so the next set (one operation, one operand) is in the slot (del)
# When there only remains one (operand) with the result stored, convert back to string and return
while len(expressionMap) > 1:
expressionMap[0] = expressionMap[0] + expressionMap[2] if expressionMap[1] == "+" else expressionMap[0] - expressionMap[2]
del expressionMap[1:3]
return str(expressionMap[0])
return ""
# If there is a - and a - (double negation), swap next operator to a + and carry on
# Swapping next operation to a + is the same as subtracting a negative, you add. this flips the sign of the next operator and ignores the current negation
# A combination + and - is ignored as the negation will be bound to the int and the plus will be discarded
elif expressionMap[i] == "-" and expressionMap[i+1] == "-":
expressionMap[i+1] = '+'
else: #simple math, jsut return what's there
total = expressionMap[0]
return str(total)
PMPVInterpreter = Interpreter()
PMPVInterpreter.startCommandLine()
+10
View File
@@ -0,0 +1,10 @@
8
2
42
126
42