Files
COS301-HW1/interpreter.py
T

85 lines
3.6 KiB
Python

## Interpreter for PMPV Language
# @author Nicholas Pease
# Resources
# Python String Reference: https://www.w3schools.com/python/python_ref_string.asp
# System Imports
import sys
class Interpreter:
def __init__(this):
this.inputRaw = ""
this.inputMap = ""
this.variables = {}
@staticmethod
def error(module,message):
print(f'[Interpreter] ({str(module)}) Error: {str(message)}', file=sys.stderr)
def startCommandLine(this):
while this.inputRaw != ":q":
this.inputRaw = input()
this.processAssignments()
def processAssignments(this):
# First Step - Determine if assignment operator present
if this.inputRaw.count('=') != 0:
# Working with Assignment Operator
# Stop immediately if multiple assignment operators in string
if this.inputRaw.count('=') > 1:
Interpreter.error("processAssignments","Multiple assignment operators in use (1 max)")
return
assignmentSplit = this.inputRaw.split("=") # First Arg: variable, Second Arg: expression
for i in range(0, 1): assignmentSplit[i].strip()
#assignmentSplit[0] = assignmentSplit[0][:-1] # Remove trailing space in variable
#assignmentSplit[1] = assignmentSplit[1][1:] # Remove leading space in expression
this.variables[assignmentSplit[1]] = this.processParenthesis(assignmentSplit[1])
else:
# Direct Result Printing
print(this.processParenthesis(this.inputRaw))
def processParenthesis(this,inputString):
# Second Step - Determine if expression contains parenthesis and split into subexpressions
if inputString.count('(') == 0:
# No Parenthesis, process and return
return this.evaluate(inputString)
else:
# Has Parenthesis, process and return
if inputString.count('(') == inputString.count(')'):
i = 0
while inputString[i] != ')':
if inputString[i] == '(':
start = i
if inputString[i] != ')':
i+=1
inputString = inputString[:start] + this.evaluate(inputString[start+1:i]) + inputString[i+1:]
print(inputString)
return this.processParenthesis(inputString)
else:
Interpreter.error("processParenthesis", "Parenthesis Mismatch, Ensure all Parenthesis are Closed")
def evaluate(this,inputString):
expressionMap = inputString.split(" ")
for i in range(len(expressionMap)):
if expressionMap[i] in this.variables:
expressionMap[i] = this.variables[expressionMap[i]]
elif expressionMap[i] != "+" and expressionMap[i] != "-":
expressionMap[i] = int(expressionMap[i])
if expressionMap[i] != "+" and expressionMap[i] != "-" and not(isinstance(expressionMap[i], int)):
Interpreter.error("evaluate",f"Unknown symbol '{expressionMap[i]} is not a valid input.")
break
while len(expressionMap) > 1:
expressionMap[0] = expressionMap[0] + expressionMap[2] if expressionMap[1] == "+" else expressionMap[0] - expressionMap[2]
del expressionMap[1:3]
return expressionMap[0]
#TODO: WORK INTO STARTCOMMANDLINE LOOP TO ENSURE STRING IS NOT BLANK SEE BELOW
# Interpreter.error("mapify","Attempted to mapify inputRaw, but no data as found")
commandInterpreter = Interpreter()
commandInterpreter.startCommandLine()