代码拉取完成,页面将自动刷新
同步操作将从 FSHelix/PyBrainfuckIDE 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
from enum import Enum
from PySide6.QtUiTools import QUiLoader
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtGui import QTextCursor, QIcon, QCloseEvent
import kernal
class Mode(Enum):
STOP = 0
RUNNING = 1
TRACING = 2
def read_from(filename):
file = QFile(filename)
file.open(QIODevice.ReadOnly | QIODevice.Text)
stream = QTextStream(file)
s = stream.readAll()
file.close()
return s
def write_to(filename, text):
file = QFile(filename)
file.open(QIODevice.WriteOnly | QIODevice.Text)
stream = QTextStream(file)
stream << text
stream.flush()
file.close()
class UiManager(QObject):
def __init__(self):
super().__init__()
self.ker = kernal.Kernal()
self.currentMode = Mode.STOP
self.currentFilename = None
self.ui = QUiLoader().load('ui/main.ui')
self.ui.menuFileNew.triggered.connect(self.when_new)
self.ui.menuFileOpen.triggered.connect(self.when_open)
self.ui.menuFileSave.triggered.connect(self.when_save)
self.ui.menuFileSaveas.triggered.connect(self.when_saveas)
self.ui.menuRunAnalyze.triggered.connect(self.when_analyze)
self.ui.menuRunForwRun.triggered.connect(self.when_forw_run)
self.ui.menuRunBackwRun.triggered.connect(self.when_backw_run)
self.ui.menuRunForwStep.triggered.connect(self.when_forw_step)
self.ui.menuRunBackwStep.triggered.connect(self.when_backw_step)
self.ui.menuRunForwTo.triggered.connect(self.when_forw_to)
self.ui.menuRunBackwTo.triggered.connect(self.when_backw_to)
self.ui.menuRunPause.triggered.connect(self.when_pause)
self.ui.menuRunStop.triggered.connect(self.when_stop)
self.ui.memField.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.ui.setWindowIcon(QIcon('icon/icon.ico'))
self.update_title()
self.ui.show()
def eventFilter(self, obj, event):
if obj == self.ui and type(event) == QCloseEvent:
if self.maybe_save():
event.accept()
else:
event.ignore()
return True
else:
return super().eventFilter(obj, event)
def update_title(self):
if self.currentFilename:
self.ui.setWindowTitle(self.currentFilename + ' - BrainfuckIDE')
else:
self.ui.setWindowTitle('BrainfuckIDE')
def update_cursor(self):
cursor = self.ui.codeField.textCursor()
cursor.setPosition(min(self.ker.codePointer, len(self.ker.code) - 1))
cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor)
selection = QTextEdit.ExtraSelection()
selection.cursor = cursor
selection.format.setBackground(Qt.lightGray)
self.ui.codeField.setExtraSelections([selection])
cursor.clearSelection()
self.ui.codeField.setTextCursor(cursor)
def update_output(self):
self.ui.outputField.setPlainText(self.ker.output)
self.ui.outputField.moveCursor(QTextCursor.End)
def update_memory(self):
pos = self.ker.dataPointer
while pos >= self.ui.memField.rowCount():
self.ui.memField.insertRow(pos)
self.ui.memField.setItem(pos, 0, QTableWidgetItem(str(pos)))
self.ui.memField.setItem(pos, 1, QTableWidgetItem(str(self.ker.mem[pos])))
self.ui.memField.item(pos, 1).setText(str(self.ker.mem[pos]))
for r in self.ui.memField.selectedRanges():
self.ui.memField.setRangeSelected(r, False)
self.ui.memField.setRangeSelected(QTableWidgetSelectionRange(pos, 0, pos, 1), True)
self.ui.memField.scrollToItem(self.ui.memField.item(pos, 0))
def lock_panel(self):
self.ui.codeField.setReadOnly(True)
self.ui.inputField.setReadOnly(True)
def unlock_panel(self):
self.ui.codeField.setReadOnly(False)
self.ui.inputField.setReadOnly(False)
def maybe_save(self):
if self.ui.codeField.document().isModified():
reply = QMessageBox.question(
self.ui, '提示', '是否保存当前文件?',
QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel,
QMessageBox.Save)
if reply == QMessageBox.Discard or reply == QMessageBox.Save and self.when_save():
return True
else:
return False
return True
def clear_all(self):
self.ui.codeField.clear()
self.ui.inputField.clear()
self.ui.outputField.clear()
self.ui.memField.clearContents()
self.ui.memField.setRowCount(0)
def when_start(self):
self.lock_panel()
self.ker.load(self.ui.codeField.toPlainText(), self.ui.inputField.toPlainText())
self.ker.analyze()
self.ker.start()
self.ui.memField.clearContents()
self.ui.memField.setRowCount(0)
self.update_memory()
def when_new(self):
if self.maybe_save():
self.when_stop()
self.clear_all()
self.currentFilename = None
self.update_title()
self.ui.codeField.clear()
self.ui.codeField.document().setModified(False)
return True
return False
def when_open(self):
if self.maybe_save():
filename = QFileDialog.getOpenFileName(self.ui)[0]
if not filename:
return False
self.when_stop()
self.clear_all()
self.currentFilename = filename
self.update_title()
self.ui.codeField.setPlainText(read_from(filename))
self.ui.codeField.document().setModified(False)
return True
return False
def when_save(self):
if not self.currentFilename:
return self.when_saveas()
write_to(self.currentFilename, self.ui.codeField.toPlainText())
self.ui.codeField.document().setModified(False)
return True
def when_saveas(self):
filename = QFileDialog.getSaveFileName(self.ui)[0]
if not filename:
return False
self.currentFilename = filename
self.update_title()
write_to(filename, self.ui.codeField.toPlainText())
self.ui.codeField.document().setModified(False)
return True
def when_analyze(self):
if self.ui.codeField.toPlainText() == '':
QMessageBox.warning(self.ui, '提示', '代码不能为空')
return
try:
self.ker.load(self.ui.codeField.toPlainText(), self.ui.inputField.toPlainText())
self.ker.analyze()
except AssertionError:
QMessageBox.warning(self.ui, '语法检查', '语法错误')
else:
QMessageBox.information(self.ui, '语法检查', '语法正确')
def when_forw_run(self):
def run_():
if self.currentMode == Mode.RUNNING and self.ker.step_forw():
self.update_cursor()
self.update_output()
self.update_memory()
else:
timer.stop()
if self.ui.codeField.toPlainText() == '':
QMessageBox.warning(self.ui, '提示', '代码不能为空')
return
if self.currentMode != Mode.STOP and self.currentMode != Mode.TRACING:
return
if self.currentMode == Mode.STOP:
self.when_start()
self.currentMode = Mode.RUNNING
timer = QTimer()
timer.timeout.connect(run_)
timer.start(0)
def when_backw_run(self):
def run_():
if self.currentMode == Mode.RUNNING and self.ker.step_backw():
self.update_cursor()
self.update_output()
self.update_memory()
else:
timer.stop()
if self.ui.codeField.toPlainText() == '':
QMessageBox.warning(self.ui, '提示', '代码不能为空')
return
if self.currentMode != Mode.STOP and self.currentMode != Mode.TRACING:
return
if self.currentMode == Mode.STOP:
self.when_start()
self.currentMode = Mode.RUNNING
timer = QTimer()
timer.timeout.connect(run_)
timer.start(0)
def when_forw_step(self):
if self.ui.codeField.toPlainText() == '':
QMessageBox.warning(self.ui, '提示', '代码不能为空')
return
if self.currentMode != Mode.STOP and self.currentMode != Mode.TRACING:
return
if self.currentMode == Mode.STOP:
self.when_start()
self.currentMode = Mode.TRACING
self.ker.step_forw()
self.update_cursor()
self.update_output()
self.update_memory()
def when_backw_step(self):
if self.ui.codeField.toPlainText() == '':
QMessageBox.warning(self.ui, '提示', '代码不能为空')
return
if self.currentMode != Mode.TRACING:
return
self.ker.step_backw()
self.update_cursor()
self.update_output()
self.update_memory()
def when_forw_to(self):
def run_():
if self.currentMode == Mode.RUNNING and self.ker.codePointer != pos and self.ker.step_forw():
self.update_cursor()
self.update_output()
self.update_memory()
else:
self.currentMode = Mode.TRACING
timer.stop()
if self.ui.codeField.toPlainText() == '':
QMessageBox.warning(self.ui, '提示', '代码不能为空')
return
if self.currentMode != Mode.STOP and self.currentMode != Mode.TRACING:
return
if self.currentMode == Mode.STOP:
self.when_start()
self.currentMode = Mode.RUNNING
pos = self.ui.codeField.textCursor().position()
timer = QTimer()
timer.timeout.connect(run_)
timer.start(0)
def when_backw_to(self):
def run_():
if self.currentMode == Mode.RUNNING and self.ker.codePointer != pos and self.ker.step_backw():
self.update_cursor()
self.update_output()
self.update_memory()
else:
self.currentMode = Mode.TRACING
timer.stop()
if self.ui.codeField.toPlainText() == '':
QMessageBox.warning(self.ui, '提示', '代码不能为空')
return
if self.currentMode != Mode.TRACING:
return
self.currentMode = Mode.RUNNING
pos = self.ui.codeField.textCursor().position()
timer = QTimer()
timer.timeout.connect(run_)
timer.start(0)
def when_pause(self):
if self.currentMode != Mode.RUNNING:
return
self.currentMode = Mode.TRACING
def when_stop(self):
self.currentMode = Mode.STOP
self.ui.codeField.setExtraSelections([])
self.unlock_panel()
for r in self.ui.memField.selectedRanges():
self.ui.memField.setRangeSelected(r, False)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。