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[]) {