Skip to content

Commit 607e072

Browse files
committed
Initial control flow syntax highlighting implementation
1 parent 90051ce commit 607e072

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

gui/qt/datawidget.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ AsmHighlighter::AsmHighlighter(QTextDocument *parent) : QSyntaxHighlighter(paren
143143

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

146+
controlFlowFormat.setForeground(QColor("crimson"));
147+
controlFlowTargetFormat.setForeground(QColor("#dc795d"));
148+
146149
symbolFormat.setFontWeight(disasm.bold_sym ? QFont::DemiBold : QFont::Normal);
147150
rule.pattern = QRegularExpression("\\b\\w+\\b");
148151
rule.format = symbolFormat;
@@ -187,6 +190,14 @@ void AsmHighlighter::highlightBlock(const QString &text) {
187190
setFormat(match.capturedStart(4), match.capturedLength(4), breakPFormat);
188191
setFormat(match.capturedStart(5), match.capturedLength(5), bytesFormat);
189192
setFormat(match.capturedStart(6), match.capturedLength(6), mnemonicFormat);
193+
194+
const QString fullMnemonic = match.captured(6);
195+
const QString primary = fullMnemonic.section('.', 0, 0).toUpper();
196+
const bool isControlFlow = std::find(controlFlowMnemonics.begin(), controlFlowMnemonics.end(), primary) != controlFlowMnemonics.end();
197+
if (isControlFlow) {
198+
setFormat(match.capturedStart(6), match.capturedLength(6), controlFlowFormat);
199+
}
200+
190201
foreach(const HighlightingRule &rule, highlightingRules) {
191202
QRegularExpressionMatchIterator iter = rule.pattern.globalMatch(text, match.capturedEnd());
192203
while (iter.hasNext()) {
@@ -196,5 +207,45 @@ void AsmHighlighter::highlightBlock(const QString &text) {
196207
}
197208
}
198209
}
210+
211+
if (!isControlFlow) {
212+
return;
213+
}
214+
215+
if (std::find(noTargetMnemonics.begin(), noTargetMnemonics.end(), primary) != noTargetMnemonics.end()) {
216+
return;
217+
}
218+
219+
const int operandStart = match.capturedEnd();
220+
const QString operands = text.mid(operandStart);
221+
222+
// hex address patterns allowing optional +/ - after '$' for relative forms like $+5
223+
const QRegularExpression hexTargetRe(QStringLiteral("\\$[+\\-]?[0-9A-Fa-f]+\\b"));
224+
QRegularExpressionMatchIterator hIt = hexTargetRe.globalMatch(operands);
225+
while (hIt.hasNext()) {
226+
const auto m2 = hIt.next();
227+
if (m2.hasMatch()) {
228+
const int s = operandStart + m2.capturedStart();
229+
const int l = m2.capturedLength();
230+
setFormat(s, l, controlFlowTargetFormat);
231+
}
232+
}
233+
234+
// equate/label tokens (exclude registers and condition codes)
235+
const QRegularExpression labelRe(QStringLiteral("\\b[._A-Za-z][._A-Za-z0-9]*\\b"));
236+
237+
QRegularExpressionMatchIterator lIt = labelRe.globalMatch(operands);
238+
while (lIt.hasNext()) {
239+
const auto m3 = lIt.next();
240+
if (m3.hasMatch()) {
241+
const QString tok = m3.captured().toUpper();
242+
if (std::find(reservedTokens.begin(), reservedTokens.end(), tok) != reservedTokens.end()) {
243+
continue;
244+
}
245+
const int start = operandStart + m3.capturedStart();
246+
const int len = m3.capturedLength();
247+
setFormat(start, len, controlFlowTargetFormat);
248+
}
249+
}
199250
}
200251
}

gui/qt/datawidget.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <QtGui/QTextCharFormat>
77
#include <QtCore/QRegularExpression>
88
#include <QtCore/QObject>
9+
#include <QtCore/QStringList>
910

1011
QT_BEGIN_NAMESPACE
1112
class QPaintEvent;
@@ -39,11 +40,39 @@ class AsmHighlighter : public QSyntaxHighlighter
3940
QTextCharFormat breakPFormat;
4041
QTextCharFormat bytesFormat;
4142
QTextCharFormat mnemonicFormat;
43+
QTextCharFormat controlFlowFormat;
44+
QTextCharFormat controlFlowTargetFormat;
4245
QTextCharFormat hexFormat;
4346
QTextCharFormat decimalFormat;
4447
QTextCharFormat parenFormat;
4548
QTextCharFormat registerFormat;
4649

50+
std::array<std::string_view, 8> controlFlowMnemonics {
51+
"CALL",
52+
"DJNZ",
53+
"JP",
54+
"JR",
55+
"RET",
56+
"RETI",
57+
"RETN",
58+
"RST"
59+
};
60+
61+
std::array<std::string_view, 3> noTargetMnemonics {
62+
"RET",
63+
"RETI",
64+
"RETN"
65+
};
66+
67+
std::array<std::string_view, 29> reservedTokens {
68+
"A", "B", "C", "D", "E", "H", "L", "I", "R",
69+
"AF", "BC", "DE", "HL", "SP",
70+
"IX", "IY", "IXH", "IXL",
71+
"IYH", "IYL", "MB",
72+
"NZ", "Z", "NC", "C",
73+
"PO", "PE", "P", "M"
74+
};
75+
4776
QRegularExpression labelPattern;
4877
QRegularExpression instructionPattern;
4978
};

0 commit comments

Comments
 (0)