picceler
Loading...
Searching...
No Matches
lexer.h
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <cstdint>
12#include <fstream>
13#include <ostream>
14#include <string>
15#include <utility>
16#include <vector>
17
18#include "error.h"
19
20namespace picceler {
21
26struct Token {
28 enum class Type : uint8_t {
29 IDENTIFIER, // Represents identifiers (user defined names)
30 NUMBER, // Represents numeric literals (e.g., integers, floats)
31 PLUS, // Represents binary operation '+'
32 MINUS, // Represents binary operation '-'
33 MULTIPLY, // Represents binary operation '*'
34 DIVIDE, // Represents binary operation '/'
35 STRING, // Represents string literals
36 L_PAREN, // Represents the left parenthesis '('
37 R_PAREN, // Represents the right parenthesis ')'
38 L_BRACKET, // Represents the left bracket '['
39 R_BRACKET, // Represents the right bracket ']'
40 L_BRACE, // Represents the left brace '{'
41 R_BRACE, // Represents the right brace '}'
42 COMMA, // Represents the comma ','
43 COLON, // Represents the colon ':'
44 ARROW, // Represents the arrow '->'
45 ASSIGN, // Represents the assignment operator '='
46 EQ, // Represents the assignment operator '=='
47 NE, // Represents the assignment operator '!='
48 LT, // Represents the assignment operator '<'
49 GT, // Represents the assignment operator '>'
50 LE, // Represents the assignment operator '<='
51 GE, // Represents the assignment operator '>='
52 TYPE, // Represents type annotations (e.g., int, float, string)
53 KW_DEF, // Represents the keyword 'def'
54 KW_RETURN, // Represents the keyword 'return'
55 KW_IF, // Represents the keyword 'if'
56 EOF_TOKEN, // Represents the end of file
57 UNKNOWN // Represents unknown tokens
58 };
59
60 Token() : _type(Type::UNKNOWN), _value(""), _location() {}
61
62 Token(Type type, std::string value, Location location) : _type(type), _value(std::move(value)), _location(location) {}
63
64 Token(const Token &other) : _type(other._type), _value(other._value), _location(other._location) {}
65 Token(Token &&other) noexcept : _type(other._type), _value(std::move(other._value)), _location(other._location) {}
66 ~Token() = default;
67 Token &operator=(const Token &other) {
68 if (this != &other) {
69 _type = other._type;
70 _value = other._value;
71 _location = other._location;
72 }
73 return *this;
74 }
75 Token &operator=(Token &&other) noexcept {
76 if (this != &other) {
77 _type = other._type;
78 _value = std::move(other._value);
79 _location = other._location;
80 }
81 return *this;
82 }
83
88 std::string typeToString() const;
89
94 std::string toString() const {
95 return std::format("Token(type: {}, value: '{}', line: {}, column: {})", typeToString(), _value, _location.line(),
96 _location.column());
97 }
98
99 Type type() const { return _type; }
100 const std::string &value() const { return _value; }
101 size_t line() const { return _location.line(); }
102 size_t column() const { return _location.column(); }
103 Location location() const { return _location; }
104 /*
105 * @brief Compares a token to a token type for easy checking in parsing.
106 * @param lhs The token to compare.
107 * @param rhs The token type to compare against.
108 * @return True if the token's type matches the token type, false otherwise.
109 */
110 friend constexpr bool operator==(const Token &lhs, const Token::Type &rhs) { return lhs._type == rhs; }
111
112private:
113 Type _type;
114 std::string _value;
115 Location _location;
116};
117
122class Lexer {
123public:
127 Lexer();
128
133 void setSourceString(std::string_view source);
134
139 Result<void> setSource(const std::string &filepath);
140
146
152
157
163
164private:
169 void resetState();
170
174 bool eof() const;
175
179 char peek() const;
180
184 char get();
185
191
192 bool isIdentifier(char ch) const;
198 bool isSymbol(char ch) const;
199
205 Result<Token::Type> isKeyword(const std::string &value) const;
206
212 Result<Token::Type> isType(const std::string &value) const;
213
219 Result<Token> readIdentifierOrKeywordOrType(std::pair<size_t, size_t> start);
220
226 Result<Token> readNumber(std::pair<size_t, size_t> start);
227
233 Result<Token> readString(std::pair<size_t, size_t> start);
234
240 Result<Token> readSymbol(std::pair<size_t, size_t> start);
241
242private:
243 std::string unescapeString(std::string &&string) const;
244
245private:
246 std::ifstream _file;
247 std::string _buffer;
248 size_t _position;
249 size_t _line;
250 size_t _column;
251};
252
259std::ostream &operator<<(std::ostream &os, const Token &token);
260
261} // namespace picceler
Lexer()
Constructs a Lexer.
Definition lexer.cpp:73
Result< Token > peekToken()
Returns the next token without advancing the input.
Definition lexer.cpp:137
Result< Token > nextToken()
Returns the next token from the input.
Definition lexer.cpp:101
void skipWhitespaceAndComment()
Skips whitespace characters and comment lines in the input.
Definition lexer.cpp:148
Result< std::vector< Token > > getTokens()
Tokenizes the entire input.
Definition lexer.cpp:159
Result< void > setSource(const std::string &filepath)
Sets the source file for the lexer.
Definition lexer.cpp:85
void setSourceString(std::string_view source)
Sets the source string for the lexer.
Definition lexer.cpp:80
Struct to hold location information.
Definition error.h:10
Definition ast.h:11
std::expected< T, CompileError > Result
A type alias for the result of a compilation operation.
Definition error.h:59
std::ostream & operator<<(std::ostream &os, const Token &token)
Outputs a token to the given output stream.
Definition lexer.cpp:385
Represents a token produced by the lexer.
Definition lexer.h:26
std::string typeToString() const
Converts the token type to a string representation.
Definition lexer.cpp:10
Token & operator=(const Token &other)
Definition lexer.h:67
friend constexpr bool operator==(const Token &lhs, const Token::Type &rhs)
Definition lexer.h:110
const std::string & value() const
Definition lexer.h:100
Token(Token &&other) noexcept
Definition lexer.h:65
std::string toString() const
Converts the token to a string representation.
Definition lexer.h:94
size_t line() const
Definition lexer.h:101
Type type() const
Definition lexer.h:99
~Token()=default
Token(const Token &other)
Definition lexer.h:64
Location location() const
Definition lexer.h:103
Token(Type type, std::string value, Location location)
Definition lexer.h:62
size_t column() const
Definition lexer.h:102
Type
The type of the token.
Definition lexer.h:28
@ L_PAREN
Definition lexer.h:36
@ MULTIPLY
Definition lexer.h:33
@ L_BRACE
Definition lexer.h:40
@ R_BRACE
Definition lexer.h:41
@ DIVIDE
Definition lexer.h:34
@ EQ
Definition lexer.h:46
@ NUMBER
Definition lexer.h:30
@ KW_RETURN
Definition lexer.h:54
@ KW_DEF
Definition lexer.h:53
@ R_BRACKET
Definition lexer.h:39
@ COMMA
Definition lexer.h:42
@ R_PAREN
Definition lexer.h:37
@ STRING
Definition lexer.h:35
@ UNKNOWN
Definition lexer.h:57
@ IDENTIFIER
Definition lexer.h:29
@ EOF_TOKEN
Definition lexer.h:56
@ PLUS
Definition lexer.h:31
@ TYPE
Definition lexer.h:52
@ L_BRACKET
Definition lexer.h:38
@ LT
Definition lexer.h:48
@ ARROW
Definition lexer.h:44
@ GT
Definition lexer.h:49
@ LE
Definition lexer.h:50
@ NE
Definition lexer.h:47
@ COLON
Definition lexer.h:43
@ GE
Definition lexer.h:51
@ KW_IF
Definition lexer.h:55
@ MINUS
Definition lexer.h:32
@ ASSIGN
Definition lexer.h:45
Token()
Definition lexer.h:60
Token & operator=(Token &&other) noexcept
Definition lexer.h:75