Skip to content

Commit eb495cd

Browse files
committed
fix #194: correctly display edit prompt when interrupting a syntax error trap with ctrl+break
1 parent 4aa5e58 commit eb495cd

File tree

3 files changed

+33
-14
lines changed

3 files changed

+33
-14
lines changed

pcbasic/basic/base/error.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,13 @@ class Break(Interrupt):
103103

104104
message = b'Break'
105105

106-
def __init__(self, stop=False):
106+
def __init__(self, stop=False, pos=None):
107107
"""Initialise break."""
108108
Interrupt.__init__(self)
109109
self.stop = stop
110+
self.pos = pos
111+
self.trapped_error_num = None
112+
self.trapped_error_pos = None
110113

111114

112115
class BASICError(Interrupt):

pcbasic/basic/implementation.py

+21-8
Original file line numberDiff line numberDiff line change
@@ -400,12 +400,20 @@ def _handle_exceptions(self):
400400
"""Context guard to handle BASIC exceptions."""
401401
try:
402402
yield
403-
except error.Break:
403+
except error.Break as e:
404+
# ctrl-break stops foreground and background sound
404405
self.sound.stop_all_sound()
405-
self._prompt = False
406+
if not self.interpreter.run_mode and not e.stop:
407+
self._prompt = False
408+
else:
409+
self.interpreter.set_pointer(False)
410+
# call _handle_error to write a message, etc.
411+
self._handle_error(e)
412+
# override position of syntax error
413+
if e.trapped_error_num == error.STX:
414+
self._syntax_error_edit_prompt(e.trapped_error_pos)
406415
except error.BASICError as e:
407416
self._handle_error(e)
408-
self._prompt = True
409417
except error.Exit:
410418
raise
411419

@@ -416,13 +424,18 @@ def _handle_error(self, e):
416424
self.console.write(e.get_message(self.program.get_line_number(e.pos)))
417425
self.interpreter.set_parse_mode(False)
418426
self.interpreter.input_mode = False
427+
self._prompt = True
419428
# special case: syntax error
420429
if e.err == error.STX:
421-
# for some reason, err is reset to zero by GW-BASIC in this case.
422-
self.interpreter.error_num = 0
423-
if e.pos is not None and e.pos != -1:
424-
# line edit gadget appears
425-
self._edit_prompt = (self.program.get_line_number(e.pos), e.pos+1)
430+
self._syntax_error_edit_prompt(e.pos)
431+
432+
def _syntax_error_edit_prompt(self, pos):
433+
"""Show an EDIT prompt at the location of a syntax error."""
434+
# for some reason, err is reset to zero by GW-BASIC in this case.
435+
self.interpreter.error_num = 0
436+
if pos is not None and pos != -1:
437+
# line edit gadget appears
438+
self._edit_prompt = (self.program.get_line_number(pos), pos+1)
426439

427440
###########################################################################
428441
# callbacks

pcbasic/basic/interpreter.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ def loop(self):
123123
# parse until break or end
124124
self.parse()
125125
except error.Break as e:
126-
# ctrl-break stops foreground and background sound
127126
self._sound.stop_all_sound()
128127
self._handle_break(e)
129128
# move pointer to the start of direct line (for both on and off!)
@@ -150,11 +149,15 @@ def _handle_break(self, e):
150149
else:
151150
self._program.bytecode.skip_to(tk.END_STATEMENT)
152151
self.stop = self._program.bytecode.tell()
153-
self._console.start_line()
154-
self._console.write(e.get_message(self._program.get_line_number(pos)))
155-
self.set_parse_mode(False)
156-
self.input_mode = False
157152
self.parser.redo_on_break = False
153+
if self.error_handle_mode:
154+
e.trapped_error_num = self.error_num
155+
e.trapped_error_pos = self.error_pos
156+
#self.error_handle_mode = False
157+
# ensure we can handle the break like an error
158+
e.err = 0
159+
e.pos = pos
160+
raise e
158161

159162
###########################################################################
160163
# clear state

0 commit comments

Comments
 (0)