-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented turing complete programming language
- Loading branch information
1 parent
3337287
commit a4a674f
Showing
17 changed files
with
451 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
ind1 isnow 2 | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
end |
Oops, something went wrong.