7#include <llvm/Support/ErrorHandling.h>
8#include <llvm/Support/raw_ostream.h>
12 bool found_separator =
false;
13 while (!tokens.at_end() && tokens->type == Separator) {
14#ifdef YUME_SPEW_CONSUMED_TOKENS
15 errs() <<
"consumed " << *tokens <<
" at " <<
at(location) <<
"\n";
18 found_separator =
true;
20 return found_separator;
27 if (
tokens->type != token_type) {
41 llvm::raw_string_ostream(str) << token;
46 auto [token_type, payload] = token_atom;
50 <<
" for payload " + string(payload) <<
", got the end of the file at " <<
at(location);
53 if (
tokens->type != token_type) {
57 if (
tokens->payload != payload) {
59 <<
" at " <<
at(location);
62#ifdef YUME_SPEW_CONSUMED_TOKENS
63 errs() <<
"consume: " << *
tokens <<
" at " <<
at(location) <<
"\n";
70 auto [token_type, payload] = token_atom;
71 if (tokens.at_end() || tokens->type != token_type || tokens->payload != payload)
74#ifdef YUME_SPEW_CONSUMED_TOKENS
75 errs() <<
"try_consume: " << *tokens <<
" at " <<
at(location) <<
"\n";
83 auto [token_type, payload] = token_atom;
87 auto token = tokens + ahead;
91#ifdef YUME_SPEW_CONSUMED_TOKENS
92 errs() <<
"try_peek ahead by " << ahead <<
": expected " <<
Token::type_name(token_type) <<
" " << string(payload)
93 <<
", got " << *token <<
" at " <<
at(location) <<
"\n";
96 return (token->type == token_type) && (token->payload == payload);
104 auto token = tokens + ahead;
108#ifdef YUME_SPEW_CONSUMED_TOKENS
109 errs() <<
"try_peek ahead by " << ahead <<
": expected " <<
Token::type_name(token_type) <<
", got " << *token
110 <<
" at " <<
at(location) <<
"\n";
113 return token->type == token_type;
117 auto tok = *tokens++;
118#ifdef YUME_SPEW_CONSUMED_TOKENS
119 errs() <<
"next: " << tok <<
" at " <<
at(location) <<
"\n";
125 auto payload = tokens->payload;
127 emit_fatal_and_terminate() <<
"Expected a payload, but wasn't found: " << to_string(*tokens) <<
" at "
129 llvm_unreachable(
"Fatal error should have terminated by now");
133 return payload.value();
139 emit_fatal_and_terminate() <<
"Expected word, got the end of the file";
140 if (tokens->type !=
Word)
141 emit_fatal_and_terminate() <<
"Expected word, got " << to_string(*tokens) <<
" at " <<
at(location);
143 return string(assert_payload_next());
147 auto token = tokens + ahead;
149#ifdef YUME_SPEW_CONSUMED_TOKENS
150 errs() <<
"try_peek ahead by " << ahead <<
": expected uword, got " << *token <<
" at " <<
at(location) <<
"\n";
153 auto payload = token->payload;
154 return token->type ==
Word && payload.has_value() && is_uword(payload.value());
161 stat = parse_fn_or_ctor_decl();
163 stat = parse_struct_decl();
164 else if (tokens->is_a(
KWD_LET))
165 stat = parse_var_decl();
167 stat = parse_const_decl();
169 stat = parse_while_stmt();
170 else if (tokens->is_a(
KWD_IF))
171 stat = parse_if_stmt();
173 stat = parse_return_stmt();
183 auto entry = tokens.begin();
184 auto result = [&]() -> optional<unique_ptr<FunctionType>> {
186 auto args = vector<AnyType>{};
193 auto t = try_parse_type();
196 args.emplace_back(move(*t));
198 auto fn_ptr = try_consume(
KWD_PTR);
201 return ast_ptr<FunctionType>(entry, move(ret), move(args), fn_ptr);
205 if (!result.has_value())
206 tokens = {entry, tokens.end()};
211 if (!implicit_self) {
212 if (
auto maybe_fn_type = try_parse_function_type(); maybe_fn_type.has_value())
213 return move(*maybe_fn_type);
216 auto entry = tokens.begin();
219 return ast_ptr<SelfType>(entry);
221 const string name = consume_word();
223 emit_fatal_and_terminate() <<
"Expected capitalized payload for simple type";
225 return ast_ptr<SimpleType>(entry, name);
230 }
else if (try_consume(
KWD_MUT)) {
232 }
else if (try_consume(
KWD_REF)) {
241 auto slice_ty = ast_ptr<SimpleType>(entry,
"Slice");
242 auto generic_args = vector<AnyTypeOrExpr>{};
243 generic_args.emplace_back(move(base));
244 base = ast_ptr<TemplatedType>(entry, move(slice_ty), move(generic_args));
246 auto generic_args = vector<AnyTypeOrExpr>{};
248 auto expr = parse_expr();
249 if (
auto* type_expr = dyn_cast<ast::TypeExpr>(expr.get()))
250 generic_args.emplace_back(move(type_expr->type));
252 generic_args.emplace_back(move(expr));
255 base = ast_ptr<TemplatedType>(entry, move(base), move(generic_args));
265 if (
auto maybe_fn_type = try_parse_function_type(); maybe_fn_type.has_value())
266 return maybe_fn_type;
268 auto entry = tokens.begin();
269 if (tokens->type !=
Word || !tokens->payload.has_value())
272 if (!try_peek_uword(0))
275 const string name = consume_word();
281 base = ast_ptr<SelfType>(entry);
283 base = ast_ptr<SimpleType>(entry, name);
288 }
else if (try_consume(
KWD_MUT)) {
290 }
else if (try_consume(
KWD_REF)) {
299 auto slice_ty = ast_ptr<SimpleType>(entry,
"Slice");
300 auto generic_args = vector<AnyTypeOrExpr>{};
301 generic_args.emplace_back(move(base));
302 base = ast_ptr<TemplatedType>(entry, move(slice_ty), move(generic_args));
304 auto generic_args = vector<AnyTypeOrExpr>{};
307 generic_args.emplace_back(move(*type));
309 generic_args.emplace_back(parse_expr());
312 base = ast_ptr<TemplatedType>(entry, move(base), move(generic_args));
322 auto entry = tokens.begin();
325 return ast_ptr<TypeName>(entry, move(type),
"self");
327 const string name = consume_word();
329 return ast_ptr<TypeName>(entry, move(type), name);
333 auto entry = tokens.begin();
334 auto left = parse_logical_and();
336 auto right = parse_logical_or();
337 left = ast_ptr<BinaryLogicExpr>(entry,
SYM_OR_OR.second, move(left), move(right));
343 auto entry = tokens.begin();
344 auto left = parse_operator();
347 left = ast_ptr<BinaryLogicExpr>(entry,
SYM_AND_AND.second, move(left), move(right));
356 if (tokens->type ==
Word) {
357 name = consume_word();
358 }
else if (tokens->type ==
Symbol) {
360 bool found_op =
false;
361 for (
const auto& op_row : operators()) {
362 for (
const auto& op : op_row) {
363 if (try_consume(op)) {
365 name = std::get<Atom>(op);
390 auto entry = tokens.begin();
392 bool interface = try_consume(KWD_INTERFACE);
396 auto annotations = std::unordered_set<string>{};
397 while (try_consume(
SYM_AT))
398 annotations.emplace(consume_word());
400 const string name = consume_word();
402 emit_fatal_and_terminate() <<
"Expected capitalized name for struct decl";
404 auto type_args = parse_generic_type_params();
406 auto fields = vector<TypeName>{};
408 consume_with_commas_until(
SYM_RPAREN, [&] { fields.push_back(move(*parse_type_name())); });
412 implements = parse_type();
416 auto body = vector<AnyStmt>{};
417 auto body_begin = tokens.begin();
418 while (!try_consume(
KWD_END)) {
419 body.emplace_back(parse_stmt());
423 return ast_ptr<StructDecl>(entry, name, move(fields), move(type_args), make_ast<Compound>(body_begin, move(body)),
424 move(implements), move(annotations), interface);
428 auto entry = tokens.begin();
430 auto field_name = consume_word();
431 AnyType proxy_type = ast_ptr<ProxyType>(entry, field_name);
432 auto proxied_arg = ast_ptr<TypeName>(entry, move(proxy_type), field_name);
434 auto implicit_field = ast_ptr<FieldAccessExpr>(entry, std::nullopt, field_name);
435 auto arg_var = ast_ptr<VarExpr>(entry, field_name);
436 auto extra_assign = ast_ptr<AssignExpr>(entry, move(implicit_field), move(arg_var));
438 return {move(proxied_arg), move(extra_assign)};
441 return {parse_type_name(), std::nullopt};
445 auto type_args = vector<GenericParam>{};
448 auto entry = tokens.begin();
449 auto name = consume_word();
450 if (is_uword(name)) {
453 type_args.push_back(make_ast<GenericParam>(entry, std::nullopt, name));
455 auto type = parse_type();
456 type_args.push_back(make_ast<GenericParam>(entry, move(type), name));
466 return parse_ctor_decl();
467 return parse_fn_decl();
471 auto entry = tokens.begin();
475 auto annotations = std::unordered_set<string>{};
476 while (try_consume(
SYM_AT))
477 annotations.emplace(consume_word());
479 const string name = parse_fn_name();
480 auto type_args = parse_generic_type_params();
484 auto args = vector<TypeName>{};
485 auto body = vector<AnyStmt>{};
488 auto arg = parse_fn_arg();
489 args.emplace_back(move(*arg.type_name));
491 body.emplace_back(move(arg.extra_body));
495 auto body_begin = entry;
497 if (try_consume(
SYM_EQ)) {
500 auto primitive = consume_word();
502 return ast_ptr<FnDecl>(entry, name, move(args), move(type_args), move(ret_type), primitive, move(annotations));
509 return ast_ptr<FnDecl>(entry, name, move(args), move(type_args), move(ret_type),
525 args.emplace_back(make_ast<TypeName>(entry, ast_ptr<SelfType>(entry),
""));
530 body_begin = tokens.begin();
531 auto expr = parse_expr();
532 body.emplace_back(ast_ptr<ReturnStmt>(entry, move(expr)));
537 body_begin = tokens.begin();
538 while (!try_consume(
KWD_END)) {
539 body.emplace_back(parse_stmt());
544 return ast_ptr<FnDecl>(entry, name, move(args), move(type_args), move(ret_type),
545 make_ast<Compound>(body_begin, move(body)), move(annotations));
549 auto entry = tokens.begin();
556 auto args = vector<TypeName>{};
557 auto body = vector<AnyStmt>{};
560 auto arg = parse_fn_arg();
561 args.emplace_back(move(*arg.type_name));
563 body.emplace_back(move(arg.extra_body));
569 auto body_begin = tokens.begin();
570 while (!try_consume(
KWD_END)) {
571 body.emplace_back(parse_stmt());
575 return ast_ptr<CtorDecl>(entry, move(args), make_ast<Compound>(body_begin, move(body)));
579 auto entry = tokens.begin();
582 const string name = consume_word();
587 auto init = parse_expr();
589 return ast_ptr<VarDecl>(entry, name, move(type), move(init));
593 auto entry = tokens.begin();
596 const string name = consume_word();
597 auto type =
AnyType{parse_type()};
601 auto init = parse_expr();
603 return ast_ptr<ConstDecl>(entry, name, move(type), move(init));
607 auto entry = tokens.begin();
610 auto cond = parse_expr();
614 auto body_begin = tokens.begin();
615 auto body = vector<AnyStmt>{};
616 while (!try_consume(
KWD_END)) {
617 body.emplace_back(parse_stmt());
621 auto compound = make_ast<Compound>(body_begin, move(body));
623 return ast_ptr<WhileStmt>(entry, move(cond), move(compound));
627 auto entry = tokens.begin();
630 if (!tokens.at_end() && try_peek(0, Separator))
631 return ast_ptr<ReturnStmt>(entry, std::nullopt);
633 auto expr = parse_expr();
635 return ast_ptr<ReturnStmt>(entry, move(expr));
639 auto entry = tokens.begin();
640 auto clause_begin = entry;
642 auto cond = parse_expr();
646 auto current_entry = tokens.begin();
647 auto else_entry = tokens.begin();
648 auto clauses = vector<IfClause>{};
649 auto current_body = vector<AnyStmt>{};
650 auto else_body = vector<AnyStmt>{};
651 bool in_else =
false;
654 auto current_clause_begin = tokens.begin();
659 if (!in_else && try_consume(
KWD_IF)) {
660 clauses.emplace_back(ts(clause_begin), move(cond), make_ast<Compound>(current_entry, move(current_body)));
661 current_body = vector<AnyStmt>{};
663 current_entry = tokens.begin();
664 clause_begin = current_clause_begin;
667 else_entry = tokens.begin();
672 auto st = parse_stmt();
674 else_body.emplace_back(move(st));
676 current_body.emplace_back(move(st));
679 if (else_body.empty())
680 else_entry = tokens.begin();
682 clauses.emplace_back(ts(clause_begin, else_entry - 1), move(cond),
683 Compound(ts(current_entry, else_entry - 1), move(current_body)));
685 auto else_clause = optional<Compound>{};
686 if (!else_body.empty())
687 else_clause.emplace(ts(else_entry), move(else_body));
689 return ast_ptr<IfStmt>(entry, move(clauses), move(else_clause));
693 static constexpr int BASE_16 = 16;
694 static constexpr int BASE_10 = 10;
695 auto entry = tokens.begin();
698 auto literal = string(assert_payload_next());
699 int64_t value = literal.starts_with(
"0x"sv) ? stoll(literal,
nullptr, BASE_16) : stoll(literal,
nullptr, BASE_10);
701 return ast_ptr<NumberExpr>({entry, 1}, value);
705 auto entry = tokens.begin();
708 auto value = string(assert_payload_next());
710 return ast_ptr<StringExpr>({entry, 1}, value);
714 auto entry = tokens.begin();
717 auto value = string(assert_payload_next())[0];
719 return ast_ptr<CharExpr>({entry, 1}, value);
723 const auto guard = make_guard(
"Parsing primary expression");
725 auto entry = tokens.begin();
728 if (
auto maybe_fn_type = try_parse_function_type(); maybe_fn_type.has_value())
729 return ast_ptr<TypeExpr>(entry, move(*maybe_fn_type));
732 auto val = parse_expr();
737 if (tokens->type == Number)
738 return parse_number_expr();
740 return parse_string_expr();
742 return parse_char_expr();
744 return ast_ptr<BoolExpr>(entry,
true);
746 return ast_ptr<BoolExpr>(entry,
false);
748 return ast_ptr<FieldAccessExpr>(entry, std::nullopt, consume_word());
750 return ast_ptr<ConstExpr>(entry, consume_word(), std::nullopt);
752 if (tokens->type ==
Word) {
753 if (try_peek_uword(0)) {
755 auto parent = consume_word();
757 return ast_ptr<ConstExpr>(entry, consume_word(), parent);
760 auto type = parse_type();
763 return ast_ptr<CtorExpr>(entry, move(type), move(call_args));
768 return ast_ptr<SliceExpr>(entry, move(type), move(slice_members));
772 if (try_peek_uword(0))
773 emit_fatal_and_terminate() <<
"Nested types aren't yet implemented";
775 auto name = consume_word();
776 auto call_args = vector<AnyExpr>{};
779 return ast_ptr<CallExpr>(entry, name, move(type), move(call_args));
782 return ast_ptr<TypeExpr>(entry, move(type));
784 auto name = consume_word();
787 return ast_ptr<CallExpr>(entry, name, std::nullopt, move(call_args));
789 return ast_ptr<VarExpr>({entry, 1}, name);
791 emit_fatal_and_terminate() <<
"Couldn't make an expression from here";
792 llvm_unreachable(
"Fatal error encountered");
796 auto entry = tokens.begin();
798 auto name = consume_word();
799 auto call_args = vector<AnyExpr>{};
800 call_args.emplace_back(move(receiver));
803 auto call = ast_ptr<CallExpr>(entry + 1, name, std::nullopt, move(call_args));
804 return parse_receiver(move(call), receiver_entry);
806 if (try_consume(
SYM_EQ)) {
807 auto value = parse_expr();
808 call_args.emplace_back(move(value));
809 auto call = ast_ptr<CallExpr>(entry + 1, name +
'=', std::nullopt, move(call_args));
810 return parse_receiver(move(call), receiver_entry);
812 auto noarg_call = ast_ptr<CallExpr>(receiver_entry, name, std::nullopt, move(call_args));
813 return parse_receiver(move(noarg_call), receiver_entry);
815 if (try_consume(
SYM_EQ)) {
816 auto value = parse_expr();
817 auto assign = ast_ptr<AssignExpr>(receiver_entry, move(receiver), move(value));
818 return parse_receiver(move(assign), receiver_entry);
821 auto args = vector<AnyExpr>{};
822 args.emplace_back(move(receiver));
823 args.emplace_back(parse_expr());
825 if (try_consume(
SYM_EQ)) {
826 auto value = parse_expr();
827 args.emplace_back(move(value));
828 auto call = ast_ptr<CallExpr>(entry,
"[]=", std::nullopt, move(args));
829 return parse_receiver(move(call), receiver_entry);
831 auto call = ast_ptr<CallExpr>(entry,
"[]", std::nullopt, move(args));
832 return parse_receiver(move(call), receiver_entry);
835 auto field = consume_word();
836 auto access = ast_ptr<FieldAccessExpr>(receiver_entry, move(receiver), field);
837 return parse_receiver(move(access), receiver_entry);
841 auto call_args = vector<AnyExpr>{};
842 call_args.emplace_back(move(receiver));
844 auto call = ast_ptr<CallExpr>(entry,
"->", std::nullopt, move(call_args));
845 return parse_receiver(move(call), receiver_entry);
851 auto entry = tokens.begin();
855 auto annotations = std::set<string>{};
856 while (try_consume(
SYM_AT))
857 annotations.emplace(consume_word());
861 auto args = vector<TypeName>{};
863 auto arg = parse_type_name();
864 args.emplace_back(move(*arg));
868 auto body_begin = entry;
869 auto body = vector<AnyStmt>{};
871 if (try_consume(
SYM_EQ)) {
872 body_begin = tokens.begin();
873 auto expr = parse_expr();
874 body.emplace_back(ast_ptr<ReturnStmt>(entry, move(expr)));
879 body_begin = tokens.begin();
880 while (!try_consume(
KWD_END)) {
881 body.emplace_back(parse_stmt());
886 return ast_ptr<LambdaExpr>(entry, move(args), move(ret_type), make_ast<Compound>(body_begin, move(body)),
892 return parse_lambda();
894 auto entry = tokens.begin();
895 return parse_receiver(parse_primary(), entry);
899 auto entry = tokens.begin();
900 for (
const auto& un_op : unary_operators()) {
901 if (try_consume(un_op)) {
902 auto value = parse_receiver();
903 auto args = vector<AnyExpr>{};
904 args.emplace_back(move(value));
905 return ast_ptr<CallExpr>(entry,
string(std::get<Atom>(un_op)), std::nullopt, move(args));
908 return parse_receiver();
916 auto entry = tokens.begin();
918 auto statements = vector<AnyStmt>{};
920 statements.emplace_back(parser.parse_stmt());
923 return make_unique<Program>(parser.ts(entry), move(statements));
Atoms represent strings in a string pool.
An iterator-like holding Tokens, used when parsing.
auto at_end() const noexcept -> bool
Check if the iterator is at the end and no more Tokens could possibly be read.
static const TokenAtom KWD_TYPE
static const TokenAtom KWD_DEF
static const TokenAtom SYM_RBRACKET
static const TokenAtom SYM_DOLLAR
static const TokenAtom KWD_SELF_ITEM
static const TokenAtom KWD_IF
static const TokenAtom SYM_COMMA
static const TokenAtom SYM_COLON
static const TokenAtom KWD_INTERFACE
static const TokenAtom KWD_LET
static const TokenAtom KWD_STRUCT
static const TokenAtom KWD_VARARGS
static const TokenAtom SYM_LBRACE
static const TokenAtom KWD_PRIMITIVE
static const TokenAtom SYM_AT
static constexpr auto Word
static const TokenAtom KWD_THEN
static const TokenAtom SYM_RPAREN
static const TokenAtom KWD_CONST
static const TokenAtom SYM_DOT
static const TokenAtom SYM_LPAREN
static const TokenAtom KWD_PTR
static const TokenAtom KWD_NEW
static const TokenAtom SYM_COLON_COLON
static const TokenAtom SYM_EQ
static const TokenAtom KWD_SELF_TYPE
static const TokenAtom KWD_WHILE
static const TokenAtom KWD_TRUE
static const TokenAtom SYM_BANG
static const TokenAtom SYM_ARROW
static const TokenAtom KWD_ABSTRACT
static const TokenAtom KWD_END
static const TokenAtom KWD_IS
static const TokenAtom KWD_EXTERN
static const TokenAtom SYM_AND_AND
static const TokenAtom KWD_ELSE
static const TokenAtom KWD_RETURN
static const TokenAtom KWD_MUT
static const TokenAtom SYM_RBRACE
static const TokenAtom KWD_REF
static const TokenAtom KWD_FALSE
static const TokenAtom SYM_LBRACKET
std::pair< Token::Type, Atom > TokenAtom
static const TokenAtom SYM_OR_OR
static constexpr auto Symbol
vector< Token >::iterator VectorTokenIterator
auto make_atom(std::string_view value) noexcept -> Atom
Create an Atom with the given string content.
auto at(const source_location location=source_location::current()) -> std::string
A categorized token in source code, created by the tokenizer. These tokens are consumed by the lexer.
@ Char
A character literal, beginning with ?
@ EndOfFile
A token added at the very end of the file.
@ Literal
A string literal, enclosed in quotes.
static auto constexpr type_name(Type type) -> const char *
A statement consisting of multiple other statements, i.e. the body of a function.
{ string name extern_decl_t
static auto parse(TokenIterator &tokens, diagnostic::NotesHolder ¬es) -> unique_ptr< Program >
auto parse_generic_type_params() -> vector< GenericParam >
auto parse_string_expr() -> unique_ptr< StringExpr >
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.
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.
auto parse_number_expr() -> unique_ptr< NumberExpr >
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.
auto parse_logical_and() -> unique_ptr< Expr >
auto parse_receiver() -> unique_ptr< Expr >
auto try_parse_function_type() -> optional< unique_ptr< FunctionType > >
auto emit_fatal_and_terminate(int offset=0) const noexcept(false) -> diagnostic::Note
auto parse_fn_or_ctor_decl() -> unique_ptr< Stmt >
auto try_parse_type() -> optional< unique_ptr< Type > >
static auto to_string(Token token) -> string
auto parse_unary() -> unique_ptr< Expr >
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.
auto parse_if_stmt() -> unique_ptr< IfStmt >
auto parse_struct_decl() -> unique_ptr< StructDecl >
auto next(source_location location=source_location::current()) -> Token
Return the next token and increment the iterator.
auto parse_while_stmt() -> unique_ptr< WhileStmt >
static constexpr auto Separator
auto parse_var_decl() -> unique_ptr< VarDecl >
auto assert_payload_next(source_location location=source_location::current()) -> Atom
Returns the payload of the next token and increment the iterator.
auto parse_fn_arg() -> FnArg
auto parse_type_name() -> unique_ptr< TypeName >
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.
auto parse_stmt(bool require_sep=true) -> unique_ptr< Stmt >
auto parse_fn_name() -> string
void require_separator(source_location location=source_location::current())
Consume all subsequent Separator tokens. Throws if none were found.
auto parse_const_decl() -> unique_ptr< ConstDecl >
auto parse_lambda() -> unique_ptr< LambdaExpr >
auto ignore_separator(source_location location=source_location::current()) -> bool
Ignore any Separator tokens if any are present.
auto parse_expr() -> unique_ptr< Expr >
auto parse_type(bool implicit_self=false) -> unique_ptr< Type >
auto parse_ctor_decl() -> unique_ptr< CtorDecl >
auto parse_fn_decl() -> unique_ptr< FnDecl >
auto parse_logical_or() -> unique_ptr< Expr >
auto parse_primary() -> unique_ptr< Expr >
auto parse_return_stmt() -> unique_ptr< ReturnStmt >
auto try_peek_uword(int ahead, source_location location=source_location::current()) const -> bool
Check if the ahead by ahead is a capitalized word.
auto parse_char_expr() -> unique_ptr< CharExpr >