def edit(from_line, bytepos=None): """ Output program line to console and position cursor. """ if state.basic_state.protected: console.write(str(from_line) + '\r') raise error.RunError(error.IFC) # list line state.basic_state.bytecode.seek(state.basic_state.line_numbers[from_line] + 1) _, output, textpos = tokenise.detokenise_line(state.basic_state.bytecode, bytepos) # no newline to avoid scrolling on line 24 console.list_line(str(output), newline=False) # find row, column position for textpos newlines, c = 0, 0 pos_row, pos_col = 0, 0 for i, byte in enumerate(output): c += 1 if chr(byte) == '\n' or c > state.console_state.screen.mode.width: newlines += 1 c = 0 if i == textpos: pos_row, pos_col = newlines, c if textpos > i: pos_row, pos_col = newlines, c + 1 if bytepos: console.set_pos(state.console_state.row - newlines + pos_row, pos_col) else: console.set_pos(state.console_state.row - newlines, 1)
def edit(from_line, bytepos=None): """ Output program line to console and position cursor. """ if state.basic_state.protected: console.write(str(from_line)+'\r') raise error.RunError(error.IFC) # list line state.basic_state.bytecode.seek(state.basic_state.line_numbers[from_line]+1) _, output, textpos = tokenise.detokenise_line(state.basic_state.bytecode, bytepos) # no newline to avoid scrolling on line 24 console.list_line(str(output), newline=False) # find row, column position for textpos newlines, c = 0, 0 pos_row, pos_col = 0, 0 if not output: return for i, byte in enumerate(output): c += 1 if chr(byte) == '\n' or c > state.console_state.screen.mode.width: newlines += 1 c = 0 if i == textpos: pos_row, pos_col = newlines, c if textpos > i: pos_row, pos_col = newlines, c + 1 if bytepos: console.set_pos(state.console_state.row-newlines+pos_row, pos_col) else: console.set_pos(state.console_state.row-newlines, 1)
def list_lines(from_line, to_line): """ List line range. """ if state.basic_state.protected: # don't list protected files raise error.RunError(error.IFC) # 65529 is max insertable line number for GW-BASIC 3.23. # however, 65530-65535 are executed if present in tokenised form. # in GW-BASIC, 65530 appears in LIST, 65531 and above are hidden if to_line is None: to_line = max_list_line # sort by positions, not line numbers! listable = sorted([ state.basic_state.line_numbers[num] for num in state.basic_state.line_numbers if num >= from_line and num <= to_line ]) lines = [] for pos in listable: state.basic_state.bytecode.seek(pos + 1) _, line, _ = tokenise.detokenise_line(state.basic_state.bytecode) lines.append(str(line)) flow.set_pointer(False) return lines
def list_lines(dev, from_line, to_line): """ List line range to console or device. """ if state.basic_state.protected: # don't list protected files raise error.RunError(5) # 65529 is max insertable line number for GW-BASIC 3.23. # however, 65530-65535 are executed if present in tokenised form. # in GW-BASIC, 65530 appears in LIST, 65531 and above are hidden if to_line == None: to_line = max_list_line # sort by positions, not line numbers! listable = sorted([ state.basic_state.line_numbers[num] for num in state.basic_state.line_numbers if num >= from_line and num <= to_line ]) for pos in listable: state.basic_state.bytecode.seek(pos + 1) _, line, _ = tokenise.detokenise_line(state.basic_state.bytecode) if dev == backend.devices['SCRN:']: console.list_line(str(line)) else: dev.write_line(str(line)) dev.close() flow.set_pointer(False)
def save(g, mode='B'): """ Save the program to stream g in (A)scii, (B)ytecode or (P)rotected mode. """ if state.basic_state.protected and mode != 'P': raise error.RunError(5) current = state.basic_state.bytecode.tell() # skip first \x00 in bytecode, replace with appropriate magic number state.basic_state.bytecode.seek(1) if mode == 'B': # binary bytecode mode g.write('\xff') last = '' while True: nxt = state.basic_state.bytecode.read(1) if not nxt: break g.write(nxt) last = nxt if last != '\x1a': g.write('\x1a') elif mode == 'P': # protected mode g.write('\xfe') protect.protect(state.basic_state.bytecode, g) g.write('\x1a') else: # ascii mode while True: current_line, output, _ = tokenise.detokenise_line(state.basic_state.bytecode) if current_line == -1 or (current_line > max_list_line): break output = str(output) if utf8_files: output = unicodepage.UTF8Converter().to_utf8(output) g.write(output + '\r\n') # close with ^Z if we're in GW-BASIC text file mode to match GW-BASIC files exactly # don't do this in UTF8-mode as it's a bit odd to have a legacy end-of-file marker in a UTF8 text. if not utf8_files: g.write('\x1a') state.basic_state.bytecode.seek(current) g.close()
def save(g): """ Save the program to stream g in (A)scii, (B)ytecode or (P)rotected mode. """ mode = g.filetype if state.basic_state.protected and mode != 'P': raise error.RunError(error.IFC) current = state.basic_state.bytecode.tell() # skip first \x00 in bytecode state.basic_state.bytecode.seek(1) if mode == 'B': # binary bytecode mode g.write(state.basic_state.bytecode.read()) elif mode == 'P': # protected mode protect.protect(state.basic_state.bytecode, g) else: # ascii mode while True: current_line, output, _ = tokenise.detokenise_line(state.basic_state.bytecode) if current_line == -1 or (current_line > max_list_line): break g.write_line(str(output)) state.basic_state.bytecode.seek(current)
def save(g): """ Save the program to stream g in (A)scii, (B)ytecode or (P)rotected mode. """ mode = g.filetype if state.basic_state.protected and mode != 'P': raise error.RunError(error.IFC) current = state.basic_state.bytecode.tell() # skip first \x00 in bytecode state.basic_state.bytecode.seek(1) if mode == 'B': # binary bytecode mode g.write(state.basic_state.bytecode.read()) elif mode == 'P': # protected mode protect.protect(state.basic_state.bytecode, g) else: # ascii mode while True: current_line, output, _ = tokenise.detokenise_line( state.basic_state.bytecode) if current_line == -1 or (current_line > max_list_line): break g.write_line(str(output)) state.basic_state.bytecode.seek(current)