Skip to content

Commit

Permalink
Use a syntax highlighter for disassembly, customize dark mode colors
Browse files Browse the repository at this point in the history
  • Loading branch information
calc84maniac committed Jan 13, 2024
1 parent 2619e6f commit 96614a2
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 42 deletions.
80 changes: 80 additions & 0 deletions gui/qt/datawidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

DataWidget::DataWidget(QWidget *parent) : QPlainTextEdit{parent} {
moveable = false;
highlighter = new AsmHighlighter(document());
QFont font = this->font();
font.setStyleHint(QFont::TypeWriter);
setFont(font);
setContextMenuPolicy(Qt::CustomContextMenu);
}

Expand All @@ -15,6 +19,8 @@ void DataWidget::updateDarkMode() {
selection.format.setBackground(selection.format.colorProperty(QTextFormat::UserProperty + darkMode));
}
updateAllHighlights();
delete highlighter;
highlighter = new AsmHighlighter(document());
}

void DataWidget::clearAllHighlights() {
Expand All @@ -25,6 +31,8 @@ void DataWidget::clearAllHighlights() {

highlights.clear();
updateAllHighlights();
delete highlighter;
highlighter = new AsmHighlighter(document());
}

void DataWidget::updateAllHighlights() {
Expand Down Expand Up @@ -118,3 +126,75 @@ void DataWidget::highlightCurrentLine() {
}
}
}

AsmHighlighter::AsmHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) {
HighlightingRule rule;
bool darkMode = isRunningInDarkMode();

addressFormat.setForeground(QColor(darkMode ? "#888" : "#444"));
addressFormat.setFontWeight(QFont::Bold);

watchRFormat.setForeground(QColor("#008000"));
watchRFormat.setFontWeight(QFont::Bold);
watchWFormat.setForeground(QColor("#808000"));
watchWFormat.setFontWeight(QFont::Bold);
breakPFormat.setForeground(QColor("#800000"));
breakPFormat.setFontWeight(QFont::Bold);

mnemonicFormat.setForeground(QColor(darkMode ? "darkorange" : "darkblue"));

symbolFormat.setFontWeight(disasm.bold_sym ? QFont::DemiBold : QFont::Normal);
rule.pattern = QRegularExpression("\\b\\w+\\b");
rule.format = symbolFormat;
highlightingRules.append(rule);

decimalFormat.setForeground(QColor(darkMode ? "lime" : "green"));
rule.pattern = QRegularExpression("\\b\\d+\\b");
rule.format = decimalFormat;
highlightingRules.append(rule);

registerFormat.setForeground(QColor(darkMode ? "magenta" : "purple"));
rule.pattern = QRegularExpression("\\b([abcdehlirmpz]|af|bc|de|hl|sp|i[xy][hl]?|mb|n[cz]|p[eo])\\b", QRegularExpression::CaseInsensitiveOption);
rule.format = registerFormat;
highlightingRules.append(rule);

hexFormat.setForeground(QColor(darkMode ? "lime" : "green"));
rule.pattern = QRegularExpression("\\$[0-9a-fA-F]+\\b");
rule.format = hexFormat;
highlightingRules.append(rule);

parenFormat.setForeground(QColor(darkMode ? "lightblue" : "navy"));
rule.pattern = QRegularExpression("[()]");
rule.format = parenFormat;
highlightingRules.append(rule);

labelPattern = QRegularExpression(QStringLiteral("^(%1)\\s+(\\S+):")
.arg(disasm.addr ? QStringLiteral("[0-9a-fA-F]+") : QString()));
instructionPattern = QRegularExpression(QStringLiteral("^(%1) ([ R])([ W])([ X])\\s+(%2)\\s+(\\S+)")
.arg(disasm.addr ? QStringLiteral("[0-9a-fA-F]+") : QString(),
disasm.bytes ? QStringLiteral("[0-9a-fA-F]+") : QStringLiteral(" ")));
}

void AsmHighlighter::highlightBlock(const QString &text) {
QRegularExpressionMatch match;
if ((match = labelPattern.match(text)).hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), addressFormat);
setFormat(match.capturedStart(2), match.capturedLength(2), symbolFormat);
} else if ((match = instructionPattern.match(text)).hasMatch()) {
setFormat(match.capturedStart(1), match.capturedLength(1), addressFormat);
setFormat(match.capturedStart(2), match.capturedLength(2), watchRFormat);
setFormat(match.capturedStart(3), match.capturedLength(3), watchWFormat);
setFormat(match.capturedStart(4), match.capturedLength(4), breakPFormat);
setFormat(match.capturedStart(5), match.capturedLength(5), bytesFormat);
setFormat(match.capturedStart(6), match.capturedLength(6), mnemonicFormat);
foreach(const HighlightingRule &rule, highlightingRules) {
QRegularExpressionMatchIterator iter = rule.pattern.globalMatch(text, match.capturedEnd());
while (iter.hasNext()) {
const auto& innerMatch = iter.next();
if (innerMatch.hasMatch()) {
setFormat(innerMatch.capturedStart(), innerMatch.capturedLength(), rule.format);
}
}
}
}
}
38 changes: 38 additions & 0 deletions gui/qt/datawidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#define CODEEDITOR_H

#include <QtWidgets/QPlainTextEdit>
#include <QtGui/QSyntaxHighlighter>
#include <QtGui/QTextCharFormat>
#include <QtCore/QRegularExpression>
#include <QtCore/QObject>

QT_BEGIN_NAMESPACE
Expand All @@ -11,6 +14,40 @@ QT_BEGIN_NAMESPACE
class QWidget;
QT_END_NAMESPACE

class AsmHighlighter : public QSyntaxHighlighter
{
Q_OBJECT

public:
AsmHighlighter(QTextDocument *parent = nullptr);

protected:
void highlightBlock(const QString &text) Q_DECL_OVERRIDE;

private:
struct HighlightingRule
{
QRegularExpression pattern;
QTextCharFormat format;
};
QVector<HighlightingRule> highlightingRules;

QTextCharFormat addressFormat;
QTextCharFormat symbolFormat;
QTextCharFormat watchRFormat;
QTextCharFormat watchWFormat;
QTextCharFormat breakPFormat;
QTextCharFormat bytesFormat;
QTextCharFormat mnemonicFormat;
QTextCharFormat hexFormat;
QTextCharFormat decimalFormat;
QTextCharFormat parenFormat;
QTextCharFormat registerFormat;

QRegularExpression labelPattern;
QRegularExpression instructionPattern;
};

class DataWidget : public QPlainTextEdit {
Q_OBJECT

Expand All @@ -31,6 +68,7 @@ class DataWidget : public QPlainTextEdit {

private:
bool moveable;
AsmHighlighter *highlighter;
QList<QTextEdit::ExtraSelection> highlights;
};

Expand Down
24 changes: 4 additions & 20 deletions gui/qt/debugger/disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@ static std::string strW(uint32_t data) {
if (high) {
range = disasm.map.equal_range(data);
for (sit = range.first; sit != range.second; ++sit) {
if (disasm.bold_sym) {
ret += "<b>" + sit->second + "</b>";
} else {
ret += sit->second;
}
ret += sit->second;
ret += '|';
}
if (!ret.empty()) {
Expand All @@ -37,11 +33,7 @@ static std::string strW(uint32_t data) {
if (!disasm.il) {
range = disasm.map.equal_range(cpu.registers.MBASE<<16|data);
for (sit = range.first; sit != range.second; ++sit) {
if (disasm.bold_sym) {
ret += "<b>" + sit->second + "</b>";
} else {
ret += sit->second;
}
ret += sit->second;
ret += '|';
}
if (!ret.empty()) {
Expand All @@ -67,11 +59,7 @@ static std::string strA(uint32_t data) {
if (!ret.empty()) {
ret += '|';
}
if (disasm.bold_sym) {
ret += "<b>" + sit->second + "</b>";
} else {
ret += sit->second;
}
ret += sit->second;
}
}
if (!ret.empty()) {
Expand All @@ -86,11 +74,7 @@ static std::string strA(uint32_t data) {
if (!ret.empty()) {
ret += '|';
}
if (disasm.bold_sym) {
ret += "<b>" + sit->second + "</b>";
} else {
ret += sit->second;
}
ret += sit->second;
}
}
if (!ret.empty()) {
Expand Down
31 changes: 10 additions & 21 deletions gui/qt/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,6 @@ void MainWindow::darkModeSwitch(bool darkMode) {
#ifdef Q_OS_WIN
QApplication::setStyle(darkMode ? "fusion" : "windowsvista");
#endif
m_disasmOpcodeColor = darkMode ? "darkorange" : "darkblue";
if (darkMode) {
m_cBack.setColor(QPalette::Base, QColor(Qt::blue).lighter(180));
m_cBack.setColor(QPalette::Text, Qt::black);
Expand Down Expand Up @@ -2389,41 +2388,31 @@ void MainWindow::disasmLine() {

QString line;
QString symbols;
QString highlighted;

if (useLabel) {
if (disasm.base > 511 || (disasm.base < 512 && sit->second[0] == '_')) {
line = QString(QStringLiteral("<pre><b><font color='#444'>%1</font></b> %2</pre>"))
.arg(int2hex(static_cast<uint32_t>(disasm.base), 6),
QString::fromStdString(disasm.bold_sym ? "<b>" + sit->second + "</b>" : sit->second) + ":");
line = QStringLiteral("%1 %2:")
.arg(disasm.addr ? int2hex(static_cast<uint32_t>(disasm.base), 6) : QString(),
QString::fromStdString(sit->second));

m_disasm->appendHtml(line);
m_disasm->appendPlainText(line);
}

if (numLines == j + 1) {
useLabel = false;
}
sit++;
} else {
symbols = QString(QStringLiteral("<b><font color='#008000'>%1</font><font color='#808000'>%2</font><font color='#800000'>%3</font></b>"))
.arg((disasm.highlight.watchR ? QStringLiteral("R") : QStringLiteral(" ")),
(disasm.highlight.watchW ? QStringLiteral("W") : QStringLiteral(" ")),
(disasm.highlight.breakP ? QStringLiteral("X") : QStringLiteral(" ")));

highlighted = QString::fromStdString(disasm.instr.operands)
.replace(QRegularExpression(QStringLiteral("(\\$[0-9a-fA-F]+)")), QStringLiteral("<font color='green'>\\1</font>")) // hex numbers
.replace(QRegularExpression(QStringLiteral("(^\\d)")), QStringLiteral("<font color='blue'>\\1</font>")) // dec number
.replace(QRegularExpression(QStringLiteral("([()])")), QStringLiteral("<font color='#600'>\\1</font>")); // parentheses

line = QString(QStringLiteral("<pre><b><font color='#444'>%1</font></b> %2 %3 <font color='%4'>%5</font> %6</pre>"))
line = QString(QStringLiteral("%1 %2%3%4 %5 %6 %7"))
.arg(disasm.addr ? int2hex(static_cast<uint32_t>(disasm.base), 6) : QString(),
symbols,
disasm.highlight.watchR ? QStringLiteral("R") : QStringLiteral(" "),
disasm.highlight.watchW ? QStringLiteral("W") : QStringLiteral(" "),
disasm.highlight.breakP ? QStringLiteral("X") : QStringLiteral(" "),
disasm.bytes ? QString::fromStdString(disasm.instr.data).leftJustified(12, ' ') : QStringLiteral(" "),
m_disasmOpcodeColor,
QString::fromStdString(disasm.instr.opcode),
highlighted);
QString::fromStdString(disasm.instr.operands));

m_disasm->appendHtml(line);
m_disasm->appendPlainText(line);
}
}

Expand Down
1 change: 0 additions & 1 deletion gui/qt/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,6 @@ class MainWindow : public QMainWindow {
InterCom com;

bool m_isInDarkMode = false;
const char* m_disasmOpcodeColor;

int m_watchGUIMask = DBG_MASK_NONE;

Expand Down

0 comments on commit 96614a2

Please sign in to comment.