Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/assembler/assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "isa/isainfo.h"
#include "isa/pseudoinstruction.h"
#include "matcher.h"
#include "parserutilities.h"
#include "ripessettings.h"

namespace Ripes {
Expand Down Expand Up @@ -244,12 +245,15 @@ class Assembler : public AssemblerBase {
if (line.value().isEmpty())
continue;
TokenizedSrcLine tsl(line.index());
runOperation(tokens, tokenize, tsl, line.value());
runOperation(tokens, tokenizeQuotes, tsl, line.value());

runOperation(remainingTokens, splitCommentFromLine, tokens);

runOperation(joinedParentheses, joinParentheses, tsl, remainingTokens);

// Symbols precede directives
runOperation(symbolsAndRest, splitSymbolsFromLine, tsl, remainingTokens);
runOperation(symbolsAndRest, splitSymbolsFromLine, tsl,
joinedParentheses);

tsl.symbols = symbolsAndRest.first;

Expand Down
30 changes: 8 additions & 22 deletions src/assembler/assemblerbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,6 @@ void AssemblerBase::setDirectives(const DirectiveVec &directives) {
}
}

Result<LineTokens> AssemblerBase::tokenize(const Location &location,
const QString &line) const {
auto quoteTokenized = tokenizeQuotes(location, line);
if (auto *error = std::get_if<Error>(&quoteTokenized))
return {*error};

auto joinedtokens =
joinParentheses(location, std::get<QStringList>(quoteTokenized));
if (auto *err = std::get_if<Error>(&joinedtokens))
return *err;

return std::get<LineTokens>(joinedtokens);
}

Result<QByteArray>
AssemblerBase::assembleDirective(const DirectiveArg &arg, bool &ok,
bool skipEarlyDirectives) const {
Expand Down Expand Up @@ -199,16 +185,16 @@ AssemblerBase::splitDirectivesFromLine(const Location &location,
}
}

Result<LineTokens>
AssemblerBase::splitCommentFromLine(const LineTokens &tokens) const {
if (tokens.size() == 0) {
return {tokens};
Result<QStringList>
AssemblerBase::splitCommentFromLine(const QStringList &stringTokens) const {
if (stringTokens.size() == 0) {
return {stringTokens};
}

LineTokens preCommentTokens;
preCommentTokens.reserve(tokens.size());
for (const auto &token : tokens) {
if (token.contains(commentDelimiter())) {
QStringList preCommentTokens;
preCommentTokens.reserve(stringTokens.size());
for (const auto &token : stringTokens) {
if (token.startsWith(commentDelimiter())) {
break;
} else {
preCommentTokens.push_back(token);
Expand Down
5 changes: 2 additions & 3 deletions src/assembler/assemblerbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ class AssemblerBase {
protected:
/// Creates a set of LineTokens by tokenizing a line of source code.
QRegularExpression m_splitterRegex;
Result<LineTokens> tokenize(const Location &location,
const QString &line) const;

Result<QByteArray> assembleDirective(const DirectiveArg &arg, bool &ok,
bool skipEarlyDirectives = true) const;
Expand All @@ -109,7 +107,8 @@ class AssemblerBase {
/// Given an input set of tokens, splits away commented code from the tokens
/// based on the comment delimiter, i.e.:
/// {"a", "b", "#", "c"} => {"a", "b"}
Result<LineTokens> splitCommentFromLine(const LineTokens &tokens) const;
Result<QStringList>
splitCommentFromLine(const QStringList &stringTokens) const;

/// Returns the comment-delimiting character for this assembler.
virtual QChar commentDelimiter() const = 0;
Expand Down
6 changes: 5 additions & 1 deletion src/assembler/parserutilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ namespace Assembler {
Result<LineTokens> joinParentheses(const Location &location,
const QStringList &tokens);

/// Quote-aware string tokenization.
/**
* @brief Quote-aware string tokenization.
* separates tokens by either ' ', ',' or '\t' characters
* and returns a list of those separated strings
*/
Result<QStringList> tokenizeQuotes(const Location &location,
const QString &line);
} // namespace Assembler
Expand Down
9 changes: 9 additions & 0 deletions test/tst_assembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ private slots:
void tst_stringDirectives();
void tst_riscv();
void tst_relativeLabels();
void tst_parentheses();

private:
QString createProgram(int entries) {
Expand Down Expand Up @@ -416,5 +417,13 @@ void tst_Assembler::tst_matcher() {
}
}

void tst_Assembler::tst_parentheses() {
testAssemble(QStringList() << "lw x0, 0(x1)", Expect::Success);
testAssemble(QStringList() << "lw x0, 0(x1", Expect::Fail);
testAssemble(QStringList() << "lw x0, 0(x1 # ignored )", Expect::Fail);
testAssemble(QStringList() << "#(valid parentheses match)", Expect::Success);
testAssemble(QStringList() << "#)nonmatching parentheses(", Expect::Success);
}

QTEST_APPLESS_MAIN(tst_Assembler)
#include "tst_assembler.moc"
Loading