114 lines
3.3 KiB
Python
114 lines
3.3 KiB
Python
|
#!/bin/python
|
||
|
|
||
|
import os
|
||
|
import shutil
|
||
|
import sys
|
||
|
import subprocess
|
||
|
from threading import Timer
|
||
|
|
||
|
def evaluate(submitted_program):
|
||
|
|
||
|
jarfile = "./emulator.jar"
|
||
|
testcases_directory = "./test_cases/"
|
||
|
|
||
|
l = len(submitted_program.split("/"))
|
||
|
program_name = submitted_program.split("/")[l-1].split("_")[0].split(".")[0]
|
||
|
total_marks = 0
|
||
|
scored_marks = 0
|
||
|
for cur_file in os.listdir(testcases_directory):
|
||
|
if program_name in cur_file and ".input" in cur_file:
|
||
|
total_marks = total_marks + 1
|
||
|
#find starting and ending address
|
||
|
expected_file = open(testcases_directory + cur_file.split(".")[0] + ".expected")
|
||
|
starting_address = "x"
|
||
|
ending_address = "x"
|
||
|
memory_required = False
|
||
|
for line in expected_file:
|
||
|
if memory_required == True:
|
||
|
if len(line.split(":")) > 1:
|
||
|
if starting_address == "x":
|
||
|
starting_address = line.split(":")[0].split()[0]
|
||
|
else:
|
||
|
ending_address = line.split(":")[0].split()[0]
|
||
|
if "Main Memory Contents" in line:
|
||
|
memory_required = True
|
||
|
expected_file.close()
|
||
|
|
||
|
if starting_address == "x":
|
||
|
starting_address = "0"
|
||
|
ending_address = "0"
|
||
|
if ending_address == "x":
|
||
|
ending_address = starting_address
|
||
|
#create new assembly file based on test case
|
||
|
new_assembly_file = open("./tmp.asm", 'w')
|
||
|
input_file = open(testcases_directory + cur_file)
|
||
|
for line in input_file:
|
||
|
new_assembly_file.write(line)
|
||
|
input_file.close()
|
||
|
|
||
|
text_encountered = False
|
||
|
submitted_file = open(submitted_program)
|
||
|
for line in submitted_file:
|
||
|
if ".text" in line:
|
||
|
text_encountered = True
|
||
|
if text_encountered == True:
|
||
|
new_assembly_file.write(line)
|
||
|
submitted_file.close()
|
||
|
new_assembly_file.close()
|
||
|
# spawn emulator
|
||
|
stdout_file = open("./tmp.output", 'w')
|
||
|
popen_args = ["java", "-Xmx1g", "-jar", jarfile, "./tmp.asm", starting_address, ending_address]
|
||
|
proc = subprocess.Popen(popen_args, stdout = stdout_file, stderr = stdout_file)
|
||
|
timer = Timer(5, proc.kill)
|
||
|
try:
|
||
|
timer.start()
|
||
|
stdout, stderr = proc.communicate()
|
||
|
finally:
|
||
|
timer.cancel()
|
||
|
stdout_file.close()
|
||
|
# evaluate against expected output
|
||
|
expected_file = open(testcases_directory + cur_file.split(".")[0] + ".expected")
|
||
|
result_file = open("./tmp.output")
|
||
|
expected_line = expected_file.readline()
|
||
|
first_line_found = False
|
||
|
evaluation = True
|
||
|
for line in result_file:
|
||
|
if first_line_found == True and line != expected_line:
|
||
|
evaluation = False
|
||
|
break
|
||
|
if expected_line == line:
|
||
|
first_line_found = True
|
||
|
expected_line = expected_file.readline()
|
||
|
if expected_line == None or expected_line == "":
|
||
|
break
|
||
|
if first_line_found == False:
|
||
|
evaluation = False
|
||
|
|
||
|
expected_file.close()
|
||
|
result_file.close()
|
||
|
|
||
|
if evaluation == True:
|
||
|
scored_marks = scored_marks + 1
|
||
|
print(cur_file + "\t: PASS!")
|
||
|
else:
|
||
|
print(cur_file + "\t: Fail")
|
||
|
#debug print
|
||
|
debug = False
|
||
|
if debug == True:
|
||
|
print("testcase = " + cur_file)
|
||
|
print("\n output expected to contain = ")
|
||
|
expected_file = open(testcases_directory + cur_file.split(".")[0] + ".expected")
|
||
|
for line in expected_file:
|
||
|
print(line)
|
||
|
expected_file.close()
|
||
|
print("\n obtained output = ")
|
||
|
output_file = open("./tmp.output")
|
||
|
for line in output_file:
|
||
|
print(line)
|
||
|
output_file.close()
|
||
|
|
||
|
os.remove("./tmp.asm")
|
||
|
os.remove("./tmp.output")
|
||
|
|
||
|
return [total_marks, scored_marks]
|