Skip to content

Instantly share code, notes, and snippets.

@aurorapar
Created June 6, 2017 22:29
Show Gist options
  • Save aurorapar/3ee3c82a690391e03022a2c4e49073d7 to your computer and use it in GitHub Desktop.
Save aurorapar/3ee3c82a690391e03022a2c4e49073d7 to your computer and use it in GitHub Desktop.
'''
PREFACE
This is probably the worst code I have ever written. The optimiation is non-existant,
the rules have little forethought and planning, and only the minimal of the procedures
that were studied in class were applied.
This software should not be taken as representation of my abilities, but more as
what a caffiene binge throughout the night can produce.
'''
import sys, os, random, string
DEBUG = True
keywords = ['for', 'while', 'if', 'write', 'writeln', 'break', 'random']
controlStatements = ['for', 'while', 'if', 'break']
hasArguments = ['write', 'writeln', 'random']
variableDeclarations = []
for x in range(8, 13+1):
variableDeclarations.append(list(string.ascii_lowercase)[x])
comparisons = ["=", "==", "<=", ">=", ">", "<", '!=']
operators = ['%']
variables = [{}]
stack = variables[-1]
def debug(output):
if DEBUG:
print('"%s"'%output)
def throwError(error, line, lineNumber):
print(error)
print('Line %s : "%s"'%(lineNumber, line))
sys.exit()
def increaseStack():
global stack, variables
#debug("Stack before increase: %s"%variables)
variables.append({})
#debug("Stack after change: %s"%variables)
stack = variables[-1]
#debug("Last entry on stack: %s"%stack)
def decreaseStack():
global stack, variables
#debug("Stack before decrease: %s"%variables)
variables.pop()
#debug("Stack after change: %s"%variables)
stack = variables[-1]
#debug("Last entry on stack: %s"%stack)
def addOutput(outputCode, outputFile, newLine):
with open(outputFile, 'a') as file:
if newLine:
code = " " * 4 * 2
code += " " * ((len(variables) - 2) * 4)
code += outputCode
file.write(code)
else:
file.write(outputCode)
def interpret(line, number, outputFile, newLine=False):
if 'int' in str(type(line)):
return line
if line.isnumeric():
return line
line = line.replace("\n", "")
if len(line.strip()) < 1:
return 0
items = line.strip()
items = items.split(" ")
if items[0].startswith("#"):
return 0
if items[0] == 'break':
#Decrease stack
addOutput("}\n", outputFile, newLine)
decreaseStack()
return 0
if newLine:
spaces = 0
for x in line:
if x == " ":
spaces += 1
else:
break
if spaces % 4 != 0:
throwError("Improper indenting, expected %s"%(len(stack) * 4), line, number)
tabs = spaces / 4
if tabs != len(variables) - 1:
throwError("Improper indenting", line, number)
word = items[0].split("(")
if word[0] not in keywords:
if len(word[0]) == 1:
if word[0] not in variableDeclarations:
throwError("Invalid variable declaration", line, number)
else:
if len(items) > 1:
character = items[0]
declared = False
if character in stack:
declared = True
if not declared:
for x in range(1, len(variables)):
if len(variables[-x]) > 0:
for y in variables[-x]:
if character in y:
declared = True
break
if items[1] not in comparisons:
if items[1] not in operators:
throwError("Unknown operator", line, number)
else:
return "%s %s %s"%\
(interpret(items[0],number,outputFile),\
items[1],\
interpret(items[2],number,outputFile))\
if items[1] == "=":
if items[2] != 'array':
toInterpret = " ".join(str(x) for x in items[2:len(items)])
#debug("To interpret: %s"%toInterpret)
#debug("Interpreted: %s"%interpret(toInterpret, line, outputFile))
code = "%s %s %s;\n"%(items[0], items[1], interpret(toInterpret, line, outputFile))
if not declared:
stack[items[0]] = interpret(toInterpret, line, outputFile)
code = "int " + code
addOutput(code, outputFile, newLine)
else:
if declared:
throwError("Array already declared", line, number)
code = "int[] %s %s new int[%s];\n"%(character, items[1], interpret(items[3], number, outputFile))
stack[items[0]] = []
addOutput(code, outputFile, newLine)
return items[0]
else:
var = items[0]
character = var[0]
if len(var) in [1,4] and character in variableDeclarations:
declared = False
if character in stack:
declared = True
if not declared:
for x in range(0, len(variables)):
if len(variables[-x]) > 0:
#debug(variables[-x])
#debug(variables[-x].keys())
for y in variables[-x].keys():
if character == y:
declared = True
break
if len(var) == 1:
toInterpret = " ".join(str(x) for x in items[2:len(items)])
outputCode = "%s %s %s;\n"%(items[0], items[1], interpret(toInterpret, number, outputFile))
if not declared:
outputCode = "int " + outputCode
stack[var] = interpret(toInterpret, number, outputFile)
addOutput(outputCode, outputFile, newLine)
return 0
if len(var) == 4:
index = interpret(var[2], number, outputFile)
if len(items) == 3:
toInterpret = " ".join(str(x) for x in items[2:len(items)])
outputCode = ""
if not declared:
throwError("Declare arrays before use", line, number)
else:
outputCode = "%s[%s-1] = %s;\n"%(character, index, interpret(toInterpret, number, outputFile))
addOutput(outputCode, outputFile, outputFile)
return 0
else:
if not declared:
throwError("%s was not declared"%var, line, number)
#debug("Should be returned here")
return "%s[%s-1]"%(var[0],index)
#Is a keyword
else:
if items[0] == 'for':
if len(items) != 5:
throwError("Improper usage of %s"%items[0], line, lineNumber)
increaseStack()
for x in [2,3,4]:
items[x] = interpret(items[x], number, outputFile)
stack[items[1]] = items[2]
addOutput("for(int %s = %s; %s <= %s; %s += %s)\n"%\
(items[1], items[2], items[1], items[3], items[1], items[4]), outputFile, newLine)
addOutput("{\n", outputFile, True)
if items[0] == 'while':
#debug("while loop")
if len(items) != 4:
throwError("Improper usage of %s"%items[0], line, lineNumber)
increaseStack()
for x in [1,3]:
items[x] = interpret(items[x], number, outputFile)
if items[2] not in comparisons:
throwError("Invalid comparison: %s"%(items[2], line, number))
code = "while(%s %s %s)"%(items[1], items[2], items[3])
addOutput(code+"\n", outputFile, newLine)
addOutput("{\n", outputFile, True)
if items[0] == 'if':
if len(items) != 4:
throwError("Improper usage of %s"%items[0], line, lineNumber)
increaseStack()
for x in [1,3]:
items[x] = interpret(items[x], number, outputFile)
if items[2] not in comparisons:
throwError("Invalid comparison: %s"%(items[2], line, number))
code = "if(%s %s %s)\n"%(items[1], items[2], items[3])
addOutput(code, outputFile, newLine)
addOutput("{\n", outputFile, True)
if word[0] == 'writeln':
if word[1] != ")":
throwError("writeln() takes no parameters", line, number, outputFile)
addOutput("System.out.println();\n", outputFile, newLine)
if word[0] == 'write':
parts = line.strip().replace("\n","")
parts = parts.replace("write(", "")
parts = list(parts)
parts = parts[0:len(parts)-1]
output = "".join(str(x) for x in parts)
parts = output.split(",")
for x in range(0, len(parts)):
if not parts[x].strip().startswith('"'):
parts[x] = "Integer.toString(%s)"%interpret(parts[x].strip(), number, outputFile)
output = "+".join(str(x) for x in parts)
output = "System.out.print(%s);\n"%output
addOutput(output, outputFile, newLine)
if word[0] == 'random':
if "(" in word[1]:
throwError("Currently do not support nested functions", line, number)
output = word[1].split(",")
if len(output) != 2:
throwError("Unsupported number of arguments", line, number)
output[-1] = output[-1].replace(")", "")
for x in range(0, len(output)):
output[x] = interpret(output[x], number, outputFile)
code = "rng.nextInt(%s) + %s"%(int(output[1])-int(output[0]), output[0])
if not newLine:
return code
else:
addOutput(code+ ";", outputFile, False)
for arg in sys.argv:
if arg != sys.argv[0]:
if arg.endswith(".4z"):
debug("Calling interpreter")
if os.path.exists(sys.argv[1]):
output = sys.argv[1].replace(".4z", ".java")
if not os.path.exists(output):
file = open(output, 'w+')
file.close()
else:
print("Overwriting %s..."%output)
with open(output, 'w') as file:
file.write("import java.util.*;\n")
file.write("\n\n")
file.write("class %s\n"%sys.argv[1].replace(".4z", ""))
file.write("\n")
file.write("{\n")
file.write(" public static void main(String[] args)\n")
file.write(" {\n")
file.write(" Random rng = new Random();\n")
with open(sys.argv[1], 'r') as program:
lineNumber = 1
for line in program:
interpret(line, lineNumber, output, True)
lineNumber += 1
print("Program closed")
with open(output, 'a') as file:
file.write("\n }\n")
file.write("}")
else:
throwError("%s was not found on the system"%script, "Parameters", sys.argv)
else:
print("%s is not a valiid FORTRANZ script"%arg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment