Add parenthesis matching
diff --git a/Matcher.cpp b/Matcher.cpp
index b4dda6d..3fc4670 100644
--- a/Matcher.cpp
+++ b/Matcher.cpp
@@ -18,10 +18,16 @@
} else {
return MatchResult{false, context};
}
- } else if (ph.isParen() && dataHead.isParen()) {
+ } else if (ph.isParen()) {
data.removeFirst();
+
+ qDebug() << "parens, dh = " << dataHead;
+ qDebug() << "Matching parens" << dataHead.parenContent() << ph.parenContent();
+
auto result = match(dataHead.parenContent(), ph.parenContent(), context);
+ qDebug() << "parens result was" << result.success << "in ctx" << result.context;
+
if (result.success) {
return match(data, pattern, result.context);
} else {
@@ -87,6 +93,10 @@
}
// If this worked we would have returned already
return MatchResult{false, context};
+
+ default:
+ qDebug() << "#TYPE_ERROR";
+ return MatchResult{false, context};
}
}
}
diff --git a/Token.cpp b/Token.cpp
index 4d36344..4ebf058 100644
--- a/Token.cpp
+++ b/Token.cpp
@@ -1,5 +1,8 @@
#include "Token.h"
+#include <QDebug>
+#include <utility>
+
Token::Token(const Token &other) {
*this = other;
}
@@ -14,9 +17,9 @@
_stringVal = identifier;
}
-Token::Token(QList<Token> &&parenthesized) {
+Token::Token(QList<Token> parenthesized) {
_type = PAREN;
- _listVal = parenthesized;
+ _listVal = std::move(parenthesized);
}
Token::Token(char varType, const QString &&name) {
@@ -25,19 +28,19 @@
_stringVal = name;
}
-bool Token::isSym() {
+bool Token::isSym() const {
return _type == SYM;
}
-bool Token::isIdent() {
+bool Token::isIdent() const {
return _type == IDENT;
}
-bool Token::isParen() {
+bool Token::isParen() const {
return _type == PAREN;
}
-bool Token::isVar() {
+bool Token::isVar() const {
return _type == VAR;
}
@@ -70,3 +73,31 @@
bool Token::operator!=(const Token &other) const {
return !(this->operator==(other));
}
+
+Token::operator QString() const {
+ if (isIdent())
+ return _stringVal;
+ if (isSym())
+ return _charVal;
+ if (isVar())
+ return QString(_charVal) + "." + _stringVal;
+ if (isParen()) {
+ QStringList parts;
+ for (const Token &tok : _listVal) {
+ parts.append(static_cast<QString>(tok));
+ }
+
+ return "(" + parts.join(" ") + ")";
+ }
+
+ return "Null";
+}
+
+int Token::type() const {
+ return _type;
+}
+
+QString Token::typeToString(int type) {
+ static const QString typeNames[] = {"SYMBOL", "IDENT", "PAREN", "VAR"};
+ return typeNames[type];
+}
diff --git a/Token.h b/Token.h
index a0a5eaa..4835de0 100644
--- a/Token.h
+++ b/Token.h
@@ -10,27 +10,33 @@
explicit Token(QChar symbol);
explicit Token(QString &&identifier);
- explicit Token(QList<Token> &&parenthesized);
+ explicit Token(QList<Token> parenthesized);
Token(char varType, const QString &&name);
bool operator ==(const Token &other) const;
bool operator !=(const Token &other) const;
- bool isSym();
- bool isIdent();
- bool isParen();
- bool isVar();
+ bool isSym() const;
+ bool isIdent() const;
+ bool isParen() const;
+ bool isVar() const;
QList<Token> parenContent();
char varType() const;
const QString &name() const;
-private:
+ operator QString() const;
+
enum Type {
SYM, IDENT, PAREN, VAR,
};
+ static QString typeToString(int type);
+
+ int type() const;
+
+private:
int _type = 0;
QString _stringVal = "";
QList<Token> _listVal;
diff --git a/VarContext.cpp b/VarContext.cpp
index 031ec42..a67df2b 100644
--- a/VarContext.cpp
+++ b/VarContext.cpp
@@ -23,3 +23,22 @@
QList<Token> VarContext::expressionVar(const QString &name) {
return _vars[name].expressionValue;
}
+
+QDebug &operator <<(QDebug &debug, const VarContext &ctx) {
+ for (const auto &name: ctx._vars.keys()) {
+ char t = ctx._vars[name].t;
+ auto d = debug.nospace().noquote() << t << '.' << name << ":";
+
+ if (t != 'e')
+ d.nospace() << "( " << ctx._vars[name].value << " )";
+ else
+ d << "( " << ctx._vars[name].expressionValue << " )";
+ d << "; ";
+ }
+
+ if (ctx._vars.empty()) {
+ debug << "{}";
+ }
+
+ return debug;
+}
diff --git a/VarContext.h b/VarContext.h
index 3da8b9d..5e580b3 100644
--- a/VarContext.h
+++ b/VarContext.h
@@ -1,6 +1,7 @@
#pragma once
#include <QMap>
+#include <QDebug>
#include "Token.h"
class VarContext {
@@ -15,6 +16,8 @@
Token singleVar(const QString &name);
QList<Token> expressionVar(const QString &name);
+ friend QDebug &operator <<(QDebug &debug, const VarContext &ctx);
+
private:
struct Var {
Var() = default;
@@ -25,4 +28,6 @@
};
QMap<QString, Var> _vars;
-};
\ No newline at end of file
+};
+
+QDebug &operator <<(QDebug &debug, const VarContext &ctx);
\ No newline at end of file
diff --git a/main.cpp b/main.cpp
index a343682..ebf886f 100644
--- a/main.cpp
+++ b/main.cpp
@@ -9,10 +9,15 @@
void printResult(const QString &test, bool shouldBe, const MatchResult &result) {
if (result.success != shouldBe) {
g_numFailed++;
- qDebug() << "TEST FAILS:";
+ qDebug() << "\nTEST FAILS:";
+ qDebug() << "with context" << result.context;
}
qDebug() << "MatchResult" << test << result.success;
+
+ if (result.success != shouldBe) {
+ qDebug() << "";
+ }
}
int testResults() {
@@ -28,6 +33,8 @@
void runTests() {
printResult("a = a", true, match({Token('a')}, {Token('a')}, VarContext()));
+ printResult("s.a = y", true, match({Token('y')}, {Token('s', "a")}, VarContext()));
+
LTok sameTwo = {Token('s', "a"), Token('s', "a")};
printResult("s.a s.a = aa", true, match({Token('a'), Token('a')}, sameTwo, VarContext()));
printResult("s.a s.a = ab", false, match({Token('a'), Token('b')}, sameTwo, VarContext()));
@@ -51,6 +58,28 @@
match({
Token('a'), Token('e'), Token('f'), Token("Hi"), Token('c')
}, sameStartEnd, VarContext()));
+
+ LTok parenthesized = {
+ Token(LTok({
+ Token('s', "a")
+ })),
+ Token('e', "Middle"),
+ Token('s', "a"),
+ };
+ LTok parenTest1 = {
+ Token(LTok({
+ Token('y')
+ })),
+ Token('f'),
+ Token("MiddleStuff"),
+ Token('y')
+ };
+
+ printResult("(s.a) e.Middle s.a = (y)f MiddleStuff y", true,
+ match(parenTest1, parenthesized, VarContext()));
+
+ printResult("(a) = (a)", true,
+ match({Token({Token('a')})}, {Token({Token('a')})}, VarContext()));
}
int main(int argc, char *argv[]) {