blob: 53ba43af03a2eea4102bce48cd7cbe40f4481816 [file] [log] [blame]
swissChili7babd922021-12-02 22:46:48 -08001#include "Token.h"
swissChili07d325f2021-12-08 20:02:05 -08002#include "AstNode.h"
swissChili7babd922021-12-02 22:46:48 -08003
swissChili1060c0e2021-12-09 09:46:42 -08004#include <QDebug>
5
swissChili07d325f2021-12-08 20:02:05 -08006template class TokenBase<Token>;
7
8// This is kind of ugly and breaks separation of concerns; but if I don't do
9// this I have to define everything in headers which is worse.
10template class TokenBase<AstNode>;
11
12template <typename T>
13TokenBase<T>::TokenBase(const T &other)
14{
15 _type = other._type;
16 _stringVal = other._stringVal;
17 _listVal = other._listVal;
18 _charVal = other._charVal;
19}
20
21template <typename T>
22TokenBase<T>::TokenBase(QChar symbol)
23{
24 _type = SYM;
25 _charVal = symbol;
26}
27
28template <typename T>
29TokenBase<T>::TokenBase(QString identifier)
30{
31 _type = IDENT;
32 _stringVal = identifier;
33}
34
35template <typename T>
36TokenBase<T>::TokenBase(QList<T> parenthesized)
37{
38 _type = PAREN;
39 _listVal = std::move(parenthesized);
40}
41
42template <typename T>
swissChili9dddbf72021-12-08 23:03:25 -080043TokenBase<T>::TokenBase(QString integer, int base)
44{
45 _type = INTEGER;
46 _intVal = integer.toInt(nullptr, base);
47}
48
49template <typename T>
swissChili1060c0e2021-12-09 09:46:42 -080050T TokenBase<T>::fromInteger(int integer)
51{
52 T tok;
53
54 tok._type = INTEGER;
55 tok._intVal = integer;
56
57 return tok;
58}
59
60template <typename T>
swissChili07d325f2021-12-08 20:02:05 -080061TokenBase<T>::TokenBase(char varType, const QString name)
62{
63 _type = VAR;
64 _charVal = varType;
65 _stringVal = name;
66}
67
68template <typename T>
69bool TokenBase<T>::isSym() const
70{
71 return _type == SYM;
72}
73
74template <typename T>
75bool TokenBase<T>::isIdent() const
76{
77 return _type == IDENT;
78}
79
80template <typename T>
81bool TokenBase<T>::isParen() const
82{
83 return _type == PAREN;
84}
85template <typename T>
86bool TokenBase<T>::isVar() const
87{
88 return _type == VAR;
89}
90
91template <typename T>
swissChili9dddbf72021-12-08 23:03:25 -080092bool TokenBase<T>::isInteger() const
93{
94 return _type == INTEGER;
95}
96
97template <typename T>
swissChili07d325f2021-12-08 20:02:05 -080098TokenBase<T>::TokenBase() : TokenBase("Null")
99{
100}
101
102template <typename T>
103bool TokenBase<T>::operator==(const T &other) const
104{
swissChili1060c0e2021-12-09 09:46:42 -0800105 // Why is this needed? Beats me.
106 if (isInteger() && other.isInteger())
107 return _intVal == other._intVal;
108
109 return _type == other._type &&
110 _stringVal == other._stringVal &&
111 _charVal == other._charVal &&
112 _listVal == other._listVal &&
113 _intVal == other._intVal;
swissChili07d325f2021-12-08 20:02:05 -0800114}
115
116template <typename T>
117QList<T> TokenBase<T>::parenContent()
118{
119 if (isParen())
120 {
121 return _listVal;
122 }
123 else
124 {
125 return {};
126 }
127}
128
129template <typename T>
swissChili9dddbf72021-12-08 23:03:25 -0800130int TokenBase<T>::integer() const
131{
132 return _intVal;
133}
134
135template <typename T>
swissChili07d325f2021-12-08 20:02:05 -0800136char TokenBase<T>::varType() const
137{
138 return _charVal.toLatin1();
139}
140
141template <typename T>
142const QString &TokenBase<T>::name() const
143{
144 return _stringVal;
145}
146
147template <typename T>
148bool TokenBase<T>::operator!=(const T &other) const
149{
150 return !(this->operator==(other));
151}
152
153template <typename T>
154TokenBase<T>::operator QString() const
155{
156 if (isIdent())
157 return _stringVal;
158 if (isSym())
159 return _charVal;
160 if (isVar())
161 return QString(_charVal) + "." + _stringVal;
swissChili9dddbf72021-12-08 23:03:25 -0800162 if (isInteger())
163 return QString::number(_intVal, 10);
swissChili07d325f2021-12-08 20:02:05 -0800164 if (isParen())
165 {
166 QStringList parts;
167 for (const T &tok : _listVal)
168 {
169 parts.append(static_cast<QString>(tok));
170 }
171
172 return "(" + parts.join(" ") + ")";
173 }
174
175 return "Null";
176}
177
178template <typename T>
179int TokenBase<T>::type() const
180{
181 return _type;
182}
183
184template <typename T>
185QString TokenBase<T>::typeToString(int type)
186{
swissChili9dddbf72021-12-08 23:03:25 -0800187 static const QString typeNames[] = {"SYMBOL", "IDENT", "PAREN", "VAR", "INTEGER"};
swissChili07d325f2021-12-08 20:02:05 -0800188 return typeNames[type];
189}
190
191template <typename T>
192QChar TokenBase<T>::symbol() const
193{
194 return _charVal;
195}