Yume
parser.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "ast/ast.hpp"
4#include "atom.hpp"
8#include "token.hpp"
9#include "util.hpp"
10#include <array>
11#include <cctype>
12#include <cstddef>
13#include <memory>
14#include <optional>
15#include <span>
16#include <stdexcept>
17#include <string>
18#include <string_view>
19#include <utility>
20#include <vector>
21
22namespace yume::ast {
23using VectorTokenIterator = vector<Token>::iterator;
24
25/// An iterator-like holding `Token`s, used when parsing.
26/**
27 * Every parse method usually takes this as the first parameter. This is its own struct as it actually holds two
28 * iterators, where one is the end. This is to provide safe indexing (avoiding going past the end) without having to
29 * pass the end iterator around as a separate parameter.
30 */
32 VectorTokenIterator m_iterator;
34
35public:
37 : m_iterator{iterator}, m_end{end} {}
38
39 /// Check if the iterator is at the end and no more `Token`s could possibly be read.
40 [[nodiscard]] auto at_end() const noexcept -> bool { return m_iterator >= m_end; }
41 [[nodiscard]] auto operator->() const -> Token* {
42 if (at_end())
43 throw std::runtime_error("Can't dereference at end");
44 return m_iterator.operator->();
45 }
46 [[nodiscard]] auto operator*() const -> Token {
47 if (at_end())
48 throw std::runtime_error("Can't dereference at end");
49 return m_iterator.operator*();
50 }
51 [[nodiscard]] auto operator+(int i) const noexcept -> TokenIterator { return TokenIterator{m_iterator + i, m_end}; }
52 [[nodiscard]] auto operator-(int i) const noexcept -> TokenIterator { return TokenIterator{m_iterator - i, m_end}; }
54 if (at_end())
55 throw std::runtime_error("Can't increment past end");
56
57 ++m_iterator;
58 return *this;
59 }
61 if (at_end())
62 throw std::runtime_error("Can't increment past end");
63
64 return TokenIterator{m_iterator++, m_end};
65 }
66 /// Returns the underlying iterator. This shouldn't really be needed but I'm too lazy to properly model an iterator.
67 [[nodiscard]] auto begin() const -> VectorTokenIterator { return m_iterator; }
68
69 [[nodiscard]] auto end() const -> VectorTokenIterator { return m_end; }
70};
71} // namespace yume::ast
72
73namespace yume::ast::parser {
74using TokenAtom = std::pair<Token::Type, Atom>;
75
76static constexpr auto Word = Token::Type::Word;
77static constexpr auto Symbol = Token::Type::Symbol;
78
79static const TokenAtom KWD_IF = {Word, "if"_a};
80static const TokenAtom KWD_IS = {Word, "is"_a};
81static const TokenAtom KWD_DEF = {Word, "def"_a};
82static const TokenAtom KWD_END = {Word, "end"_a};
83static const TokenAtom KWD_LET = {Word, "let"_a};
84static const TokenAtom KWD_PTR = {Word, "ptr"_a};
85static const TokenAtom KWD_MUT = {Word, "mut"_a};
86static const TokenAtom KWD_REF = {Word, "ref"_a};
87static const TokenAtom KWD_NEW = {Word, "new"_a};
88static const TokenAtom KWD_ELSE = {Word, "else"_a};
89static const TokenAtom KWD_SELF_ITEM = {Word, "self"_a};
90static const TokenAtom KWD_SELF_TYPE = {Word, "Self"_a};
91static const TokenAtom KWD_THEN = {Word, "then"_a};
92static const TokenAtom KWD_TRUE = {Word, "true"_a};
93static const TokenAtom KWD_TYPE = {Word, "type"_a};
94static const TokenAtom KWD_FALSE = {Word, "false"_a};
95static const TokenAtom KWD_WHILE = {Word, "while"_a};
96static const TokenAtom KWD_CONST = {Word, "const"_a};
97static const TokenAtom KWD_STRUCT = {Word, "struct"_a};
98static const TokenAtom KWD_RETURN = {Word, "return"_a};
99static const TokenAtom KWD_ABSTRACT = {Word, "abstract"_a};
100static const TokenAtom KWD_INTERFACE = {Word, "interface"_a};
101
102static const TokenAtom KWD_EXTERN = {Word, "__extern__"_a};
103static const TokenAtom KWD_VARARGS = {Word, "__varargs__"_a};
104static const TokenAtom KWD_PRIMITIVE = {Word, "__primitive__"_a};
105
106static const TokenAtom SYM_COMMA = {Symbol, ","_a};
107static const TokenAtom SYM_DOT = {Symbol, "."_a};
108static const TokenAtom SYM_EQ = {Symbol, "="_a};
109static const TokenAtom SYM_AT = {Symbol, "@"_a};
110static const TokenAtom SYM_LPAREN = {Symbol, "("_a};
111static const TokenAtom SYM_RPAREN = {Symbol, ")"_a};
112static const TokenAtom SYM_LBRACKET = {Symbol, "["_a};
113static const TokenAtom SYM_RBRACKET = {Symbol, "]"_a};
114static const TokenAtom SYM_LBRACE = {Symbol, "{"_a};
115static const TokenAtom SYM_RBRACE = {Symbol, "}"_a};
116static const TokenAtom SYM_EQ_EQ = {Symbol, "=="_a};
117static const TokenAtom SYM_NEQ = {Symbol, "!="_a};
118static const TokenAtom SYM_AND = {Symbol, "&"_a};
119static const TokenAtom SYM_LT = {Symbol, "<"_a};
120static const TokenAtom SYM_GT = {Symbol, ">"_a};
121static const TokenAtom SYM_PLUS = {Symbol, "+"_a};
122static const TokenAtom SYM_MINUS = {Symbol, "-"_a};
123static const TokenAtom SYM_PERCENT = {Symbol, "%"_a};
124static const TokenAtom SYM_SLASH_SLASH = {Symbol, "//"_a};
125static const TokenAtom SYM_STAR = {Symbol, "*"_a};
126static const TokenAtom SYM_BANG = {Symbol, "!"_a};
127static const TokenAtom SYM_COLON = {Symbol, ":"_a};
128static const TokenAtom SYM_COLON_COLON = {Symbol, "::"_a};
129static const TokenAtom SYM_OR_OR = {Symbol, "||"_a};
130static const TokenAtom SYM_AND_AND = {Symbol, "&&"_a};
131static const TokenAtom SYM_ARROW = {Symbol, "->"_a};
132static const TokenAtom SYM_DOLLAR = {Symbol, "$"_a};
133
135 span<Token> m_span;
136
137public:
138 constexpr TokenRange(auto&& begin, int end) : m_span{begin.base(), static_cast<size_t>(end)} {}
139 constexpr TokenRange(auto&& begin, auto&& end) : m_span{begin.base(), end.base()} {}
140
141 /* implicit */ operator span<Token>() const { return m_span; }
142};
143
144struct Parser {
147
148 [[nodiscard]] auto clamped_iterator(const TokenIterator& iter) const -> TokenIterator {
149 if (iter.at_end())
150 return {tokens.end() - 1, tokens.end()};
151 return iter;
152 }
153
154 [[nodiscard]] auto emit_note(int offset = 0, diagnostic::Severity severity = diagnostic::Severity::Note) const
156 return notes.emit(clamped_iterator(tokens + offset)->loc, severity);
157 };
158
159 [[nodiscard]] auto emit_fatal_and_terminate(int offset = 0) const noexcept(false) -> diagnostic::Note {
161 };
162
163 template <typename T, typename U> static auto ts(T&& begin, U&& end) -> span<Token> {
164 return TokenRange{std::forward<T>(begin), std::forward<U>(end)};
165 }
166
167 [[nodiscard]] auto ts(const VectorTokenIterator& entry) const -> span<Token> {
168 return span<Token>{entry.base(), tokens.begin().base()};
169 }
170
171 template <typename T, typename... Args> auto ast_ptr(const VectorTokenIterator& entry, Args&&... args) {
172 return std::make_unique<T>(span<Token>{entry.base(), tokens.begin().base()}, std::forward<Args>(args)...);
173 }
174
175 template <typename T, typename... Args> auto ast_ptr(TokenRange&& range, Args&&... args) {
176 return std::make_unique<T>(static_cast<span<Token>>(range), std::forward<Args>(args)...);
177 }
178
179 template <typename T, typename... Args> auto make_ast(const VectorTokenIterator& entry, Args&&... args) {
180 return T(span<Token>{entry.base(), tokens.begin().base()}, std::forward<Args>(args)...);
181 }
182
183 struct FnArg {
184 unique_ptr<TypeName> type_name;
186 };
187
188 constexpr static auto Symbol = Token::Type::Symbol;
189 constexpr static auto Word = Token::Type::Word;
190 constexpr static auto Separator = Token::Type::Separator;
191 constexpr static auto Number = Token::Type::Number;
192
193 [[nodiscard]] auto make_guard(const string& message) const -> ParserStackTrace { return {message, *tokens}; }
194
195 static auto operators() {
196 const static array OPERATORS = {
197 vector{SYM_AND},
198 vector{SYM_EQ_EQ, SYM_NEQ, SYM_GT, SYM_LT},
199 vector{SYM_PLUS, SYM_MINUS},
201 };
202 return OPERATORS;
203 };
204
205 static auto unary_operators() {
206 const static vector UNARY_OPERATORS = {
207 SYM_MINUS,
208 SYM_PLUS,
209 SYM_BANG,
210 };
211 return UNARY_OPERATORS;
212 };
213
214 static auto to_string(Token token) -> string;
215
216 /// Ignore any `Separator` tokens if any are present.
217 /// \returns true if a separator was encountered (and consumed)
219
220 /// If the next token doesn't have the type, `token_type`, throw a runtime exception.
221 void expect(Token::Type token_type, source_location location = source_location::current()) const;
222
223 /// Consume all subsequent `Separator` tokens. Throws if none were found.
225
226 /// Consume a token of the given type and payload. Throws if it wasn't encountered.
227 void consume(TokenAtom token_atom, source_location location = source_location::current());
228
229 /// Attempt to consume a token of the given type and payload. Returns false if it wasn't encountered.
230 auto try_consume(TokenAtom token_atom, source_location location = source_location::current()) -> bool;
231
232 /// Check if the token ahead by `ahead` is of the given type and payload.
233 [[nodiscard]] auto try_peek(int ahead, TokenAtom token_atom,
234 source_location location = source_location::current()) const -> bool;
235
236 /// Check if the token ahead by `ahead` is of type `token_type`.
237 [[nodiscard]] auto try_peek(int ahead, Token::Type token_type,
238 source_location location = source_location::current()) const -> bool;
239
240 /// Consume tokens until a token of the given type and payload is encountered.
241 /// `action` (a no-arg function) is called every time. Between each call, a comma is expected.
242 void consume_with_commas_until(TokenAtom token_atom, std::invocable auto action,
243 const source_location location = source_location::current()) {
244 int i = 0;
245 while (!try_consume(token_atom, location)) {
246 if (i++ > 0)
247 consume(SYM_COMMA, location);
248 action();
249 }
250 }
251
252 /// Consume tokens until a token of the given type and payload is encountered.
253 /// `action` (a no-arg member function) is called every time and its result is appended to `vec`. Between each call, a
254 /// comma is expected.
255 template <typename T, std::convertible_to<T> U>
256 void collect_with_commas_until(TokenAtom token_atom, U (Parser::*action)(), vector<T>& vec,
257 const source_location location = source_location::current()) {
258 int i = 0;
259 while (!try_consume(token_atom, location)) {
260 if (i++ > 0)
261 consume(SYM_COMMA, location);
262 vec.emplace_back((this->*action)());
263 }
264 }
265
266 /// Consume tokens until a token of the given type and payload is encountered.
267 /// `action` (a no-arg member function) is called every time. Between each call, a comma is expected.
268 /// Returns a vector of all the results of calling `action`.
269 template <typename T, std::convertible_to<T> U>
270 [[nodiscard]] auto collect_with_commas_until(TokenAtom token_atom, U (Parser::*action)(),
271 const source_location location = source_location::current())
272 -> vector<T> {
273 vector<T> vec{};
274 int i = 0;
275 while (!try_consume(token_atom, location)) {
276 if (i++ > 0)
277 consume(SYM_COMMA, location);
278 vec.emplace_back((this->*action)());
279 }
280 return vec;
281 }
282
283 /// Return the next token and increment the iterator.
284 auto next([[maybe_unused]] source_location location = source_location::current()) -> Token;
285
286 /// Returns the payload of the next token and increment the iterator.
287 /// \throws if the next token has no payload
288 auto assert_payload_next([[maybe_unused]] source_location location = source_location::current()) -> Atom;
289
290 /// Return the payload of the next token. Throws if the next token isn't a `Word`.
291 auto consume_word(source_location location = source_location::current()) -> string;
292
293 /// Check if the string begins with a capital letter. Used for types, as all types must be capitalized.
294 static auto is_uword(string_view word) -> bool { return isupper(word.front()) != 0; }
295
296 /// Check if the ahead by `ahead` is a capitalized word.
297 [[nodiscard]] auto try_peek_uword(int ahead, source_location location = source_location::current()) const -> bool;
298
299 auto parse_stmt(bool require_sep = true) -> unique_ptr<Stmt>;
300 auto parse_expr() -> unique_ptr<Expr>;
301
302 auto parse_fn_arg() -> FnArg;
303 auto parse_generic_type_params() -> vector<GenericParam>;
304
305 auto try_parse_function_type() -> optional<unique_ptr<FunctionType>>;
306 auto try_parse_type() -> optional<unique_ptr<Type>>;
307 auto parse_type(bool implicit_self = false) -> unique_ptr<Type>;
308
309 auto parse_type_name() -> unique_ptr<TypeName>;
310
311 auto parse_fn_name() -> string;
312
313 auto parse_struct_decl() -> unique_ptr<StructDecl>;
314
315 auto parse_fn_or_ctor_decl() -> unique_ptr<Stmt>;
316 auto parse_fn_decl() -> unique_ptr<FnDecl>;
317 auto parse_ctor_decl() -> unique_ptr<CtorDecl>;
318
319 auto parse_var_decl() -> unique_ptr<VarDecl>;
320
321 auto parse_const_decl() -> unique_ptr<ConstDecl>;
322
323 auto parse_while_stmt() -> unique_ptr<WhileStmt>;
324
325 auto parse_return_stmt() -> unique_ptr<ReturnStmt>;
326
327 auto parse_if_stmt() -> unique_ptr<IfStmt>;
328
329 auto parse_number_expr() -> unique_ptr<NumberExpr>;
330
331 auto parse_string_expr() -> unique_ptr<StringExpr>;
332
333 auto parse_char_expr() -> unique_ptr<CharExpr>;
334
335 auto parse_primary() -> unique_ptr<Expr>;
336
337 auto parse_receiver(unique_ptr<Expr> receiver, VectorTokenIterator receiver_entry) -> unique_ptr<Expr>;
338
339 auto parse_receiver() -> unique_ptr<Expr>;
340
341 auto parse_unary() -> unique_ptr<Expr>;
342
343 auto parse_lambda() -> unique_ptr<LambdaExpr>;
344
345 auto parse_logical_or() -> unique_ptr<Expr>;
346 auto parse_logical_and() -> unique_ptr<Expr>;
347
348 template <size_t N = 0> auto parse_operator() -> unique_ptr<Expr> {
349 auto entry = tokens.begin();
350 const auto ops = operators();
351 if constexpr (N == ops.size()) {
352 return parse_unary();
353 } else {
354 auto left = parse_operator<N + 1>();
355 while (true) {
356 auto found_operator = false;
357 for (const auto& op : ops[N]) {
358 if (try_consume(op)) {
359 auto right = parse_operator<N + 1>();
360 auto args = vector<AnyExpr>{};
361 args.emplace_back(move(left));
362 args.emplace_back(move(right));
363 left = ast_ptr<CallExpr>(entry, string(std::get<Atom>(op)), std::nullopt, move(args));
364 found_operator = true;
365 break;
366 }
367 }
368 if (!found_operator)
369 break;
370 }
371 return left;
372 }
373 }
374};
375} // namespace yume::ast::parser
Atoms represent strings in a string pool.
Definition: atom.hpp:12
Expressions have an associated value and type.
Definition: ast.hpp:438
Statements make up most things in source code.
Definition: ast.hpp:297
An iterator-like holding Tokens, used when parsing.
Definition: parser.hpp:31
auto operator->() const -> Token *
Definition: parser.hpp:41
auto end() const -> VectorTokenIterator
Definition: parser.hpp:69
auto operator++() -> TokenIterator &
Definition: parser.hpp:53
auto operator*() const -> Token
Definition: parser.hpp:46
TokenIterator(const VectorTokenIterator &iterator, const VectorTokenIterator &end)
Definition: parser.hpp:36
auto operator+(int i) const noexcept -> TokenIterator
Definition: parser.hpp:51
auto begin() const -> VectorTokenIterator
Returns the underlying iterator. This shouldn't really be needed but I'm too lazy to properly model a...
Definition: parser.hpp:67
auto operator++(int) -> TokenIterator
Definition: parser.hpp:60
auto operator-(int i) const noexcept -> TokenIterator
Definition: parser.hpp:52
auto at_end() const noexcept -> bool
Check if the iterator is at the end and no more Tokens could possibly be read.
Definition: parser.hpp:40
A type annotation. This (ast::Type) is distinct from the actual type of a value (ty::Type).
Definition: ast.hpp:312
constexpr TokenRange(auto &&begin, int end)
Definition: parser.hpp:138
constexpr TokenRange(auto &&begin, auto &&end)
Definition: parser.hpp:139
string_view end
Definition: errors.cpp:42
static const TokenAtom KWD_TYPE
Definition: parser.hpp:93
static const TokenAtom KWD_DEF
Definition: parser.hpp:81
static const TokenAtom SYM_RBRACKET
Definition: parser.hpp:113
static const TokenAtom SYM_DOLLAR
Definition: parser.hpp:132
static const TokenAtom KWD_SELF_ITEM
Definition: parser.hpp:89
static const TokenAtom KWD_IF
Definition: parser.hpp:79
static const TokenAtom SYM_COMMA
Definition: parser.hpp:106
static const TokenAtom SYM_PLUS
Definition: parser.hpp:121
static const TokenAtom SYM_SLASH_SLASH
Definition: parser.hpp:124
static const TokenAtom SYM_COLON
Definition: parser.hpp:127
static const TokenAtom KWD_INTERFACE
Definition: parser.hpp:100
static const TokenAtom SYM_PERCENT
Definition: parser.hpp:123
static const TokenAtom KWD_LET
Definition: parser.hpp:83
static const TokenAtom KWD_STRUCT
Definition: parser.hpp:97
static const TokenAtom SYM_STAR
Definition: parser.hpp:125
static const TokenAtom KWD_VARARGS
Definition: parser.hpp:103
static const TokenAtom SYM_LBRACE
Definition: parser.hpp:114
static const TokenAtom SYM_GT
Definition: parser.hpp:120
static const TokenAtom KWD_PRIMITIVE
Definition: parser.hpp:104
static const TokenAtom SYM_AT
Definition: parser.hpp:109
static constexpr auto Word
Definition: parser.hpp:76
static const TokenAtom SYM_NEQ
Definition: parser.hpp:117
static const TokenAtom KWD_THEN
Definition: parser.hpp:91
static const TokenAtom SYM_RPAREN
Definition: parser.hpp:111
static const TokenAtom KWD_CONST
Definition: parser.hpp:96
static const TokenAtom SYM_DOT
Definition: parser.hpp:107
static const TokenAtom SYM_LPAREN
Definition: parser.hpp:110
static const TokenAtom SYM_EQ_EQ
Definition: parser.hpp:116
static const TokenAtom SYM_LT
Definition: parser.hpp:119
static const TokenAtom KWD_PTR
Definition: parser.hpp:84
static const TokenAtom KWD_NEW
Definition: parser.hpp:87
static const TokenAtom SYM_COLON_COLON
Definition: parser.hpp:128
static const TokenAtom SYM_EQ
Definition: parser.hpp:108
static const TokenAtom SYM_MINUS
Definition: parser.hpp:122
static const TokenAtom KWD_SELF_TYPE
Definition: parser.hpp:90
static const TokenAtom KWD_WHILE
Definition: parser.hpp:95
static const TokenAtom KWD_TRUE
Definition: parser.hpp:92
static const TokenAtom SYM_BANG
Definition: parser.hpp:126
static const TokenAtom SYM_ARROW
Definition: parser.hpp:131
static const TokenAtom KWD_ABSTRACT
Definition: parser.hpp:99
static const TokenAtom KWD_END
Definition: parser.hpp:82
static const TokenAtom SYM_AND
Definition: parser.hpp:118
static const TokenAtom KWD_IS
Definition: parser.hpp:80
static const TokenAtom KWD_EXTERN
Definition: parser.hpp:102
static const TokenAtom SYM_AND_AND
Definition: parser.hpp:130
static const TokenAtom KWD_ELSE
Definition: parser.hpp:88
static const TokenAtom KWD_RETURN
Definition: parser.hpp:98
static const TokenAtom KWD_MUT
Definition: parser.hpp:85
static const TokenAtom SYM_RBRACE
Definition: parser.hpp:115
static const TokenAtom KWD_REF
Definition: parser.hpp:86
static const TokenAtom KWD_FALSE
Definition: parser.hpp:94
static const TokenAtom SYM_LBRACKET
Definition: parser.hpp:112
std::pair< Token::Type, Atom > TokenAtom
Definition: parser.hpp:74
static const TokenAtom SYM_OR_OR
Definition: parser.hpp:129
static constexpr auto Symbol
Definition: parser.hpp:77
Definition: ast.cpp:8
vector< Token >::iterator VectorTokenIterator
Definition: parser.hpp:23
A categorized token in source code, created by the tokenizer. These tokens are consumed by the lexer.
Definition: token.hpp:80
@ Symbol
Special characters, such as those representing operators.
@ Separator
A newline or a semicolon ;
@ Word
Any form of keyword or identifier, essentially the "default" token type.
@ Number
A number literal.
Char literals.
Definition: ast.hpp:495
A declaration of a constant (const).
Definition: ast.hpp:888
A declaration of a custom constructor (def :new).
Definition: ast.hpp:832
A declaration of a function (def).
Definition: ast.hpp:762
A function type i.e. ->(Foo,Bar)Baz.
Definition: ast.hpp:380
A generic, compile-time argument to a struct or function definition, comparable to C++ template param...
Definition: ast.hpp:422
An if statement (if), with one or more IfClauses, and optionally an else clause.
Definition: ast.hpp:930
A local definition of an anonymous function.
Definition: ast.hpp:729
Number literals.
Definition: ast.hpp:482
Return from a function body.
Definition: ast.hpp:944
String literals.
Definition: ast.hpp:521
A declaration of a struct (struct) or an interface (interface).
Definition: ast.hpp:847
A pair of a Type and an identifier, i.e. a parameter name.
Definition: ast.hpp:396
A declaration of a local variable (let).
Definition: ast.hpp:872
A while loop (while).
Definition: ast.hpp:904
unique_ptr< TypeName > type_name
Definition: parser.hpp:184
static auto operators()
Definition: parser.hpp:195
auto ast_ptr(const VectorTokenIterator &entry, Args &&... args)
Definition: parser.hpp:171
auto parse_generic_type_params() -> vector< GenericParam >
Definition: parser.cpp:444
static auto is_uword(string_view word) -> bool
Check if the string begins with a capital letter. Used for types, as all types must be capitalized.
Definition: parser.hpp:294
auto parse_string_expr() -> unique_ptr< StringExpr >
Definition: parser.cpp:704
void expect(Token::Type token_type, source_location location=source_location::current()) const
If the next token doesn't have the type, token_type, throw a runtime exception.
Definition: parser.cpp:23
auto consume_word(source_location location=source_location::current()) -> string
Return the payload of the next token. Throws if the next token isn't a Word.
Definition: parser.cpp:136
auto parse_number_expr() -> unique_ptr< NumberExpr >
Definition: parser.cpp:692
void consume(TokenAtom token_atom, source_location location=source_location::current())
Consume a token of the given type and payload. Throws if it wasn't encountered.
Definition: parser.cpp:45
auto make_guard(const string &message) const -> ParserStackTrace
Definition: parser.hpp:193
auto parse_logical_and() -> unique_ptr< Expr >
Definition: parser.cpp:342
auto parse_receiver() -> unique_ptr< Expr >
Definition: parser.cpp:890
auto try_parse_function_type() -> optional< unique_ptr< FunctionType > >
Definition: parser.cpp:182
static auto unary_operators()
Definition: parser.hpp:205
TokenIterator & tokens
Definition: parser.hpp:145
auto emit_fatal_and_terminate(int offset=0) const noexcept(false) -> diagnostic::Note
Definition: parser.hpp:159
auto parse_fn_or_ctor_decl() -> unique_ptr< Stmt >
Definition: parser.cpp:464
auto try_parse_type() -> optional< unique_ptr< Type > >
Definition: parser.cpp:264
static auto to_string(Token token) -> string
Definition: parser.cpp:39
auto parse_unary() -> unique_ptr< Expr >
Definition: parser.cpp:898
auto try_consume(TokenAtom token_atom, source_location location=source_location::current()) -> bool
Attempt to consume a token of the given type and payload. Returns false if it wasn't encountered.
Definition: parser.cpp:69
auto parse_if_stmt() -> unique_ptr< IfStmt >
Definition: parser.cpp:638
auto parse_struct_decl() -> unique_ptr< StructDecl >
Definition: parser.cpp:389
auto next(source_location location=source_location::current()) -> Token
Return the next token and increment the iterator.
Definition: parser.cpp:116
auto parse_while_stmt() -> unique_ptr< WhileStmt >
Definition: parser.cpp:606
auto emit_note(int offset=0, diagnostic::Severity severity=diagnostic::Severity::Note) const -> diagnostic::Note
Definition: parser.hpp:154
static constexpr auto Separator
Definition: parser.hpp:190
auto ast_ptr(TokenRange &&range, Args &&... args)
Definition: parser.hpp:175
auto ts(const VectorTokenIterator &entry) const -> span< Token >
Definition: parser.hpp:167
auto parse_var_decl() -> unique_ptr< VarDecl >
Definition: parser.cpp:578
auto assert_payload_next(source_location location=source_location::current()) -> Atom
Returns the payload of the next token and increment the iterator.
Definition: parser.cpp:124
void consume_with_commas_until(TokenAtom token_atom, std::invocable auto action, const source_location location=source_location::current())
Consume tokens until a token of the given type and payload is encountered. action (a no-arg function)...
Definition: parser.hpp:242
auto parse_operator() -> unique_ptr< Expr >
Definition: parser.hpp:348
auto parse_fn_arg() -> FnArg
Definition: parser.cpp:427
static constexpr auto Number
Definition: parser.hpp:191
auto collect_with_commas_until(TokenAtom token_atom, U(Parser::*action)(), const source_location location=source_location::current()) -> vector< T >
Consume tokens until a token of the given type and payload is encountered. action (a no-arg member fu...
Definition: parser.hpp:270
auto parse_type_name() -> unique_ptr< TypeName >
Definition: parser.cpp:321
auto try_peek(int ahead, TokenAtom token_atom, source_location location=source_location::current()) const -> bool
Check if the token ahead by ahead is of the given type and payload.
Definition: parser.cpp:82
diagnostic::NotesHolder & notes
Definition: parser.hpp:146
auto parse_stmt(bool require_sep=true) -> unique_ptr< Stmt >
Definition: parser.cpp:157
auto parse_fn_name() -> string
Definition: parser.cpp:354
void require_separator(source_location location=source_location::current())
Consume all subsequent Separator tokens. Throws if none were found.
Definition: parser.cpp:33
auto clamped_iterator(const TokenIterator &iter) const -> TokenIterator
Definition: parser.hpp:148
auto parse_const_decl() -> unique_ptr< ConstDecl >
Definition: parser.cpp:592
auto parse_lambda() -> unique_ptr< LambdaExpr >
Definition: parser.cpp:850
void collect_with_commas_until(TokenAtom token_atom, U(Parser::*action)(), vector< T > &vec, const source_location location=source_location::current())
Consume tokens until a token of the given type and payload is encountered. action (a no-arg member fu...
Definition: parser.hpp:256
auto ignore_separator(source_location location=source_location::current()) -> bool
Ignore any Separator tokens if any are present.
Definition: parser.cpp:11
auto parse_expr() -> unique_ptr< Expr >
Definition: parser.cpp:352
auto make_ast(const VectorTokenIterator &entry, Args &&... args)
Definition: parser.hpp:179
auto parse_type(bool implicit_self=false) -> unique_ptr< Type >
Definition: parser.cpp:210
auto parse_ctor_decl() -> unique_ptr< CtorDecl >
Definition: parser.cpp:548
static auto ts(T &&begin, U &&end) -> span< Token >
Definition: parser.hpp:163
static constexpr auto Word
Definition: parser.hpp:189
auto parse_fn_decl() -> unique_ptr< FnDecl >
Definition: parser.cpp:470
auto parse_logical_or() -> unique_ptr< Expr >
Definition: parser.cpp:332
auto parse_primary() -> unique_ptr< Expr >
Definition: parser.cpp:722
auto parse_return_stmt() -> unique_ptr< ReturnStmt >
Definition: parser.cpp:626
auto try_peek_uword(int ahead, source_location location=source_location::current()) const -> bool
Check if the ahead by ahead is a capitalized word.
Definition: parser.cpp:146
static constexpr auto Symbol
Definition: parser.hpp:188
auto parse_char_expr() -> unique_ptr< CharExpr >
Definition: parser.cpp:713
auto emit(Loc location, Severity severity=Severity::Note) -> Note
Definition: notes.hpp:55
static constexpr auto current()