MXVM 1.8.1
Virtual Machine, Compiler, and Pascal Frontend
Loading...
Searching...
No Matches
string_buffer.hpp
Go to the documentation of this file.
1
6#ifndef _STR_BUF_X
7#define _STR_BUF_X
8
9#include "types.hpp"
10#include <cstdint>
11#include <optional>
12#include <string>
13#include <unordered_map>
14
15namespace scan {
16 namespace buffer {
26 template <typename Ch = char, typename String = std::basic_string<Ch, std::char_traits<Ch>>>
28 public:
29 using ch_type = Ch;
30 using string_type = String;
36 StringBuffer(const string_type &buf, const std::string &filename = "unknown");
38 std::optional<ch_type> getch();
40 std::optional<ch_type> curch();
45 std::optional<ch_type> peekch(int num = 1);
47 std::optional<ch_type> prevch();
52 std::optional<ch_type> forward_step(int num = 1);
57 std::optional<ch_type> backward_step(int num = 1);
59 std::pair<uint64_t, uint64_t> cur_line();
61 std::string cur_file() const;
67 void process_line_directive(uint64_t newLine, const std::string &newFile);
72 bool eof(uint64_t pos = 0);
77 void reset(uint64_t pos = 0);
78
79 private:
81 uint64_t index;
82 uint64_t currentLine;
83 uint64_t currentColumn;
84 std::string currentFile;
85 };
86
87 template <typename Ch, typename String>
89 const std::string &filename)
90 : buffer_{buf + " \n"}, index{0},
92 currentFile{filename} {}
93
94 template <typename Ch, typename String>
95 std::optional<Ch> StringBuffer<Ch, String>::getch() {
96 if (index < buffer_.length()) {
97 Ch ch = buffer_[index++];
98 if (ch == '\n') {
100 currentColumn = 1;
101 } else {
103 }
104 return ch;
105 }
106 return std::nullopt;
107 }
108
109 template <typename Ch, typename String>
111 if (index < buffer_.length())
112 return buffer_[index];
113 return std::nullopt;
114 }
115
116 template <typename Ch, typename String>
117 std::optional<Ch> StringBuffer<Ch, String>::peekch(int num) {
118 if (index + num < buffer_.length())
119 return buffer_[index + num];
120 return std::nullopt;
121 }
122
123 template <typename Ch, typename String>
125 if (index > 0)
126 return buffer_[index - 1];
127 return std::nullopt;
128 }
129
130 template <typename Ch, typename String>
131 std::optional<Ch> StringBuffer<Ch, String>::forward_step(int num) {
132 if (index + num < buffer_.length()) {
133 index += num;
134 return buffer_[index];
135 }
136 return std::nullopt;
137 }
138
139 template <typename Ch, typename String>
140 std::optional<Ch> StringBuffer<Ch, String>::backward_step(int num) {
141 if (static_cast<int64_t>(index) >= num) {
142 index -= num;
143 if (buffer_[index] == '\n') {
144 currentLine--;
145 currentColumn = 1;
146 }
147 return buffer_[index];
148 }
149 return std::nullopt;
150 }
151
152 template <typename Ch, typename String>
153 std::pair<uint64_t, uint64_t> StringBuffer<Ch, String>::cur_line() {
154 uint64_t line = (currentColumn == 1 && index > 0) ? currentLine - 1 : currentLine;
155 uint64_t col = (currentColumn > 1 ? currentColumn - 1 : 1);
156 return std::make_pair(line, col);
157 }
158
159 template <typename Ch, typename String>
161 return currentFile;
162 }
163
164 template <typename Ch, typename String>
166 const std::string &newFile) {
167 currentLine = newLine;
168 currentColumn = 1;
169 currentFile = newFile;
170 }
171
172 template <typename Ch, typename String>
174 return (pos + index >= buffer_.size());
175 }
176
177 template <typename Ch, typename String>
179 index = pos;
180 currentLine = 1;
181 currentColumn = 1;
182 }
183 } // namespace buffer
184
185 namespace token {
186
187 using types::CharType;
188
194 template <typename Ch, int MAX_SIZE = 256>
195 class TokenMap {
196 public:
204 std::optional<types::CharType> lookup_int8(int8_t c);
205
206 private:
207 std::unordered_map<Ch, types::CharType> token_map;
208 };
209
210 template <typename Ch, int MAX_CHARS>
212 std::size_t i = 0;
213 for (i = 0; i < MAX_CHARS; ++i) {
214 token_map[i] = CharType::TT_NULL;
215 }
216 for (i = 'a'; i <= 'z'; ++i) {
217 token_map[i] = CharType::TT_CHAR;
218 }
219 for (i = 'A'; i <= 'Z'; ++i) {
220 token_map[i] = CharType::TT_CHAR;
221 }
222 for (i = '0'; i <= '9'; ++i) {
223 token_map[i] = CharType::TT_DIGIT;
224 }
225 token_map[' '] = CharType::TT_SPACE;
226 token_map['+'] = CharType::TT_SYMBOL;
227 token_map['-'] = CharType::TT_SYMBOL;
228 token_map['*'] = CharType::TT_SYMBOL;
229 token_map['/'] = CharType::TT_SYMBOL;
230 token_map['%'] = CharType::TT_SYMBOL;
231 token_map['&'] = CharType::TT_SYMBOL;
232 token_map['|'] = CharType::TT_SYMBOL;
233 token_map['^'] = CharType::TT_SYMBOL;
234 token_map['~'] = CharType::TT_SYMBOL;
235 token_map['!'] = CharType::TT_SYMBOL;
236 token_map['='] = CharType::TT_SYMBOL;
237 token_map['<'] = CharType::TT_SYMBOL;
238 token_map['>'] = CharType::TT_SYMBOL;
239 token_map['('] = CharType::TT_SYMBOL;
240 token_map[')'] = CharType::TT_SYMBOL;
241 token_map['['] = CharType::TT_SYMBOL;
242 token_map[']'] = CharType::TT_SYMBOL;
243 token_map['{'] = CharType::TT_SYMBOL;
244 token_map['}'] = CharType::TT_SYMBOL;
245 token_map[';'] = CharType::TT_SYMBOL;
246 token_map[':'] = CharType::TT_SYMBOL;
247 token_map[','] = CharType::TT_SYMBOL;
248 token_map['.'] = CharType::TT_SYMBOL;
249 token_map['?'] = CharType::TT_SYMBOL;
250 token_map['#'] = CharType::TT_SYMBOL;
251 token_map['_'] = CharType::TT_CHAR;
252 token_map['\\'] = CharType::TT_SYMBOL;
253 token_map['\''] = CharType::TT_SINGLE;
254 token_map['\"'] = CharType::TT_STRING;
255 token_map['"'] = CharType::TT_STRING;
256 token_map['@'] = CharType::TT_SYMBOL;
257 token_map['$'] = CharType::TT_SYMBOL;
258 }
259 template <typename Ch, int MAX_CHARS>
260 std::optional<types::CharType> TokenMap<Ch, MAX_CHARS>::lookup_int8(int8_t c) {
261 if (c >= 0 && c < MAX_CHARS) {
262 auto f = token_map.find(c);
263 if (f != token_map.end())
264 return f->second;
265 }
266 return std::nullopt;
267 }
268
274 template <typename Ch = char, typename String = std::basic_string<Ch, std::char_traits<Ch>>>
275 class Token {
276 public:
277 using ch_type = Ch;
278 using string_type = String;
280 Token() : line{1}, col{1} {}
282 Token(const types::TokenType &t) : type{t}, line{1}, col{1} {}
286 Token(Token<Ch, String> &&t) : type{t.type}, value{std::move(t.value)}, line{t.line}, col{t.col}, filename{t.filename} {}
298 void setToken(const types::TokenType &type, const String &value);
300 string_type getTokenValue() const { return value; }
304 void print(std::ostream &out);
306 const std::pair<uint64_t, uint64_t> get_pos() const { return std::make_pair(line, col); }
308 void set_pos(const std::pair<uint64_t, uint64_t> &p);
310 void set_filename(const std::string &filename) { this->filename = filename; }
312 std::string get_filename() const { return this->filename; }
314 uint64_t getLine() const { return line; }
316 uint64_t getCol() const { return col; }
317
318 private:
321 uint64_t line = 1, col = 1;
322 std::string filename;
323 };
324
325 template <typename Ch, typename String>
327 this->type = type;
328 this->value = value;
329 }
330
331 template <typename Ch, typename String>
336 template <typename Ch, typename String>
338 setToken(t.type, t.value);
339 filename = t.filename;
340 return *this;
341 }
342 template <typename Ch, typename String>
344 setToken(t.type, t.value);
345 return *this;
346 }
347
348 template <typename Ch, typename String>
349 void Token<Ch, String>::print(std::ostream &out) {
350 out << value << " -> \t";
352 out << "\n";
353 }
354 template <typename Ch, typename String>
355 void Token<Ch, String>::set_pos(const std::pair<uint64_t, uint64_t> &p) {
356 line = p.first;
357 col = p.second;
358 }
359 } // namespace token
360
361} // namespace scan
362
363#endif
std::basic_string< char, std::char_traits< char > > string_type
std::optional< ch_type > getch()
Consume and return the next character, advancing the position.
bool eof(uint64_t pos=0)
Check if end-of-buffer has been reached.
std::optional< ch_type > backward_step(int num=1)
Move the position backward by num characters.
void process_line_directive(uint64_t newLine, const std::string &newFile)
Process a line directive to update position tracking.
void reset(uint64_t pos=0)
Reset the buffer position.
std::string cur_file() const
Get the current source filename.
std::optional< ch_type > curch()
Return the current character without advancing.
std::optional< ch_type > forward_step(int num=1)
Advance the position by num characters.
StringBuffer(const string_type &buf, const std::string &filename="unknown")
Construct a string buffer.
std::pair< uint64_t, uint64_t > cur_line()
Get the current (line, column) position.
std::optional< ch_type > peekch(int num=1)
Peek ahead by num positions without advancing.
std::optional< ch_type > prevch()
Return the previously consumed character.
TokenMap()
Construct the map with default ASCII character classifications.
std::unordered_map< char, types::CharType > token_map
std::optional< types::CharType > lookup_int8(int8_t c)
Look up the character type for an 8-bit character.
void set_filename(const std::string &filename)
Set the source filename for this token.
uint64_t getLine() const
Get the source line number.
std::string get_filename() const
Get the source filename for this token.
string_type getTokenValue() const
Get the token's text value.
void print(std::ostream &out)
Print the token value and type to a stream.
std::basic_string< char, std::char_traits< char > > string_type
types::TokenType getTokenType() const
Get the token's type classification.
Token(const types::TokenType &t)
Construct a token with a given type.
Token< Ch, String > & operator=(const Token< Ch, String > &t)
Copy assignment.
Token(const Token< Ch, String > &t)
Copy constructor.
uint64_t getCol() const
Get the source column number.
Token()
Default constructor — creates a null token at line 1, col 1.
Token< Ch, String > & operator=(const types::TokenType &type)
Assign a new token type, keeping the current value.
void set_pos(const std::pair< uint64_t, uint64_t > &p)
Set the source position from a (line, column) pair.
const std::pair< uint64_t, uint64_t > get_pos() const
Get the (line, column) source position.
Token< Ch, String > & operator=(Token< Ch, String > &&t)
Move assignment.
Token(Token< Ch, String > &&t)
Move constructor.
void setToken(const types::TokenType &type, const String &value)
Set the token's type and value.
int64_t pos(const char *substr, const char *s)
Definition cstring.c:51
TokenType
Classification of scanned tokens.
Definition types.hpp:16
void print_type_TokenType(std::ostream &out, const TokenType &tt)
Print a TokenType name to a stream.
Definition types.cpp:13
CharType
Classification of individual characters during lexing.
Definition types.hpp:26
Token, character, and operator type enumerations for the scanner.