blob: c7cc7d7e23080c44132391a8da874993306132ce [file] [log] [blame]
swissChili7babd922021-12-02 22:46:48 -08001#pragma once
2
3#include <QList>
4#include <QChar>
5
swissChilic71acc62021-12-07 08:03:37 -08006template <typename T>
7class TokenBase
8{
swissChili7babd922021-12-02 22:46:48 -08009public:
swissChilic71acc62021-12-07 08:03:37 -080010 TokenBase();
11 TokenBase(const T &other);
swissChili7babd922021-12-02 22:46:48 -080012
swissChili9dddbf72021-12-08 23:03:25 -080013 TokenBase(QString integer, int base);
swissChilic71acc62021-12-07 08:03:37 -080014 explicit TokenBase(QChar symbol);
15 explicit TokenBase(QString identifier);
16 explicit TokenBase(QList<T> parenthesized);
17 TokenBase(char varType, const QString name);
swissChili7babd922021-12-02 22:46:48 -080018
swissChili1060c0e2021-12-09 09:46:42 -080019 static T fromInteger(int integer);
20
swissChilic71acc62021-12-07 08:03:37 -080021 bool operator==(const T &other) const;
22 bool operator!=(const T &other) const;
swissChili7babd922021-12-02 22:46:48 -080023
swissChilid17b5a12021-12-05 20:46:42 -080024 bool isSym() const;
25 bool isIdent() const;
26 bool isParen() const;
27 bool isVar() const;
swissChili9dddbf72021-12-08 23:03:25 -080028 bool isInteger() const;
swissChili7babd922021-12-02 22:46:48 -080029
swissChilic71acc62021-12-07 08:03:37 -080030 QList<T> parenContent();
swissChili7babd922021-12-02 22:46:48 -080031
swissChili3e98c062021-12-04 22:07:38 -080032 char varType() const;
33 const QString &name() const;
swissChili682e7bc2021-12-07 09:04:54 -080034 QChar symbol() const;
swissChili9dddbf72021-12-08 23:03:25 -080035 int integer() const;
swissChili3e98c062021-12-04 22:07:38 -080036
swissChilid17b5a12021-12-05 20:46:42 -080037 operator QString() const;
38
swissChilic71acc62021-12-07 08:03:37 -080039 enum
40 {
41 SYM,
42 IDENT,
43 PAREN,
44 VAR,
swissChili9dddbf72021-12-08 23:03:25 -080045 INTEGER,
swissChilic71acc62021-12-07 08:03:37 -080046 TOKEN_TYPE_LAST,
swissChili7babd922021-12-02 22:46:48 -080047 };
48
swissChilid17b5a12021-12-05 20:46:42 -080049 static QString typeToString(int type);
50
51 int type() const;
52
swissChilic71acc62021-12-07 08:03:37 -080053protected:
swissChili7babd922021-12-02 22:46:48 -080054 int _type = 0;
swissChili9dddbf72021-12-08 23:03:25 -080055 int _intVal = 0;
swissChili7babd922021-12-02 22:46:48 -080056 QString _stringVal = "";
swissChilic71acc62021-12-07 08:03:37 -080057 QList<T> _listVal;
swissChilie386bc72022-02-24 21:31:31 -080058 QChar _charVal = QChar(0);
swissChili7babd922021-12-02 22:46:48 -080059};
swissChili3e98c062021-12-04 22:07:38 -080060
swissChilic8894fa2022-04-16 19:21:56 -070061template <typename T>
62TokenBase<T>::TokenBase(const T &other)
63{
64 _type = other._type;
65 _stringVal = other._stringVal;
66 _listVal = other._listVal;
67 _charVal = other._charVal;
68}
69
70template <typename T>
71TokenBase<T>::TokenBase(QChar symbol)
72{
73 _type = SYM;
74 _charVal = symbol;
75}
76
77template <typename T>
78TokenBase<T>::TokenBase(QString identifier)
79{
80 _type = IDENT;
81 _stringVal = identifier;
82}
83
84template <typename T>
85TokenBase<T>::TokenBase(QList<T> parenthesized)
86{
87 _type = PAREN;
88 _listVal = std::move(parenthesized);
89}
90
91template <typename T>
92TokenBase<T>::TokenBase(QString integer, int base)
93{
94 _type = INTEGER;
95 _intVal = integer.toInt(nullptr, base);
96}
97
98template <typename T>
99T TokenBase<T>::fromInteger(int integer)
100{
101 T tok;
102
103 tok._type = INTEGER;
104 tok._intVal = integer;
105
106 return tok;
107}
108
109template <typename T>
110TokenBase<T>::TokenBase(char varType, const QString name)
111{
112 _type = VAR;
113 _charVal = varType;
114 _stringVal = name;
115}
116
117template <typename T>
118bool TokenBase<T>::isSym() const
119{
120 return _type == SYM;
121}
122
123template <typename T>
124bool TokenBase<T>::isIdent() const
125{
126 return _type == IDENT;
127}
128
129template <typename T>
130bool TokenBase<T>::isParen() const
131{
132 return _type == PAREN;
133}
134template <typename T>
135bool TokenBase<T>::isVar() const
136{
137 return _type == VAR;
138}
139
140template <typename T>
141bool TokenBase<T>::isInteger() const
142{
143 return _type == INTEGER;
144}
145
146template <typename T>
147TokenBase<T>::TokenBase() : TokenBase("Null")
148{
149}
150
151template <typename T>
152bool TokenBase<T>::operator==(const T &other) const
153{
154 // Why is this needed? Beats me.
155 if (isInteger() && other.isInteger())
156 return _intVal == other._intVal;
157
158 return _type == other._type &&
159 _stringVal == other._stringVal &&
160 _charVal == other._charVal &&
161 _listVal == other._listVal &&
162 _intVal == other._intVal;
163}
164
165template <typename T>
166QList<T> TokenBase<T>::parenContent()
167{
168 if (isParen())
169 {
170 return _listVal;
171 }
172 else
173 {
174 return {};
175 }
176}
177
178template <typename T>
179int TokenBase<T>::integer() const
180{
181 return _intVal;
182}
183
184template <typename T>
185char TokenBase<T>::varType() const
186{
187 return _charVal.toLatin1();
188}
189
190template <typename T>
191const QString &TokenBase<T>::name() const
192{
193 return _stringVal;
194}
195
196template <typename T>
197bool TokenBase<T>::operator!=(const T &other) const
198{
199 return !(this->operator==(other));
200}
201
202template <typename T>
203TokenBase<T>::operator QString() const
204{
205 if (isIdent())
206 return _stringVal;
207 if (isSym())
208 return _charVal;
209 if (isVar())
210 return QString(_charVal) + "." + _stringVal;
211 if (isInteger())
212 return QString::number(_intVal, 10);
213 if (isParen())
214 {
215 QStringList parts;
216 for (const T &tok : _listVal)
217 {
218 parts.append(static_cast<QString>(tok));
219 }
220
221 return "(" + parts.join(" ") + ")";
222 }
223
224 return "Null";
225}
226
227template <typename T>
228int TokenBase<T>::type() const
229{
230 return _type;
231}
232
233template <typename T>
234QString TokenBase<T>::typeToString(int type)
235{
236 static const QString typeNames[] = {"SYMBOL", "IDENT", "PAREN", "VAR", "INTEGER"};
237 return typeNames[type];
238}
239
240template <typename T>
241QChar TokenBase<T>::symbol() const
242{
243 return _charVal;
244}
245
swissChilic71acc62021-12-07 08:03:37 -0800246class Token : public TokenBase<Token>
247{
248public:
swissChilic8894fa2022-04-16 19:21:56 -0700249 using TokenBase<Token>::TokenBase;
swissChilic71acc62021-12-07 08:03:37 -0800250};
251
swissChili3e98c062021-12-04 22:07:38 -0800252using LTok = QList<Token>;