85 lines
3.6 KiB
Python
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() |