diff --git a/info4/kapitel-8/Interpreter/test_while_interpreter.py b/info4/kapitel-8/Interpreter/test_while_interpreter.py
index cae730e4a89927db053ab063711ef7309d834362..f326993b202191e4a6fd9c5915f6bb8bf440258f 100644
--- a/info4/kapitel-8/Interpreter/test_while_interpreter.py
+++ b/info4/kapitel-8/Interpreter/test_while_interpreter.py
@@ -1,5 +1,10 @@
 from whileinterpreter import interpret
 from test_loop_interpreter import LOOPInterpreterTest
+from unittest import mock
+
+
+def str_yes(a):
+    return "J"
 
 
 class WHILEInterpreterTest(LOOPInterpreterTest):
@@ -109,3 +114,7 @@ class WHILEInterpreterTest(LOOPInterpreterTest):
             interpret('x1:=2;; x0:=3')
         with self.assertRaises(SyntaxError):
             interpret('WHILE x1 != 0 DO x0:=2;;x2:=1 END')
+
+    @mock.patch('whileinterpreter.input', side_effect=str_yes)
+    def test_infinite_loop(self, input):
+        self.assertEqual(interpret('x1:=100000; WHILE x1 != 0 DO x0:=1; x1:=x1-1 END', 1), -1)
diff --git a/info4/kapitel-8/Interpreter/whileinterpreter.py b/info4/kapitel-8/Interpreter/whileinterpreter.py
index cbddb54d9df5470fe74a068d2e0ca923cd1a1ca7..1c401de6f784c06324911c72ff00bb68f05b27ee 100644
--- a/info4/kapitel-8/Interpreter/whileinterpreter.py
+++ b/info4/kapitel-8/Interpreter/whileinterpreter.py
@@ -1,9 +1,35 @@
-from loopinterpreter import LOOPInterpreter
+import lexer
+from loopinterpreter import LOOPInterpreter, ErrorHandler
 import re
+import signal
+
+
+class Timeout:
+    def __init__(self, time):
+        self.time = time
+
+    def __enter__(self):
+        if self.time > 0:
+            signal.signal(signal.SIGALRM, self.interrupt)
+            signal.alarm(self.time)
+
+    def __exit__(self, exc_type, exc_value, exc_traceback):
+        signal.alarm(0)
+
+    def interrupt(self, sig_num, stack_frame):
+        try:
+            abort = input('''Die Funktion rechnet relativ lange.
+Vielleicht liegt eine Endlosschleife vor.
+Möchten sie abbrechen? [J,n]:''')
+            if abort.upper() in ['J', 'JA', 'Y', 'YES', '']:
+                raise KeyboardInterrupt
+            signal.alarm(self.time)
+        except EOFError:
+            pass
 
 
 class WHILEInterpreter(LOOPInterpreter):
-    def __init__(self):
+    def __init__(self, timeout=60):
         super().__init__()
         self.regex_to_token = [(re.compile(r'\d+'), 'NUMBER'),
                                (re.compile(r'x\d+'), 'IDENTIFIER'),
@@ -19,11 +45,12 @@ class WHILEInterpreter(LOOPInterpreter):
                                (re.compile(r'BREAK'), 'BREAK'),
                                (re.compile(r'\s+', re.MULTILINE), 'WHITESPACE'),
                                (re.compile(r'[^\n]*'), 'UNKNOWN')]
+        self.timeout = timeout
 
     def process_program(self, forbidden_identifiers, current_token):
         if current_token is None or current_token.k not in ['IDENTIFIER', 'LOOP', 'WHILE']:
-            self.error_handler.handle_error("Keine passende Anweisung gefunden\n" +
-                                            "Erwartet: IDENTIFIER (x0, x1, ...), LOOP oder WHILE")
+            self.error_handler.handle_error('Keine passende Anweisung gefunden\n' +
+                                            'Erwartet: IDENTIFIER (x0, x1, ...), LOOP oder WHILE')
         elif current_token.k == 'IDENTIFIER':
             current_token = self.process_assignment(forbidden_identifiers, current_token)
         elif current_token.k == 'LOOP':
@@ -34,8 +61,8 @@ class WHILEInterpreter(LOOPInterpreter):
 
     def verify_program(self, forbidden_identifiers, current_token):
         if current_token is None or current_token.k not in ['IDENTIFIER', 'LOOP', 'WHILE']:
-            self.error_handler.handle_error("Keine passende Anweisung gefunden\n" +
-                                            "Erwartet: IDENTIFIER (x0, x1, ...), LOOP oder WHILE")
+            self.error_handler.handle_error('Keine passende Anweisung gefunden\n' +
+                                            'Erwartet: IDENTIFIER (x0, x1, ...), LOOP oder WHILE')
         elif current_token.k == 'IDENTIFIER':
             current_token = self.verify_assignment(forbidden_identifiers, current_token)
         elif current_token.k == 'LOOP':
@@ -51,16 +78,16 @@ class WHILEInterpreter(LOOPInterpreter):
         if identifier_token.v in forbidden_identifiers:
             self.error_handler.handle_error('Identifier ' + identifier_token.v +
                                             ' ist bereits in Loop vorhanden und darf nicht verwendet werden.')
-        if not self.next_nonempty_token("WHILE", "UNGLEICH").k == 'NOTEQUALS':
+        if not self.next_nonempty_token('WHILE', 'UNGLEICH').k == 'NOTEQUALS':
             self.error_handler.handle_error('UNGLEICH in WHILE erwartet.')
 
-        zero_token = self.next_nonempty_token("WHILE", "0")
+        zero_token = self.next_nonempty_token('WHILE', '0')
         if not zero_token.k == 'NUMBER':
             self.error_handler.handle_error('0 in WHILE erwartet.')
         if not int(zero_token.v) == 0:
             self.error_handler.handle_error('0 in WHILE erwartet.')
 
-        if not self.next_nonempty_token("WHILE", "DO").k == 'DO':
+        if not self.next_nonempty_token('WHILE', 'DO').k == 'DO':
             self.error_handler.handle_error('DO in WHILE erwartet.')
 
         if identifier_token.v in self.values:
@@ -76,7 +103,7 @@ class WHILEInterpreter(LOOPInterpreter):
             while not end_found:
                 token = self.verify_program(forbidden_identifiers, self.next_token())
                 if token is None or token.k not in ['SEMICOLON', 'END']:
-                    self.error_handler.handle_error("SEMICOLON oder END in WHILE erwartet.")
+                    self.error_handler.handle_error('SEMICOLON oder END in WHILE erwartet.')
                 elif token.k == 'SEMICOLON':
                     continue
                 elif token.k == 'END':
@@ -89,7 +116,7 @@ class WHILEInterpreter(LOOPInterpreter):
             while not end_found:
                 token = self.process_program(forbidden_identifiers, self.next_token())
                 if token is None or token.k not in ['SEMICOLON', 'END']:
-                    self.error_handler.handle_error("SEMICOLON oder END in WHILE erwartet.")
+                    self.error_handler.handle_error('SEMICOLON oder END in WHILE erwartet.')
                 elif token.k == 'SEMICOLON':
                     continue
                 elif token.k == 'END':
@@ -102,29 +129,29 @@ class WHILEInterpreter(LOOPInterpreter):
         return self.next_token()
 
     def verify_while(self, forbidden_identifiers, current_token):
-        identifier_token = self.next_nonempty_token("WHILE", "IDENTIFIER")
+        identifier_token = self.next_nonempty_token('WHILE', 'IDENTIFIER')
         if not identifier_token.k == 'IDENTIFIER':
             self.error_handler.handle_error('IDENTIFIER in WHILE erwartet.')
         if identifier_token.v in forbidden_identifiers:
-            self.error_handler.handle_error("Identifier " + identifier_token.v +
-                                            " ist bereits in Loop vorhanden und darf nicht verwendet werden.")
-        if not self.next_nonempty_token("WHILE", "UNGLEICH").k == 'NOTEQUALS':
+            self.error_handler.handle_error('Identifier ' + identifier_token.v +
+                                            ' ist bereits in Loop vorhanden und darf nicht verwendet werden.')
+        if not self.next_nonempty_token('WHILE', 'UNGLEICH').k == 'NOTEQUALS':
             self.error_handler.handle_error('UNGLEICH in WHILE erwartet.')
 
-        zero_token = self.next_nonempty_token("WHILE", "0")
+        zero_token = self.next_nonempty_token('WHILE', '0')
         if not zero_token.k == 'NUMBER':
             self.error_handler.handle_error('0 in WHILE erwartet.')
         if not int(zero_token.v) == 0:
             self.error_handler.handle_error('0 in WHILE erwartet.')
 
-        if not self.next_nonempty_token("WHILE", "DO").k == 'DO':
+        if not self.next_nonempty_token('WHILE', 'DO').k == 'DO':
             self.error_handler.handle_error('DO in WHILE erwartet.')
 
         end_found = False
         while not end_found:
             token = self.verify_program(forbidden_identifiers, self.next_token())
             if token is None or token.k not in ['SEMICOLON', 'END']:
-                self.error_handler.handle_error("SEMICOLON oder END in WHILE erwartet.")
+                self.error_handler.handle_error('SEMICOLON oder END in WHILE erwartet.')
             elif token.k == 'SEMICOLON':
                 continue
             elif token.k == 'END':
@@ -132,7 +159,30 @@ class WHILEInterpreter(LOOPInterpreter):
 
         return self.next_token()
 
-
-def interpret(program):
-    interpreter = WHILEInterpreter()
+    def interpret(self, program):
+        try:
+            with Timeout(self.timeout):
+                self.lex = lexer.Lexer(self.regex_to_token, program)
+                self.error_handler = ErrorHandler(program, self)
+                self.values = {}
+                forbidden_identifiers = []
+                current_token = self.next_token()
+                while current_token is not None:
+                    current_token = self.process_program(forbidden_identifiers, current_token)
+                    if current_token is not None:
+                        if not current_token.k == 'SEMICOLON':
+                            self.error_handler.handle_error('Semicolon erwartet')
+                        current_token = self.next_token()
+                        if current_token is None:
+                            self.error_handler.handle_error('Semikolons werden nur zur Trennung und nicht zum ' +
+                                                            'Abschluss von Programmen verwendet')
+                if 'x0' in self.values:
+                    return self.values.get('x0')
+                return 0
+        except KeyboardInterrupt:
+            return -1
+
+
+def interpret(program, timeout=60):
+    interpreter = WHILEInterpreter(timeout)
     return interpreter.interpret(program)