blob: 53ba43af03a2eea4102bce48cd7cbe40f4481816 [file] [log] [blame]
#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;
}