0% found this document useful (0 votes)
9 views

lmc_convert_to_python.py

idk

Uploaded by

dingklefard
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

lmc_convert_to_python.py

idk

Uploaded by

dingklefard
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

import os.

path

import time

filename = input()

if not os.path.isfile(filename):
raise Exception("No file")

s = time.time()
file = open(filename, "r")
lines = file.readlines()
lines = [line.strip() for line in lines]
lines = filter(lambda x: x != '', lines)
file.close()

two_argument_instructions = {"LDA": ["variables.accumulator = %d"], "STA": ["%d =


variables.accumulator"], "BRA": ["return %d"], "BRP": ["if variables.accumulator >=
0:", "\treturn d()"], "BRZ": ["if variables.accumulator == 0:", "\treturn %d"],
"SUB": ["variables.accumulator -= %d"], "ADD": ["variables.accumulator += %d"],
"MUL": ["variables.accumulator *= %d"]}
single_argument_instructions = {"HLT": ["raise Exception()"], "INP":
["variables.accumulator = int(input())"], "OUT": ["print(variables.accumulator)"]}

variables = {}
labels = {"main": {}}
integer_addresses = {}
current_label = "main"

for index, line in enumerate(lines):


seperated_instruction = line.split()

if len(seperated_instruction) == 3:
if seperated_instruction[1] not in two_argument_instructions or
seperated_instruction[1] not in single_argument_instructions:
if seperated_instruction[1] == "DAT":
variables[seperated_instruction[0]] = int(seperated_instruction[2])
continue
else:
label, seperated_instruction = seperated_instruction[0],
seperated_instruction[1:]
labels["_" + label] = {}
current_label = "_" + label
if len(seperated_instruction) == 2:
if seperated_instruction[0] not in two_argument_instructions:
label, seperated_instruction = seperated_instruction[0],
seperated_instruction[1:]
labels["_" + label] = {}
current_label = "_" + label

if seperated_instruction[0] in two_argument_instructions:
if len(seperated_instruction) != 2:
raise Exception(f"On line {index + 1} there is an incorrect amount of
arguments")
else:
instruction, argument = seperated_instruction
if argument[0] == "#":
try:
labels[current_label][index] =
two_argument_instructions[instruction] + ["-" + str(argument)]
except:
raise Exception(f"Error on line {index + 1}")
else:
labels[current_label][index] =
two_argument_instructions[instruction] + ["_" + argument]
elif seperated_instruction[0] in single_argument_instructions:
if len(seperated_instruction) != 1:
raise Exception(f"On line {index + 1} there is an incorrect amount of
arguments")
else:
instruction = seperated_instruction[0]
labels[current_label][index] =
single_argument_instructions[instruction]
else:
raise Exception("Unknown instruction " + str(seperated_instruction))

for label in labels:


for addr in labels[label]:
if len(labels[label][addr]) == 3:
if isinstance(labels[label][addr][2], int):
for l in labels:
if labels[label][addr][2] in labels[l]:
integer_addresses[labels[label][addr][2]] = [labels[label]
[k] for k in range(labels[label][addr][2], max(labels[l].keys()) + 1)]
elif len(labels[label][addr]) == 1:
if isinstance(labels[label][addr][0], int):
for l in labels:
if labels[label][addr][0] in labels[l]:
integer_addresses[labels[label][addr][0]] = [labels[label]
[k] for k in range(labels[label][addr][0], max(labels[l].keys()) + 1)]

new_labels = {}
for label in labels:
new_labels[label] = list(labels[label].values())
has_added = False
for index, instruction in enumerate(new_labels[label]):
if instruction[-1] == label:
if len(instruction) == 3:
new_labels[label][index] = instruction[0] + ["continue"]
if not has_added:
new_labels[label].insert(0, ["while True:"])
has_added = True
elif len(instruction) == 2 and "%d" in instruction[0]:
new_labels[label][index] = ["continue"]
if not has_added:
new_labels[label].insert(0, ["while True:"])
has_added = True

labels = new_labels

label_list = list(labels.keys())
def convert(instructions, current_indent, functions):
for instruction in instructions:
#print(instruction)
if len(instruction) == 1:
functions.append("\t" * current_indent + instruction[0])
if instruction[0] == "while True:":
current_indent += 1
elif len(instruction) == 2:
if instruction[0].split()[0] == "if":
functions.append("\t" * current_indent + instruction[0])
convert(instruction[1], current_indent + 1, functions)
else:
#print(instruction)
if "return" in instruction[0]:
#print("True")
functions.append("\t" * current_indent +
instruction[0].replace("%d", str(label_list.index(instruction[1]))))
else:
if instruction[1][1] == "#":
functions.append("\t" * current_indent +
instruction[0].replace("%d", instruction[1][2:]))
continue
functions.append("\t" * current_indent +
instruction[0].replace("%d", "variables." + instruction[1]))

else:
functions.append("\t" * current_indent + instruction[0])
functions.append("\t" * (current_indent) + instruction[1].replace("%d",
str(label_list.index(instruction[2]))))

def scan(instructions):
pass

for label in labels:


if label == "main":
continue
labels["main"].append([f"return {label_list.index(label)}"])
#labels["main"].append(["raise Exception()"])
#print(labels["main"])
variables_instructions = []

variables_instructions.append("class variables:")
variables_instructions.append("\taccumulator = 0")
for variable in variables:
variables_instructions.append(f"\t{variable} = {variables[variable]}")

def execute_function(function):
while True:
function = functions[function()]

functions = {}
for label in labels:
functions[label] = []
functions[label].append(f"def {label}():")
indent = 1
new = []
convert(labels[label], indent, new)
functions[label].extend(new)
#print('\n'.join(variables_instructions))
#for label in labels:
# print('\n'.join(functions[label]))

for label in functions:


exec("\n".join(functions[label]))

fg = []
i = 0
for label in functions:
#print(label)
exec(f"fg.append({label})")
functions = fg

#print(variables)
exec("\n".join(variables_instructions))

t = time.time()

try:
execute_function(functions[0])
except Exception as e:
#print(e)
e = time.time()
print(f"Program Terminated, Taking: {e - t:.2f}s")
print(f"Program Parsing, Took: { t - s:.10f}s")
print(f"Total Time: {e - s:.2f}s")

You might also like