diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..2cf58d6 --- /dev/null +++ b/notes.txt @@ -0,0 +1,3 @@ +Aatish said I missed some teammate evaluations for non-subteam members in the assignments. And with personal updates +that I missed the first few but after I talked to him earlier in the semester about it the submissions have been solid. +Because of that he recommended I ask you given that I am 2 points from an A in the class. \ No newline at end of file diff --git a/readme.MD b/readme.MD new file mode 100644 index 0000000..0008b50 --- /dev/null +++ b/readme.MD @@ -0,0 +1,6 @@ +lexer will convert into tokens + +I will use the symboltable, but fortunately with python I can be more "liberal" with the way I interact with types + +evaluator will be used for actually running the code. + diff --git a/src/__pycache__/engevaluator.cpython-39.pyc b/src/__pycache__/engevaluator.cpython-39.pyc new file mode 100644 index 0000000..8f9eb7b Binary files /dev/null and b/src/__pycache__/engevaluator.cpython-39.pyc differ diff --git a/src/__pycache__/englexer.cpython-39.pyc b/src/__pycache__/englexer.cpython-39.pyc new file mode 100644 index 0000000..e1a27ed Binary files /dev/null and b/src/__pycache__/englexer.cpython-39.pyc differ diff --git a/src/__pycache__/engnode.cpython-39.pyc b/src/__pycache__/engnode.cpython-39.pyc new file mode 100644 index 0000000..861a003 Binary files /dev/null and b/src/__pycache__/engnode.cpython-39.pyc differ diff --git a/src/__pycache__/engparser.cpython-39.pyc b/src/__pycache__/engparser.cpython-39.pyc new file mode 100644 index 0000000..db998f1 Binary files /dev/null and b/src/__pycache__/engparser.cpython-39.pyc differ diff --git a/src/__pycache__/engtoken.cpython-39.pyc b/src/__pycache__/engtoken.cpython-39.pyc new file mode 100644 index 0000000..1b20a24 Binary files /dev/null and b/src/__pycache__/engtoken.cpython-39.pyc differ diff --git a/src/__pycache__/symboltable.cpython-39.pyc b/src/__pycache__/symboltable.cpython-39.pyc new file mode 100644 index 0000000..f46597d Binary files /dev/null and b/src/__pycache__/symboltable.cpython-39.pyc differ diff --git a/src/engevaluator.py b/src/engevaluator.py new file mode 100644 index 0000000..6a04316 --- /dev/null +++ b/src/engevaluator.py @@ -0,0 +1,73 @@ +from engnode import * +from symboltable import SymbolTable + + +class EngEvaluator: + def __init__(self, nodes): + self.nodes = nodes + self.end = False + self.counter = 0 + self.st = SymbolTable() + + while(not self.end): + self.runcycle() + + + def runcycle(self): + currenttype = type(self.nodes[self.counter]) + if(currenttype == DisplayNode): + print(self.gettrueval(self.nodes[self.counter].displayval)) + elif(currenttype == SimpleAssignNode): + self.st.updateval(self.nodes[self.counter].var, self.gettrueval(self.nodes[self.counter].value)) + + elif(currenttype == EvaluatedAssignNode): + var, lhs, op, rhs = self.nodes[self.counter].var, self.nodes[self.counter].lhs, self.nodes[self.counter].op, self.nodes[self.counter].rhs + lhs, rhs, = self.gettrueval(lhs), self.gettrueval(rhs) + + if(op == "equals"): + self.st.updateval(var, lhs == rhs) + elif(op == "!equals"): + self.st.updateval(var, lhs != rhs) + elif(op == "or"): + self.st.updateval(var, lhs or rhs) + elif(op == "and"): + self.st.updateval(var, lhs and rhs) + elif(op == "xnor"): + self.st.updateval(var, (not lhs and not rhs) or (lhs and rhs)) + elif(op == "nor"): + self.st.updateval(var, (not lhs and not rhs)) + elif(op == "xor"): + self.st.updateval(var, not ((not lhs and not rhs) or (lhs and rhs))) + elif(op == "nand"): + self.st.updateval(var, not(lhs and rhs)) + elif(op == "plus"): + self.st.updateval(var, lhs + rhs) + elif(op == "minus"): + self.st.updateval(var, lhs - rhs) + elif(op == "times"): + self.st.updateval(var, lhs * rhs) + elif(op == "divided"): + self.st.updateval(var, lhs / rhs) + else: + raise ValueError + + elif(currenttype == JumpNode): + if(self.gettrueval(self.nodes[self.counter].condition)): + self.counter = self.nodes[self.counter].jumpto - 2 + + elif(currenttype == EndNode): + self.end = True + else: + raise ValueError + + self.counter += 1 + + + + def gettrueval(self, var): + if(var in self.st): + return self.st.getval(var) + elif(var.isalpha()): + return bool(var) + else: + return int(var) diff --git a/src/englexer.py b/src/englexer.py new file mode 100644 index 0000000..53dfe79 --- /dev/null +++ b/src/englexer.py @@ -0,0 +1,11 @@ +from engtoken import EngToken + + +class EngLexer: + def __init__(self, path): + self.path = path + + def lex(self): + with open(self.path, 'r') as file: + content = [line.strip() for line in file.readlines() if line != '\n'] + return [EngToken(line) for line in content] \ No newline at end of file diff --git a/src/engnode.py b/src/engnode.py new file mode 100644 index 0000000..774483a --- /dev/null +++ b/src/engnode.py @@ -0,0 +1,41 @@ +class DisplayNode: + def __init__(self, displayval): + self.displayval = displayval + + def __repr__(self): + return f'printing: {self.displayval}' + + +class SimpleAssignNode: + def __init__(self, var, value): + self.var = var + self.value = value + + def __repr__(self): + return f'assigning {self.value} to {self.var}' + +class EvaluatedAssignNode: + def __init__(self, var, lhs, op, rhs): + self.var = var + self.lhs = lhs + self.op = op + self.rhs = rhs + + def __repr__(self): + return f'{self.lhs} {self.op} {self.rhs} are now assigned to {self.var}' + +class JumpNode: + def __init__(self, jumpto, condition): + self.jumpto = int(jumpto) + self.condition = condition + + def __repr__(self): + return f'jumping to line {self.jumpto} if {self.condition}' + +class EndNode: + def __init__(self): + pass + + def __repr__(self): + return "ending program" + diff --git a/src/engparser.py b/src/engparser.py new file mode 100644 index 0000000..31dbc6a --- /dev/null +++ b/src/engparser.py @@ -0,0 +1,48 @@ +from engnode import * + + + + +class EngParser: + + def parsetokens(self, tokens): + nodelst = [] + + + for token in tokens: + if(token.type == "display"): + nodelst.append(self.parseDisplay(token.val[0])) + elif(token.type == "simpleassign"): + nodelst.append(self.parseSimpleAssign(token.var, token.val[0])) + elif(token.type == "numericcomparativeassign"): + nodelst.append(self.parseNumericComparativeAssign(token.var, token.val)) + elif(token.type == "evaluatedassign"): + nodelst.append(self.parseEvaluatedAssign(token.var, token.val)) + elif(token.type == "jump"): + nodelst.append(self.parseJump(token.val)) + elif(token.type == "end"): + nodelst.append(EndNode()) + else: + print("Error unknown Type Parser") + raise ValueError + return nodelst + + def parseDisplay(self, displayval): + return DisplayNode(displayval) + + def parseSimpleAssign(self, var, value): + return SimpleAssignNode(var, value) + + def parseNumericComparativeAssign(self, var, value): + if(len(value) == 5): #Is equal to + return EvaluatedAssignNode(var, value[0], "equals", value[-1]) + + else: #is not equal to + return EvaluatedAssignNode(var, value[0], "!equals", value[-1]) + + def parseEvaluatedAssign(self, var, value): + return EvaluatedAssignNode(var, value[0], value[1], value[2]) + + def parseJump(self, value): + return JumpNode(value[0], value[-1]) + diff --git a/src/engtoken.py b/src/engtoken.py new file mode 100644 index 0000000..fcae33e --- /dev/null +++ b/src/engtoken.py @@ -0,0 +1,34 @@ +class EngToken: + def __init__(self, line): + self.linelst = line.split() + if(self.linelst[0] == "end"): + self.type = "end" + self.var = None + self.val = [] + elif(self.linelst[0] == "jump"): + self.type = "jump" + self.var = None + self.val = [val for val in self.linelst[2:]] + + elif(self.linelst[0] == "display"): + self.type = "display" + self.var = None + self.val = [self.linelst[1]] + elif(self.linelst[1] == "isnow" and len(self.linelst) == 3): + self.type = "simpleassign" + self.var = self.linelst[0] + self.val = [self.linelst[2]] + elif(len(self.linelst) > 6): + self.type = "numericcomparativeassign" + self.var = self.linelst[0] + self.val = [val for val in self.linelst[2:]] + else: + self.type = "evaluatedassign" + self.var = self.linelst[0] + self.val = [val for val in self.linelst[2:]] + + def __repr__(self): + return " ".join(self.linelst) + + + diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..2f9a965 --- /dev/null +++ b/src/main.py @@ -0,0 +1,39 @@ +import sys +import os +from englexer import EngLexer +from engparser import EngParser +from engevaluator import EngEvaluator + +def main(): + # Check if a file path was provided as an argument + if len(sys.argv) < 2: + print("Error: Please provide a file path") + sys.exit(1) + + # Get the file path from command line arguments + file_path = sys.argv[1] + if file_path[-4:] != ".eng": + print("Wrong file format") + sys.exit(1) + filename = file_path.split(".")[0] + + + # Check if the file exists + if not os.path.exists(file_path): + print(f"Error: File '{file_path}' does not exist") + sys.exit(1) + + try: + # Open and read the file + tokens = EngLexer(file_path).lex() + parsednodes = EngParser().parsetokens(tokens) + EngEvaluator(parsednodes) + + + + except Exception as e: + print(f"Error reading file: {e}") + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/symboltable.py b/src/symboltable.py new file mode 100644 index 0000000..510c37d --- /dev/null +++ b/src/symboltable.py @@ -0,0 +1,13 @@ +class SymbolTable: + def __init__(self): + self.table = {} + + def __contains__(self, value): + return value in self.table + + def updateval(self, var, value): + self.table[var] = value + + def getval(self, var): + return self.table[var] + diff --git a/src/test.eng b/src/test.eng new file mode 100644 index 0000000..4303904 --- /dev/null +++ b/src/test.eng @@ -0,0 +1,16 @@ +ind1 isnow 2 + + + + + + + + + + + + + + +end \ No newline at end of file diff --git a/syntax.ipynb b/syntax.ipynb new file mode 100644 index 0000000..a49a9c4 --- /dev/null +++ b/syntax.ipynb @@ -0,0 +1,167 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Syntax for New Programming Language that we'll just call Eng" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Assignment " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "X isnow y\n", + "\n", + "y isnow 3\n", + "\n", + "z isnow 4 + 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# printing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "display X\n", + "display y\n", + "display x" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Math" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "X isnow y plus 3\n", + "y isnow z minus 2\n", + "h isnow f times 9\n", + "p isnow g divided 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Boolean" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "x isnow true\n", + "y isnow false" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Boolean Operators" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "y isnow true or false\n", + "y isnow true xnor true\n", + "y isnow true and false\n", + "y isnow true nand false\n", + "y isnow true nor true\n", + "y isnow true xor false\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "y isnow 5 is equal to 3\n", + "y isnow 5 is not equal to 3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LOOPS (These are going to take a line number to go back to and a boolean) WILL IMPLEMENT LATER" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "jump to 6 if bool" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}