Commit c84ede0b authored by Christopher Happe's avatar Christopher Happe
Browse files

Feature: Übergabe von Parametern an Programm eingefügt

parent e7588d06
......@@ -261,13 +261,15 @@ class GOTOInterpreter:
current_token = self.verify_halt(current_token)
return current_token
def interpret(self, program):
def interpret(self, program, values=None):
try:
with Timeout(self.timeout):
self.halted = False
self.lex = lexer.Lexer(self.regex_to_token, program)
self.error_handler = ErrorHandler(program, self)
self.values = {}
self.values=values
if values is None:
self.values = {}
current_token = self.next_token()
while current_token is not None:
current_token = self.process_line(current_token)
......@@ -282,16 +284,25 @@ class GOTOInterpreter:
return -1
def interpret(program, timeout=60):
def interpret(program, value_list=None, timeout=60):
"""Funktion zum Ausführen eines GOTO-Programms.
:param program: GOTO-Programm als String 'M1: A1; M2: A2; ... Mn: An;'
:param value_list: Array von Integern ([v1, ..., vn]).
Das GOTO-Programm startet mit diesen Werten in x1, ..., xn.
:param timeout: Zeit nach der die Ausführung eines Programms pausiert wird.
Gibt eine Möglichkeit zum Abbrechen bei einer Endlosschleife.
Ein Wert von 0 deaktiviert den Timeout.
:returns integer: Gibt bei Abbruch -1 und sonst den Wert von x0 nach dem GOTO-Programm zurück.
:usage interpret('M1: x0 := x0 + 1; M2: IF x0 = 10 THEN GOTO M4; M3: GOTO M1; M4: HALT;')"""
interpreter = GOTOInterpreter(timeout)
return interpreter.interpret(program)
values = None
if value_list is not None:
values = {}
for index, value in enumerate(value_list):
if not isinstance(value, int) or value < 0 or not int(value) == value:
raise ValueError("Variablen können nur natürliche Zahlen zugewiesen bekommen.")
values.update({'x' + str(index + 1): value})
return interpreter.interpret(program, values)
if __name__ == '__main__':
......
......@@ -225,11 +225,13 @@ class LOOPInterpreter:
'Frühzeitiges Ende von ' + current_function + '\n' + 'Erwartet: ' + expected_token)
return token
def interpret(self, program):
def interpret(self, program, values=None):
try:
self.lex = lexer.Lexer(self.regex_to_token, program)
self.error_handler = ErrorHandler(program, self)
self.values = {}
self.values = values
if values is None:
self.values = {}
forbidden_identifiers = []
current_token = self.next_token()
while current_token is not None:
......@@ -250,13 +252,22 @@ class LOOPInterpreter:
return -1
def interpret(program):
def interpret(program, value_list=None):
"""Funktion zum Ausführen eines LOOP-Programms.
:param program: LOOP-Programm als String 'x1 := 4; LOOP x1 DO x0:=x0+1 END'
:param value_list: Array von Integern ([v1, ..., vn]).
Das LOOP-Programm startet mit diesen Werten in x1, ..., xn.
:returns integer: Gibt bei Abbruch -1 und sonst den Wert von x0 nach dem LOOP-Programm zurück.
:usage interpret('x1:=10; x2:=8; x0:=x2+0; LOOP x1 DO x0:=x0+1 END')"""
interpreter = LOOPInterpreter()
return interpreter.interpret(program)
values = None
if value_list is not None:
values = {}
for index, value in enumerate(value_list):
if not isinstance(value, int) or value < 0 or not int(value) == value:
raise ValueError("Variablen können nur natürliche Zahlen zugewiesen bekommen.")
values.update({'x' + str(index + 1): value})
return interpreter.interpret(program, values)
if __name__ == '__main__':
......
......@@ -7,6 +7,10 @@ def input_continue(prompt):
return ''
def str_yes(prompt):
return 'J'
def input_exit(prompt):
return 'EXIT'
......@@ -182,3 +186,23 @@ class GOTOInterpreterTest(TestCase):
def test_end_without_halt(self):
with self.assertRaises(SyntaxError):
interpret('M1: x0:=2;')
@mock.patch('whileinterpreter.input', side_effect=str_yes)
def test_infinite_loop(self, custom_input):
self.assertEqual(-1, interpret('M1: x1:=100000; M2: x1:=x1-1; M3: IF x1=0 THEN GOTO M5; M4: GOTO M1; M5:HALT;',
timeout=1))
def test_given_values(self):
self.assertEqual(5, interpret('M1: x0:=x1+0; M2: IF x2=0 THEN GOTO M6; M3: x0:=x0+1;' +
'M4: x2:=x2-1; M5: GOTO M2; M6: HALT;', [2, 3]))
self.assertEqual(4, interpret('M1: x0:=x1+0; M2: IF x2=0 THEN GOTO M6; M3: x0:=x0+1;' +
'M4: x2:=x2-1; M5: GOTO M2; M6: HALT;', [0, 4]))
self.assertEqual(1, interpret('M1: x0:=x0+1; M2: HALT;', [2,3,4]))
def test_wrong_given_values(self):
with self.assertRaises(ValueError):
interpret('M1: x0:=2;', [-1])
with self.assertRaises(ValueError):
interpret('M1: x0:=1;', [0.2])
with self.assertRaises(ValueError):
interpret('M1: x0:=4;', ['EINS'])
......@@ -246,3 +246,16 @@ class LOOPInterpreterTest(unittest.TestCase):
def test_unknown_tokens(self):
with self.assertRaises(SyntaxError):
interpret('BLIBLABLUB')
def test_given_values(self):
self.assertEqual(5, interpret('x0:=x1+0; LOOP x2 DO x0:=x0+1 END', [2, 3]))
self.assertEqual(4, interpret('x0:=x1+0; LOOP x2 DO x0:=x0+1 END', [0, 4]))
self.assertEqual(1, interpret('x0:=x0+1', [2,3,4]))
def test_wrong_given_values(self):
with self.assertRaises(ValueError):
interpret('x0:=2;', [-1])
with self.assertRaises(ValueError):
interpret('x0:=1;', [0.2])
with self.assertRaises(ValueError):
interpret('x0:=4;', ['EINS'])
\ No newline at end of file
......@@ -119,4 +119,17 @@ class WHILEInterpreterTest(LOOPInterpreterTest):
@mock.patch('whileinterpreter.input', side_effect=str_yes)
def test_infinite_loop(self, custom_input):
self.assertEqual(-1, interpret('x1:=100000; WHILE x1 != 0 DO x0:=1; x1:=x1-1 END', 1))
self.assertEqual(-1, interpret('x1:=100000; WHILE x1 != 0 DO x0:=1; x1:=x1-1 END', timeout=1))
def test_given_values(self):
self.assertEqual(5, interpret('x0:=x1+0; WHILE x2/=0 DO x0:=x0+1; x2:=x2-1 END', [2, 3]))
self.assertEqual(4, interpret('x0:=x1+0; WHILE x2/=0 DO x0:=x0+1; x2:=x2-1 END', [0, 4]))
self.assertEqual(1, interpret('x0:=x0+1', [2,3,4]))
def test_wrong_given_values(self):
with self.assertRaises(ValueError):
interpret('x0:=2', [-1])
with self.assertRaises(ValueError):
interpret('x0:=1', [0.2])
with self.assertRaises(ValueError):
interpret('x0:=4', ['EINS'])
......@@ -159,12 +159,14 @@ class WHILEInterpreter(LOOPInterpreter):
return self.next_token()
def interpret(self, program):
def interpret(self, program, values=None):
try:
with Timeout(self.timeout):
self.lex = lexer.Lexer(self.regex_to_token, program)
self.error_handler = ErrorHandler(program, self)
self.values = {}
self.values = values
if values is None:
self.values = {}
forbidden_identifiers = []
current_token = self.next_token()
while current_token is not None:
......@@ -185,16 +187,25 @@ class WHILEInterpreter(LOOPInterpreter):
return -1
def interpret(program, timeout=60):
def interpret(program, value_list=None, timeout=60):
"""Funktion zum Ausführen eines WHILE-Programms.
:param program: WHILE-Programm als String 'x1:=10; x2:=8; x0:=x2+0; WHILE x1 /=0 DO x0:=x0+1; x1:=x1-1 END'
:param value_list: Array von Integern ([v1, ..., vn]).
Das WHILE-Programm startet mit diesen Werten in x1, ..., xn.
:param timeout: Zeit nach der die Ausführung eines Programms pausiert wird.
Gibt eine Möglichkeit zum Abbrechen bei einer Endlosschleife.
Ein Wert von 0 deaktiviert den Timeout.
:returns integer: Gibt bei Abbruch -1 und sonst den Wert von x0 nach dem WHILE-Programm zurück.
:usage interpret('x1:=10; x2:=8; x0:=x2+0; WHILE x1 /=0 DO x0:=x0+1; x1:=x1-1 END')"""
interpreter = WHILEInterpreter(timeout)
return interpreter.interpret(program)
values = None
if value_list is not None:
values = {}
for index, value in enumerate(value_list):
if not isinstance(value, int) or value < 0 or not int(value) == value:
raise ValueError("Variablen können nur natürliche Zahlen zugewiesen bekommen.")
values.update({'x' + str(index+1): value})
return interpreter.interpret(program, values)
if __name__ == '__main__':
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment