Fix compilation for Clang & MSVC
diff --git a/.gitignore b/.gitignore
index 2892543..0754dce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
build
.cache
compile_commands.json
+build-*
diff --git a/AstNode.h b/AstNode.h
index 1cf66d4..6ab397c 100644
--- a/AstNode.h
+++ b/AstNode.h
@@ -5,7 +5,7 @@
class AstNode : public TokenBase<AstNode>
{
public:
- using TokenBase::TokenBase;
+ using TokenBase<AstNode>::TokenBase;
AstNode(QString function, QList<AstNode> args);
diff --git a/REFAL.pro b/REFAL.pro
index 320dc5b..8726fb9 100644
--- a/REFAL.pro
+++ b/REFAL.pro
@@ -15,7 +15,6 @@
Parser.cpp \
PPrint.cpp \
StdLib.cpp \
- Token.cpp \
VarContext.cpp
HEADERS += \
diff --git a/Token.cpp b/Token.cpp
deleted file mode 100644
index 53ba43a..0000000
--- a/Token.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-#include "Token.h"
-#include "AstNode.h"
-
-#include <QDebug>
-
-template class TokenBase<Token>;
-
-// This is kind of ugly and breaks separation of concerns; but if I don't do
-// this I have to define everything in headers which is worse.
-template class TokenBase<AstNode>;
-
-template <typename T>
-TokenBase<T>::TokenBase(const T &other)
-{
- _type = other._type;
- _stringVal = other._stringVal;
- _listVal = other._listVal;
- _charVal = other._charVal;
-}
-
-template <typename T>
-TokenBase<T>::TokenBase(QChar symbol)
-{
- _type = SYM;
- _charVal = symbol;
-}
-
-template <typename T>
-TokenBase<T>::TokenBase(QString identifier)
-{
- _type = IDENT;
- _stringVal = identifier;
-}
-
-template <typename T>
-TokenBase<T>::TokenBase(QList<T> parenthesized)
-{
- _type = PAREN;
- _listVal = std::move(parenthesized);
-}
-
-template <typename T>
-TokenBase<T>::TokenBase(QString integer, int base)
-{
- _type = INTEGER;
- _intVal = integer.toInt(nullptr, base);
-}
-
-template <typename T>
-T TokenBase<T>::fromInteger(int integer)
-{
- T tok;
-
- tok._type = INTEGER;
- tok._intVal = integer;
-
- return tok;
-}
-
-template <typename T>
-TokenBase<T>::TokenBase(char varType, const QString name)
-{
- _type = VAR;
- _charVal = varType;
- _stringVal = name;
-}
-
-template <typename T>
-bool TokenBase<T>::isSym() const
-{
- return _type == SYM;
-}
-
-template <typename T>
-bool TokenBase<T>::isIdent() const
-{
- return _type == IDENT;
-}
-
-template <typename T>
-bool TokenBase<T>::isParen() const
-{
- return _type == PAREN;
-}
-template <typename T>
-bool TokenBase<T>::isVar() const
-{
- return _type == VAR;
-}
-
-template <typename T>
-bool TokenBase<T>::isInteger() const
-{
- return _type == INTEGER;
-}
-
-template <typename T>
-TokenBase<T>::TokenBase() : TokenBase("Null")
-{
-}
-
-template <typename T>
-bool TokenBase<T>::operator==(const T &other) const
-{
- // Why is this needed? Beats me.
- if (isInteger() && other.isInteger())
- return _intVal == other._intVal;
-
- return _type == other._type &&
- _stringVal == other._stringVal &&
- _charVal == other._charVal &&
- _listVal == other._listVal &&
- _intVal == other._intVal;
-}
-
-template <typename T>
-QList<T> TokenBase<T>::parenContent()
-{
- if (isParen())
- {
- return _listVal;
- }
- else
- {
- return {};
- }
-}
-
-template <typename T>
-int TokenBase<T>::integer() const
-{
- return _intVal;
-}
-
-template <typename T>
-char TokenBase<T>::varType() const
-{
- return _charVal.toLatin1();
-}
-
-template <typename T>
-const QString &TokenBase<T>::name() const
-{
- return _stringVal;
-}
-
-template <typename T>
-bool TokenBase<T>::operator!=(const T &other) const
-{
- return !(this->operator==(other));
-}
-
-template <typename T>
-TokenBase<T>::operator QString() const
-{
- if (isIdent())
- return _stringVal;
- if (isSym())
- return _charVal;
- if (isVar())
- return QString(_charVal) + "." + _stringVal;
- if (isInteger())
- return QString::number(_intVal, 10);
- if (isParen())
- {
- QStringList parts;
- for (const T &tok : _listVal)
- {
- parts.append(static_cast<QString>(tok));
- }
-
- return "(" + parts.join(" ") + ")";
- }
-
- return "Null";
-}
-
-template <typename T>
-int TokenBase<T>::type() const
-{
- return _type;
-}
-
-template <typename T>
-QString TokenBase<T>::typeToString(int type)
-{
- static const QString typeNames[] = {"SYMBOL", "IDENT", "PAREN", "VAR", "INTEGER"};
- return typeNames[type];
-}
-
-template <typename T>
-QChar TokenBase<T>::symbol() const
-{
- return _charVal;
-}
diff --git a/Token.h b/Token.h
index 82c1906..c7cc7d7 100644
--- a/Token.h
+++ b/Token.h
@@ -58,10 +58,195 @@
QChar _charVal = QChar(0);
};
+template <typename T>
+TokenBase<T>::TokenBase(const T &other)
+{
+ _type = other._type;
+ _stringVal = other._stringVal;
+ _listVal = other._listVal;
+ _charVal = other._charVal;
+}
+
+template <typename T>
+TokenBase<T>::TokenBase(QChar symbol)
+{
+ _type = SYM;
+ _charVal = symbol;
+}
+
+template <typename T>
+TokenBase<T>::TokenBase(QString identifier)
+{
+ _type = IDENT;
+ _stringVal = identifier;
+}
+
+template <typename T>
+TokenBase<T>::TokenBase(QList<T> parenthesized)
+{
+ _type = PAREN;
+ _listVal = std::move(parenthesized);
+}
+
+template <typename T>
+TokenBase<T>::TokenBase(QString integer, int base)
+{
+ _type = INTEGER;
+ _intVal = integer.toInt(nullptr, base);
+}
+
+template <typename T>
+T TokenBase<T>::fromInteger(int integer)
+{
+ T tok;
+
+ tok._type = INTEGER;
+ tok._intVal = integer;
+
+ return tok;
+}
+
+template <typename T>
+TokenBase<T>::TokenBase(char varType, const QString name)
+{
+ _type = VAR;
+ _charVal = varType;
+ _stringVal = name;
+}
+
+template <typename T>
+bool TokenBase<T>::isSym() const
+{
+ return _type == SYM;
+}
+
+template <typename T>
+bool TokenBase<T>::isIdent() const
+{
+ return _type == IDENT;
+}
+
+template <typename T>
+bool TokenBase<T>::isParen() const
+{
+ return _type == PAREN;
+}
+template <typename T>
+bool TokenBase<T>::isVar() const
+{
+ return _type == VAR;
+}
+
+template <typename T>
+bool TokenBase<T>::isInteger() const
+{
+ return _type == INTEGER;
+}
+
+template <typename T>
+TokenBase<T>::TokenBase() : TokenBase("Null")
+{
+}
+
+template <typename T>
+bool TokenBase<T>::operator==(const T &other) const
+{
+ // Why is this needed? Beats me.
+ if (isInteger() && other.isInteger())
+ return _intVal == other._intVal;
+
+ return _type == other._type &&
+ _stringVal == other._stringVal &&
+ _charVal == other._charVal &&
+ _listVal == other._listVal &&
+ _intVal == other._intVal;
+}
+
+template <typename T>
+QList<T> TokenBase<T>::parenContent()
+{
+ if (isParen())
+ {
+ return _listVal;
+ }
+ else
+ {
+ return {};
+ }
+}
+
+template <typename T>
+int TokenBase<T>::integer() const
+{
+ return _intVal;
+}
+
+template <typename T>
+char TokenBase<T>::varType() const
+{
+ return _charVal.toLatin1();
+}
+
+template <typename T>
+const QString &TokenBase<T>::name() const
+{
+ return _stringVal;
+}
+
+template <typename T>
+bool TokenBase<T>::operator!=(const T &other) const
+{
+ return !(this->operator==(other));
+}
+
+template <typename T>
+TokenBase<T>::operator QString() const
+{
+ if (isIdent())
+ return _stringVal;
+ if (isSym())
+ return _charVal;
+ if (isVar())
+ return QString(_charVal) + "." + _stringVal;
+ if (isInteger())
+ return QString::number(_intVal, 10);
+ if (isParen())
+ {
+ QStringList parts;
+ for (const T &tok : _listVal)
+ {
+ parts.append(static_cast<QString>(tok));
+ }
+
+ return "(" + parts.join(" ") + ")";
+ }
+
+ return "Null";
+}
+
+template <typename T>
+int TokenBase<T>::type() const
+{
+ return _type;
+}
+
+template <typename T>
+QString TokenBase<T>::typeToString(int type)
+{
+ static const QString typeNames[] = {"SYMBOL", "IDENT", "PAREN", "VAR", "INTEGER"};
+ return typeNames[type];
+}
+
+template <typename T>
+QChar TokenBase<T>::symbol() const
+{
+ return _charVal;
+}
+
class Token : public TokenBase<Token>
{
public:
- using TokenBase::TokenBase;
+ using TokenBase<Token>::TokenBase;
};
using LTok = QList<Token>;