const_TokenPtr t = lexer.peek_token ();
while (t->get_id () != RIGHT_CURLY)
{
- ExprOrStmt expr_or_stmt = parse_stmt_or_expr ();
- if (expr_or_stmt.is_error ())
+ auto expr_or_stmt = parse_stmt_or_expr ();
+ if (!expr_or_stmt)
{
skip_after_end_block ();
return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
t = lexer.peek_token ();
- if (expr_or_stmt.stmt != nullptr)
+ if (expr_or_stmt->stmt != nullptr)
{
- stmts.push_back (std::move (expr_or_stmt.stmt));
+ stmts.push_back (std::move (expr_or_stmt->stmt));
}
else
{
// assign to expression and end parsing inside
- expr = std::move (expr_or_stmt.expr);
- break;
+ expr = std::move (expr_or_stmt->expr);
}
}
if (!expr)
return tl::make_unexpected (Parse::Error::Node{});
- return AST::AnonConst (std::move (expr), locus);
+ return AST::AnonConst (std::move (expr.value ()), locus);
}
/* Parse a "const block", a block preceded by the `const` keyword whose
AST::AttrVec inner_attrs = parse_inner_attributes ();
// parse required expr inside parentheses
- std::unique_ptr<AST::Expr> expr_in_parens = parse_expr ();
+ auto expr_in_parens = parse_expr ();
if (!expr_in_parens)
{
// skip after somewhere?
}
return std::unique_ptr<AST::GroupedExpr> (
- new AST::GroupedExpr (std::move (expr_in_parens), std::move (inner_attrs),
- std::move (outer_attrs), locus));
+ new AST::GroupedExpr (std::move (expr_in_parens.value ()),
+ std::move (inner_attrs), std::move (outer_attrs),
+ locus));
}
// Parses a closure expression (closure definition).
// must be expr-only closure
// parse expr, which is required
- std::unique_ptr<AST::Expr> expr = parse_expr ();
- if (expr == nullptr)
+ auto expr = parse_expr ();
+ if (!expr)
{
Error error (t->get_locus (),
"failed to parse expression in closure");
}
return std::unique_ptr<AST::ClosureExprInner> (
- new AST::ClosureExprInner (std::move (expr), std::move (params), locus,
- has_move, std::move (outer_attrs)));
+ new AST::ClosureExprInner (std::move (expr.value ()),
+ std::move (params), locus, has_move,
+ std::move (outer_attrs)));
}
}
}
template <typename ManagedTokenSource>
-std::unique_ptr<AST::BoxExpr>
+tl::expected<std::unique_ptr<AST::BoxExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_box_expr (AST::AttrVec outer_attrs,
location_t pratt_parsed_loc)
{
ParseRestrictions restrictions;
restrictions.expr_can_be_null = false;
- std::unique_ptr<AST::Expr> expr = parse_expr (AST::AttrVec (), restrictions);
+ auto expr = parse_expr (AST::AttrVec (), restrictions);
+ if (!expr)
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
return std::unique_ptr<AST::BoxExpr> (
- new AST::BoxExpr (std::move (expr), std::move (outer_attrs), locus));
+ new AST::BoxExpr (std::move (expr.value ()), std::move (outer_attrs),
+ locus));
}
// Parses a return expression (including any expression to return).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ReturnExpr>
+tl::expected<std::unique_ptr<AST::ReturnExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_return_expr (AST::AttrVec outer_attrs,
location_t pratt_parsed_loc)
{
// parse expression to return, if it exists
ParseRestrictions restrictions;
restrictions.expr_can_be_null = true;
- std::unique_ptr<AST::Expr> returned_expr
- = parse_expr (AST::AttrVec (), restrictions);
+ auto returned_expr = parse_expr (AST::AttrVec (), restrictions);
+ tl::optional<std::unique_ptr<AST::Expr>> expr = tl::nullopt;
+ if (returned_expr)
+ expr = std::move (returned_expr.value ());
- return std::unique_ptr<AST::ReturnExpr> (
- new AST::ReturnExpr (std::move (returned_expr), std::move (outer_attrs),
- locus));
+ return std::make_unique<AST::ReturnExpr> (std::move (expr),
+ std::move (outer_attrs), locus);
}
// Parses a try expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::TryExpr>
+tl::expected<std::unique_ptr<AST::TryExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_try_expr (AST::AttrVec outer_attrs,
location_t pratt_parsed_loc)
{
auto block_expr = parse_block_expr ();
if (!block_expr)
- {
- Error error (lexer.peek_token ()->get_locus (),
- "failed to parse try block expression");
- add_error (std::move (error));
-
- return nullptr;
- }
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
return std::unique_ptr<AST::TryExpr> (
new AST::TryExpr (std::move (block_expr.value ()), std::move (outer_attrs),
/* Parses a break expression (including any label to break to AND any return
* expression). */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::BreakExpr>
+tl::expected<std::unique_ptr<AST::BreakExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_break_expr (AST::AttrVec outer_attrs,
location_t pratt_parsed_loc)
{
// parse break return expression if it exists
ParseRestrictions restrictions;
restrictions.expr_can_be_null = true;
- std::unique_ptr<AST::Expr> return_expr
- = parse_expr (AST::AttrVec (), restrictions);
+ auto return_expr = parse_expr (AST::AttrVec (), restrictions);
- return std::unique_ptr<AST::BreakExpr> (
- new AST::BreakExpr (std::move (label), std::move (return_expr),
- std::move (outer_attrs), locus));
+ if (return_expr)
+ return std::unique_ptr<AST::BreakExpr> (
+ new AST::BreakExpr (std::move (label), std::move (return_expr.value ()),
+ std::move (outer_attrs), locus));
+ else if (return_expr.error () == Parse::Error::Expr::NULL_EXPR)
+ return std::unique_ptr<AST::BreakExpr> (
+ new AST::BreakExpr (std::move (label), tl::nullopt,
+ std::move (outer_attrs), locus));
+ else
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
// Parses a continue expression (including any label to continue from).
? tl::optional<AST::Lifetime> (parsed_label.value ())
: tl::nullopt;
- return std::unique_ptr<AST::ContinueExpr> (
- new AST::ContinueExpr (std::move (label), std::move (outer_attrs), locus));
+ return std::make_unique<AST::ContinueExpr> (std::move (label),
+ std::move (outer_attrs), locus);
}
/* Parses an if expression of any kind, including with else, else if, else if
* let, and neither. Note that any outer attributes will be ignored because if
* expressions don't support them. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::IfExpr>
+tl::expected<std::unique_ptr<AST::IfExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec outer_attrs,
location_t pratt_parsed_loc)
{
if (!skip_token (IF))
{
skip_after_end_block ();
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
}
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
/* parse required condition expr - HACK to prevent struct expr from being
* parsed */
ParseRestrictions no_struct_expr;
no_struct_expr.can_be_struct_expr = false;
- std::unique_ptr<AST::Expr> condition = parse_expr ({}, no_struct_expr);
- if (condition == nullptr)
+ auto condition = parse_expr ({}, no_struct_expr);
+ if (!condition)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse condition expression in if expression");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
// parse required block expr
auto if_body = parse_block_expr ();
if (!if_body)
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
// branch to parse end or else (and then else, else if, or else if let)
if (lexer.peek_token ()->get_id () != ELSE)
{
// single selection - end of if expression
return std::unique_ptr<AST::IfExpr> (
- new AST::IfExpr (std::move (condition), std::move (if_body.value ()),
- std::move (outer_attrs), locus));
+ new AST::IfExpr (std::move (condition.value ()),
+ std::move (if_body.value ()), std::move (outer_attrs),
+ locus));
}
else
{
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::IfExprConseqElse> (
- new AST::IfExprConseqElse (std::move (condition),
+ new AST::IfExprConseqElse (std::move (condition.value ()),
std::move (if_body.value ()),
std::move (else_body.value ()),
std::move (outer_attrs), locus));
if (lexer.peek_token (1)->get_id () == LET)
{
// parse if let expr (required)
- std::unique_ptr<AST::IfLetExpr> if_let_expr
- = parse_if_let_expr ();
- if (if_let_expr == nullptr)
+ auto if_let_expr = parse_if_let_expr ();
+ if (!if_let_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse (else) if let expression "
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::IfExprConseqElse> (
- new AST::IfExprConseqElse (std::move (condition),
+ new AST::IfExprConseqElse (std::move (condition.value ()),
std::move (if_body.value ()),
- std::move (if_let_expr),
+ std::move (if_let_expr.value ()),
std::move (outer_attrs), locus));
}
else
{
// parse if expr (required)
- std::unique_ptr<AST::IfExpr> if_expr = parse_if_expr ();
- if (if_expr == nullptr)
+ auto if_expr = parse_if_expr ();
+ if (!if_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse (else) if expression after "
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::IfExprConseqElse> (
- new AST::IfExprConseqElse (std::move (condition),
+ new AST::IfExprConseqElse (std::move (condition.value ()),
std::move (if_body.value ()),
- std::move (if_expr),
+ std::move (if_expr.value ()),
std::move (outer_attrs), locus));
}
}
t->get_token_description ()));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
}
}
* if let, and none. Note that any outer attributes will be ignored as if let
* expressions don't support them. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::IfLetExpr>
+tl::expected<std::unique_ptr<AST::IfLetExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec outer_attrs,
location_t pratt_parsed_loc)
{
if (!skip_token (IF))
{
skip_after_end_block ();
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
}
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
lexer.skip_token ();
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
if (!skip_token (EQUAL))
{
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
// parse expression (required) - HACK to prevent struct expr being parsed
ParseRestrictions no_struct_expr;
no_struct_expr.can_be_struct_expr = false;
- std::unique_ptr<AST::Expr> scrutinee_expr = parse_expr ({}, no_struct_expr);
- if (scrutinee_expr == nullptr)
+ auto scrutinee_expr = parse_expr ({}, no_struct_expr);
+ if (!scrutinee_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse scrutinee expression in if let expression");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
/* TODO: check for expression not being a struct expression or lazy boolean
* expression here? or actually probably in semantic analysis. */
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
// branch to parse end or else (and then else, else if, or else if let)
{
// single selection - end of if let expression
return std::unique_ptr<AST::IfLetExpr> (new AST::IfLetExpr (
- std::move (match_arm_pattern), std::move (scrutinee_expr),
+ std::move (match_arm_pattern), std::move (scrutinee_expr.value ()),
std::move (if_let_body.value ()), std::move (outer_attrs), locus));
}
else
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::IfLetExprConseqElse> (
new AST::IfLetExprConseqElse (std::move (match_arm_pattern),
- std::move (scrutinee_expr),
+ std::move (scrutinee_expr.value ()),
std::move (if_let_body.value ()),
std::move (else_body.value ()),
std::move (outer_attrs), locus));
if (lexer.peek_token (1)->get_id () == LET)
{
// parse if let expr (required)
- std::unique_ptr<AST::IfLetExpr> if_let_expr
- = parse_if_let_expr ();
- if (if_let_expr == nullptr)
+ auto if_let_expr = parse_if_let_expr ();
+ if (!if_let_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse (else) if let expression "
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::IfLetExprConseqElse> (
new AST::IfLetExprConseqElse (
- std::move (match_arm_pattern), std::move (scrutinee_expr),
- std::move (if_let_body.value ()), std::move (if_let_expr),
- std::move (outer_attrs), locus));
+ std::move (match_arm_pattern),
+ std::move (scrutinee_expr.value ()),
+ std::move (if_let_body.value ()),
+ std::move (if_let_expr.value ()), std::move (outer_attrs),
+ locus));
}
else
{
// parse if expr (required)
- std::unique_ptr<AST::IfExpr> if_expr = parse_if_expr ();
- if (if_expr == nullptr)
+ auto if_expr = parse_if_expr ();
+ if (!if_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse (else) if expression after "
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::IfLetExprConseqElse> (
new AST::IfLetExprConseqElse (
- std::move (match_arm_pattern), std::move (scrutinee_expr),
- std::move (if_let_body.value ()), std::move (if_expr),
- std::move (outer_attrs), locus));
+ std::move (match_arm_pattern),
+ std::move (scrutinee_expr.value ()),
+ std::move (if_let_body.value ()),
+ std::move (if_expr.value ()), std::move (outer_attrs),
+ locus));
}
}
default:
t->get_token_description ()));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
}
}
/* Parses a "loop" infinite loop expression. Label is not parsed and should be
* parsed via parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::LoopExpr>
+tl::expected<std::unique_ptr<AST::LoopExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs,
tl::optional<AST::LoopLabel> label,
location_t pratt_parsed_loc)
if (!skip_token (LOOP))
{
skip_after_end_block ();
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
}
else
// parse loop body, which is required
auto loop_body = parse_block_expr ();
if (!loop_body)
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
return std::unique_ptr<AST::LoopExpr> (
new AST::LoopExpr (std::move (loop_body.value ()), locus, std::move (label),
/* Parses a "while" loop expression. Label is not parsed and should be parsed
* via parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::WhileLoopExpr>
+tl::expected<std::unique_ptr<AST::WhileLoopExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_while_loop_expr (
AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label,
location_t pratt_parsed_loc)
if (!skip_token (WHILE))
{
skip_after_end_block ();
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
}
else
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
// parse loop predicate (required) with HACK to prevent struct expr parsing
ParseRestrictions no_struct_expr;
no_struct_expr.can_be_struct_expr = false;
- std::unique_ptr<AST::Expr> predicate = parse_expr ({}, no_struct_expr);
- if (predicate == nullptr)
+ auto predicate = parse_expr ({}, no_struct_expr);
+ if (!predicate)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse predicate expression in while loop");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
/* TODO: check that it isn't struct expression here? actually, probably in
* semantic analysis */
add_error (std::move (error));
// skip somewhere
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::WhileLoopExpr> (
- new AST::WhileLoopExpr (std::move (predicate), std::move (body.value ()),
- locus, std::move (label), std::move (outer_attrs)));
+ new AST::WhileLoopExpr (std::move (predicate.value ()),
+ std::move (body.value ()), locus, std::move (label),
+ std::move (outer_attrs)));
}
/* Parses a "while let" loop expression. Label is not parsed and should be
* parsed via parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::WhileLetLoopExpr>
+tl::expected<std::unique_ptr<AST::WhileLetLoopExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_while_let_loop_expr (
AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label)
{
add_error (std::move (error));
// skip somewhere
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
// as this token is definitely let now, save the computation of comparison
lexer.skip_token ();
Error error (lexer.peek_token ()->get_locus (),
"should be at least 1 pattern");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
if (!skip_token (EQUAL))
{
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
/* parse predicate expression, which is required (and HACK to prevent struct
* expr) */
ParseRestrictions no_struct_expr;
no_struct_expr.can_be_struct_expr = false;
- std::unique_ptr<AST::Expr> predicate_expr = parse_expr ({}, no_struct_expr);
- if (predicate_expr == nullptr)
+ auto predicate_expr = parse_expr ({}, no_struct_expr);
+ if (!predicate_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse predicate expression in while let loop");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
/* TODO: ensure that struct expression is not parsed? Actually, probably in
* semantic analysis. */
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::WhileLetLoopExpr> (
new AST::WhileLetLoopExpr (std::move (predicate_pattern),
- std::move (predicate_expr),
+ std::move (predicate_expr.value ()),
std::move (body.value ()), locus,
std::move (label), std::move (outer_attrs)));
}
/* Parses a "for" iterative loop. Label is not parsed and should be parsed via
* parse_labelled_loop_expr, which would call this. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ForLoopExpr>
+tl::expected<std::unique_ptr<AST::ForLoopExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_for_loop_expr (
AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label)
{
// parse pattern, which is required
std::unique_ptr<AST::Pattern> pattern = parse_pattern ();
- if (pattern == nullptr)
+ if (!pattern)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse iterator pattern in for loop");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
if (!skip_token (IN))
{
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
/* parse iterator expression, which is required - also HACK to prevent
* struct expr */
ParseRestrictions no_struct_expr;
no_struct_expr.can_be_struct_expr = false;
- std::unique_ptr<AST::Expr> expr = parse_expr ({}, no_struct_expr);
- if (expr == nullptr)
+ auto expr = parse_expr ({}, no_struct_expr);
+ if (!expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse iterator expression in for loop");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
// TODO: check to ensure this isn't struct expr? Or in semantic analysis.
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::ForLoopExpr> (
- new AST::ForLoopExpr (std::move (pattern), std::move (expr),
+ new AST::ForLoopExpr (std::move (pattern), std::move (expr.value ()),
std::move (body.value ()), locus, std::move (label),
std::move (outer_attrs)));
}
// Parses a loop expression with label (any kind of loop - disambiguates).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::Expr>
+tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_labelled_loop_expr (const_TokenPtr tok,
AST::AttrVec outer_attrs)
{
"label) - found %qs",
tok->get_token_description ());
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
else
add_error (std::move (error));
// skip?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
}
case WHILE:
// further disambiguate into while vs while let
if (lexer.peek_token (1)->get_id () == LET)
- {
- return parse_while_let_loop_expr (std::move (outer_attrs),
- std::move (label));
- }
+ return parse_while_let_loop_expr (std::move (outer_attrs),
+ std::move (label));
else
- {
- return parse_while_loop_expr (std::move (outer_attrs),
- std::move (label));
- }
+ return parse_while_loop_expr (std::move (outer_attrs),
+ std::move (label));
case LEFT_CURLY:
- {
- auto block
- = parse_block_expr (std::move (outer_attrs), std::move (label));
- if (block)
- return std::move (block.value ());
- else
- return nullptr;
- }
+ return parse_block_expr (std::move (outer_attrs), std::move (label));
default:
// error
add_error (Error (t->get_locus (),
t->get_token_description ()));
// skip?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
}
// Parses a match expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::MatchExpr>
+tl::expected<std::unique_ptr<AST::MatchExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_match_expr (AST::AttrVec outer_attrs,
location_t pratt_parsed_loc)
{
* expr) */
ParseRestrictions no_struct_expr;
no_struct_expr.can_be_struct_expr = false;
- std::unique_ptr<AST::Expr> scrutinee = parse_expr ({}, no_struct_expr);
- if (scrutinee == nullptr)
+ auto scrutinee = parse_expr ({}, no_struct_expr);
+ if (!scrutinee)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse scrutinee expression in match expression");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
/* TODO: check for scrutinee expr not being struct expr? or do so in
* semantic analysis */
if (!skip_token (LEFT_CURLY))
{
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
// parse inner attributes (if they exist)
"failed to parse match arm in match arms");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
if (!skip_token (MATCH_ARROW))
{
// skip after somewhere?
// TODO is returning here a good idea? or is break better?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
ParseRestrictions restrictions;
restrictions.expr_can_be_stmt = true;
- std::unique_ptr<AST::Expr> expr = parse_expr ({}, restrictions);
+ auto expr = parse_expr ({}, restrictions);
- if (expr == nullptr)
+ if (!expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse expr in match arm in match expr");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
- bool is_expr_without_block = expr->is_expr_without_block ();
+ bool is_expr_without_block = expr.value ()->is_expr_without_block ();
- match_arms.push_back (AST::MatchCase (std::move (arm), std::move (expr)));
+ match_arms.push_back (
+ AST::MatchCase (std::move (arm), std::move (expr.value ())));
// handle comma presence
if (lexer.peek_token ()->get_id () != COMMA)
"expression in match arm (if not final case)");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
else
{
if (!skip_token (RIGHT_CURLY))
{
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
match_arms.shrink_to_fit ();
return std::unique_ptr<AST::MatchExpr> (
- new AST::MatchExpr (std::move (scrutinee), std::move (match_arms),
+ new AST::MatchExpr (std::move (scrutinee.value ()), std::move (match_arms),
std::move (inner_attrs), std::move (outer_attrs),
locus));
}
// Parses an async block expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::AsyncBlockExpr>
+tl::expected<std::unique_ptr<AST::AsyncBlockExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_async_block_expr (AST::AttrVec outer_attrs)
{
location_t locus = lexer.peek_token ()->get_locus ();
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::AsyncBlockExpr> (
// Parses an unsafe block expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::UnsafeBlockExpr>
+tl::expected<std::unique_ptr<AST::UnsafeBlockExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_unsafe_block_expr (
AST::AttrVec outer_attrs, location_t pratt_parsed_loc)
{
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
return std::unique_ptr<AST::UnsafeBlockExpr> (
new AST::UnsafeBlockExpr (std::move (block_expr.value ()),
// Parses an array definition expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArrayExpr>
+tl::expected<std::unique_ptr<AST::ArrayExpr>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_array_expr (AST::AttrVec outer_attrs,
location_t pratt_parsed_loc)
{
{
// should have array elements
// parse initial expression, which is required for either
- std::unique_ptr<AST::Expr> initial_expr = parse_expr ();
- if (initial_expr == nullptr)
+ auto initial_expr = parse_expr ();
+ if (!initial_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"could not parse expression in array expression "
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
if (lexer.peek_token ()->get_id () == SEMICOLON)
lexer.skip_token ();
// parse copy amount expression (required)
- std::unique_ptr<AST::Expr> copy_amount = parse_expr ();
- if (copy_amount == nullptr)
+ auto copy_amount = parse_expr ();
+ if (!copy_amount)
{
Error error (lexer.peek_token ()->get_locus (),
"could not parse copy amount expression in array "
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
skip_token (RIGHT_SQUARE);
std::unique_ptr<AST::ArrayElemsCopied> copied_array_elems (
- new AST::ArrayElemsCopied (std::move (initial_expr),
- std::move (copy_amount), locus));
+ new AST::ArrayElemsCopied (std::move (initial_expr.value ()),
+ std::move (copy_amount.value ()),
+ locus));
return std::unique_ptr<AST::ArrayExpr> (
new AST::ArrayExpr (std::move (copied_array_elems),
std::move (inner_attrs),
// single-element array expression
std::vector<std::unique_ptr<AST::Expr>> exprs;
exprs.reserve (1);
- exprs.push_back (std::move (initial_expr));
+ exprs.push_back (std::move (initial_expr.value ()));
exprs.shrink_to_fit ();
skip_token (RIGHT_SQUARE);
{
// multi-element array expression (or trailing comma)
std::vector<std::unique_ptr<AST::Expr>> exprs;
- exprs.push_back (std::move (initial_expr));
+ exprs.push_back (std::move (initial_expr.value ()));
const_TokenPtr t = lexer.peek_token ();
while (t->get_id () == COMMA)
break;
// parse expression (required)
- std::unique_ptr<AST::Expr> expr = parse_expr ();
- if (expr == nullptr)
+ auto expr = parse_expr ();
+ if (!expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse element in array expression");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
- exprs.push_back (std::move (expr));
+ exprs.push_back (std::move (expr.value ()));
t = lexer.peek_token ();
}
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
}
}
// Parses a grouped or tuple expression (disambiguates).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ExprWithoutBlock>
+tl::expected<std::unique_ptr<AST::ExprWithoutBlock>, Parse::Error::Node>
Parser<ManagedTokenSource>::parse_grouped_or_tuple_expr (
AST::AttrVec outer_attrs, location_t pratt_parsed_loc)
{
}
// parse first expression (required)
- std::unique_ptr<AST::Expr> first_expr = parse_expr ();
- if (first_expr == nullptr)
+ auto first_expr = parse_expr ();
+ if (!first_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse expression in grouped or tuple expression");
add_error (std::move (error));
// skip after somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
// detect whether grouped expression with right parentheses as next token
// create grouped expr
return std::unique_ptr<AST::GroupedExpr> (
- new AST::GroupedExpr (std::move (first_expr), std::move (inner_attrs),
- std::move (outer_attrs), locus));
+ new AST::GroupedExpr (std::move (first_expr.value ()),
+ std::move (inner_attrs), std::move (outer_attrs),
+ locus));
}
else if (lexer.peek_token ()->get_id () == COMMA)
{
// tuple expr
std::vector<std::unique_ptr<AST::Expr>> exprs;
- exprs.push_back (std::move (first_expr));
+ exprs.push_back (std::move (first_expr.value ()));
// parse potential other tuple exprs
const_TokenPtr t = lexer.peek_token ();
break;
// parse expr, which is now required
- std::unique_ptr<AST::Expr> expr = parse_expr ();
- if (expr == nullptr)
+ auto expr = parse_expr ();
+ if (!expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse expr in tuple expr");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
}
- exprs.push_back (std::move (expr));
+ exprs.push_back (std::move (expr.value ()));
t = lexer.peek_token ();
}
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Node::MALFORMED);
}
}
// Parses a struct expression field.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::StructExprField>
+tl::expected<std::unique_ptr<AST::StructExprField>,
+ Parse::Error::StructExprField>
Parser<ManagedTokenSource>::parse_struct_expr_field ()
{
AST::AttrVec outer_attrs = parse_outer_attributes ();
lexer.skip_token (1);
// parse expression (required)
- std::unique_ptr<AST::Expr> expr = parse_expr ();
- if (expr == nullptr)
+ auto expr = parse_expr ();
+ if (!expr)
{
Error error (t->get_locus (),
"failed to parse struct expression field with "
"identifier and expression");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (
+ Parse::Error::StructExprField::CHILD_ERROR);
}
return std::unique_ptr<AST::StructExprFieldIdentifierValue> (
new AST::StructExprFieldIdentifierValue (std::move (ident),
- std::move (expr),
+ std::move (expr.value ()),
std::move (outer_attrs),
t->get_locus ()));
}
if (!skip_token (COLON))
{
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::StructExprField::MALFORMED);
}
// parse field expression (required)
- std::unique_ptr<AST::Expr> expr = parse_expr ();
- if (expr == nullptr)
+ auto expr = parse_expr ();
+ if (!expr)
{
Error error (t->get_locus (),
"failed to parse expr in struct (or enum) expr "
"field with tuple index");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::StructExprField::CHILD_ERROR);
}
return std::unique_ptr<AST::StructExprFieldIndexValue> (
- new AST::StructExprFieldIndexValue (index, std::move (expr),
+ new AST::StructExprFieldIndexValue (index, std::move (expr.value ()),
std::move (outer_attrs),
t->get_locus ()));
}
/* this is a struct base and can't be parsed here, so just return
* nothing without erroring */
- return nullptr;
+ return tl::unexpected (Parse::Error::StructExprField::STRUCT_BASE);
default:
add_error (
Error (t->get_locus (),
"expected identifier or integer literal",
t->get_token_description ()));
- return nullptr;
+ return tl::unexpected (Parse::Error::StructExprField::MALFORMED);
}
}
/* Pratt parser impl of parse_expr. FIXME: this is only provisional and
* probably will be changed. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::Expr>
+tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_expr (int right_binding_power,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions)
TokenId id = current_token->get_id ();
if (id == SEMICOLON || id == RIGHT_PAREN || id == RIGHT_CURLY
|| id == RIGHT_SQUARE || id == COMMA || id == LEFT_CURLY)
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::NULL_EXPR);
}
ParseRestrictions null_denotation_restrictions = restrictions;
null_denotation_restrictions.expr_can_be_stmt = false;
// parse null denotation (unary part of expression)
- std::unique_ptr<AST::Expr> expr
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr> expr
= null_denotation ({}, null_denotation_restrictions);
- if (expr == nullptr)
- return nullptr;
+ if (!expr)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
return left_denotations (std::move (expr), right_binding_power,
std::move (outer_attrs), restrictions);
// Parse expression with lowest left binding power.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::Expr>
+tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_expr (AST::AttrVec outer_attrs,
ParseRestrictions restrictions)
{
}
template <typename ManagedTokenSource>
-std::unique_ptr<AST::Expr>
-Parser<ManagedTokenSource>::left_denotations (std::unique_ptr<AST::Expr> expr,
- int right_binding_power,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions)
+tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
+Parser<ManagedTokenSource>::left_denotations (
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr> expr,
+ int right_binding_power, AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions)
{
- if (expr == nullptr)
+ if (!expr)
{
// DEBUG
rust_debug ("null denotation is null; returning null for parse_expr");
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::NULL_DENOTATION);
}
const_TokenPtr current_token = lexer.peek_token ();
- if (restrictions.expr_can_be_stmt && !expr->is_expr_without_block ()
+ if (restrictions.expr_can_be_stmt && !expr.value ()->is_expr_without_block ()
&& current_token->get_id () != DOT
&& current_token->get_id () != QUESTION_MARK)
{
rust_debug ("statement expression with block");
- expr->set_outer_attrs (std::move (outer_attrs));
+ expr.value ()->set_outer_attrs (std::move (outer_attrs));
return expr;
}
lexer.skip_token ();
// FIXME attributes should generally be applied to the null denotation.
- expr = left_denotation (current_token, std::move (expr),
+ expr = left_denotation (current_token, std::move (expr.value ()),
std::move (outer_attrs), restrictions);
- if (expr == nullptr)
+ if (!expr)
{
// DEBUG
rust_debug ("left denotation is null; returning null for parse_expr");
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::LEFT_DENOTATION);
}
current_token = lexer.peek_token ();
/* Determines action to take when finding token at beginning of expression. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::Expr>
+tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::null_denotation (AST::AttrVec outer_attrs,
ParseRestrictions restrictions)
{
// Handling of expresions that start with a path for `null_denotation`.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::Expr>
+tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::null_denotation_path (
AST::PathInExpression path, AST::AttrVec outer_attrs,
ParseRestrictions restrictions)
{
// HACK: add outer attrs to path
path.set_outer_attrs (std::move (outer_attrs));
- return std::unique_ptr<AST::PathInExpression> (
- new AST::PathInExpression (std::move (path)));
+ return std::make_unique<AST::PathInExpression> (std::move (path));
}
// branch on next token
// assume path is returned
// HACK: add outer attributes to path
path.set_outer_attrs (std::move (outer_attrs));
- return std::unique_ptr<AST::PathInExpression> (
- new AST::PathInExpression (std::move (path)));
+ return std::make_unique<AST::PathInExpression> (std::move (path));
}
return parse_struct_expr_tuple_partial (std::move (path),
std::move (outer_attrs));
// Handling of expresions that do not start with a path for `null_denotation`.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::Expr>
+tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::null_denotation_not_path (
const_TokenPtr tok, AST::AttrVec outer_attrs, ParseRestrictions restrictions)
{
AST::QualifiedPathInExpression path
= parse_qualified_path_in_expression (tok->get_locus ());
path.set_outer_attrs (std::move (outer_attrs));
- return std::unique_ptr<AST::QualifiedPathInExpression> (
- new AST::QualifiedPathInExpression (std::move (path)));
+ return std::make_unique<AST::QualifiedPathInExpression> (
+ std::move (path));
}
// FIXME: delegate to parse_literal_expr instead? would have to rejig
// tokens and whatever.
AST::Literal::BOOL, tok->get_type_hint (), {},
tok->get_locus ()));
case LEFT_PAREN:
- return parse_grouped_or_tuple_expr (std::move (outer_attrs),
- tok->get_locus ());
+ {
+ auto grouped_or_tuple_expr
+ = parse_grouped_or_tuple_expr (std::move (outer_attrs),
+ tok->get_locus ());
+ if (grouped_or_tuple_expr)
+ return std::move (grouped_or_tuple_expr.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
/*case PLUS: { // unary plus operator
// invoke parse_expr recursively with appropriate priority, etc. for
entered_from_unary.entered_from_unary = true;
if (!restrictions.can_be_struct_expr)
entered_from_unary.can_be_struct_expr = false;
- std::unique_ptr<AST::Expr> expr
- = parse_expr (LBP_UNARY_MINUS, {}, entered_from_unary);
+ auto expr = parse_expr (LBP_UNARY_MINUS, {}, entered_from_unary);
- if (expr == nullptr)
- return nullptr;
+ if (!expr)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// can only apply to integer and float expressions
/*if (expr.get_type() != integer_type_node || expr.get_type() !=
float_type_node) { rust_error_at(tok->get_locus(), "operand of unary
/* FIXME: allow outer attributes on these expressions by having an
* outer attrs parameter in function*/
- return std::unique_ptr<AST::NegationExpr> (
- new AST::NegationExpr (std::move (expr), NegationOperator::NEGATE,
- std::move (outer_attrs), tok->get_locus ()));
+ return std::make_unique<AST::NegationExpr> (std::move (expr.value ()),
+ NegationOperator::NEGATE,
+ std::move (outer_attrs),
+ tok->get_locus ());
}
case EXCLAM:
{ // logical or bitwise not
entered_from_unary.entered_from_unary = true;
if (!restrictions.can_be_struct_expr)
entered_from_unary.can_be_struct_expr = false;
- std::unique_ptr<AST::Expr> expr
- = parse_expr (LBP_UNARY_EXCLAM, {}, entered_from_unary);
+ auto expr = parse_expr (LBP_UNARY_EXCLAM, {}, entered_from_unary);
- if (expr == nullptr)
- return nullptr;
+ if (!expr)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// can only apply to boolean expressions
/*if (expr.get_type() != boolean_type_node) {
rust_error_at(tok->get_locus(),
* analysis */
// FIXME: allow outer attributes on these expressions
- return std::unique_ptr<AST::NegationExpr> (
- new AST::NegationExpr (std::move (expr), NegationOperator::NOT,
- std::move (outer_attrs), tok->get_locus ()));
+ return std::make_unique<AST::NegationExpr> (std::move (expr.value ()),
+ NegationOperator::NOT,
+ std::move (outer_attrs),
+ tok->get_locus ());
}
case ASTERISK:
{
ParseRestrictions entered_from_unary;
entered_from_unary.entered_from_unary = true;
entered_from_unary.can_be_struct_expr = false;
- std::unique_ptr<AST::Expr> expr
- = parse_expr (LBP_UNARY_ASTERISK, {}, entered_from_unary);
+ auto expr = parse_expr (LBP_UNARY_ASTERISK, {}, entered_from_unary);
+ if (!expr)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: allow outer attributes on expression
- return std::unique_ptr<AST::DereferenceExpr> (
- new AST::DereferenceExpr (std::move (expr), std::move (outer_attrs),
- tok->get_locus ()));
+ return std::make_unique<AST::DereferenceExpr> (std::move (
+ expr.value ()),
+ std::move (outer_attrs),
+ tok->get_locus ());
}
case AMP:
{
// (single) "borrow" expression - shared (mutable) or immutable
- std::unique_ptr<AST::Expr> expr = nullptr;
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr> expr
+ = tl::unexpected (Parse::Error::Expr::MALFORMED);
Mutability mutability = Mutability::Imm;
bool raw_borrow = false;
"raw borrow should be either const or mut");
}
lexer.skip_token ();
- expr = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary);
+ auto expr_result
+ = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary);
+ if (expr_result)
+ expr = std::move (expr_result.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
raw_borrow = true;
}
else if (t->get_id () == MUT)
{
lexer.skip_token ();
- expr = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary);
+ auto expr_result
+ = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary);
+ if (expr_result)
+ expr = std::move (expr_result.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
mutability = Mutability::Mut;
raw_borrow = false;
}
else
{
- expr = parse_expr (LBP_UNARY_AMP, {}, entered_from_unary);
+ auto expr_result
+ = parse_expr (LBP_UNARY_AMP, {}, entered_from_unary);
+ if (expr_result)
+ expr = std::move (expr_result.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
raw_borrow = false;
}
// FIXME: allow outer attributes on expression
- return std::unique_ptr<AST::BorrowExpr> (
- new AST::BorrowExpr (std::move (expr), mutability, raw_borrow, false,
- std::move (outer_attrs), tok->get_locus ()));
+ return std::make_unique<AST::BorrowExpr> (std::move (expr.value ()),
+ mutability, raw_borrow, false,
+ std::move (outer_attrs),
+ tok->get_locus ());
}
case LOGICAL_AND:
{
if (lexer.peek_token ()->get_id () == MUT)
{
lexer.skip_token ();
- expr = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary);
+ auto expr_res
+ = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary);
+ if (!expr_res)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ expr = std::move (expr_res.value ());
mutability = Mutability::Mut;
}
else
{
- expr = parse_expr (LBP_UNARY_AMP, {}, entered_from_unary);
+ auto expr_result
+ = parse_expr (LBP_UNARY_AMP, {}, entered_from_unary);
+ if (expr_result)
+ expr = std::move (expr_result.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
mutability = Mutability::Imm;
}
// FIXME: allow outer attributes on expression
- return std::unique_ptr<AST::BorrowExpr> (
- new AST::BorrowExpr (std::move (expr), mutability, false, true,
- std::move (outer_attrs), tok->get_locus ()));
+ return std::make_unique<AST::BorrowExpr> (std::move (expr), mutability,
+ false, true,
+ std::move (outer_attrs),
+ tok->get_locus ());
}
case OR:
case PIPE:
case MOVE:
// closure expression
- return parse_closure_expr_pratt (tok, std::move (outer_attrs));
+ {
+ auto ret = parse_closure_expr_pratt (tok, std::move (outer_attrs));
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case DOT_DOT:
// either "range to" or "range full" expressions
- return parse_nud_range_exclusive_expr (tok, std::move (outer_attrs));
+ {
+ auto ret
+ = parse_nud_range_exclusive_expr (tok, std::move (outer_attrs));
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case DOT_DOT_EQ:
// range to inclusive expr
- return parse_range_to_inclusive_expr (tok, std::move (outer_attrs));
+ {
+ auto ret = parse_range_to_inclusive_expr (tok, std::move (outer_attrs));
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case RETURN_KW:
// FIXME: is this really a null denotation expression?
- return parse_return_expr (std::move (outer_attrs), tok->get_locus ());
+ {
+ auto ret
+ = parse_return_expr (std::move (outer_attrs), tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case TRY:
// FIXME: is this really a null denotation expression?
- return parse_try_expr (std::move (outer_attrs), tok->get_locus ());
+ {
+ auto ret = parse_try_expr (std::move (outer_attrs), tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case BREAK:
// FIXME: is this really a null denotation expression?
- return parse_break_expr (std::move (outer_attrs), tok->get_locus ());
+ {
+ auto ret
+ = parse_break_expr (std::move (outer_attrs), tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case CONTINUE:
return parse_continue_expr (std::move (outer_attrs), tok->get_locus ());
case LEFT_CURLY:
// ok - this is an expression with block for once.
{
- auto block = parse_block_expr (std::move (outer_attrs), tl::nullopt,
- tok->get_locus ());
- if (block)
- return std::move (block.value ());
+ auto ret = parse_block_expr (std::move (outer_attrs), tl::nullopt,
+ tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
else
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
case IF:
// if or if let, so more lookahead to find out
if (lexer.peek_token ()->get_id () == LET)
{
// if let expr
- return parse_if_let_expr (std::move (outer_attrs), tok->get_locus ());
+ auto ret
+ = parse_if_let_expr (std::move (outer_attrs), tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
else
{
// if expr
- return parse_if_expr (std::move (outer_attrs), tok->get_locus ());
+ auto ret = parse_if_expr (std::move (outer_attrs), tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
case LIFETIME:
- return parse_labelled_loop_expr (tok, std::move (outer_attrs));
+ {
+ auto ret = parse_labelled_loop_expr (tok, std::move (outer_attrs));
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case LOOP:
- return parse_loop_expr (std::move (outer_attrs), tl::nullopt,
- tok->get_locus ());
+ {
+ auto ret = parse_loop_expr (std::move (outer_attrs), tl::nullopt,
+ tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case WHILE:
if (lexer.peek_token ()->get_id () == LET)
{
- return parse_while_let_loop_expr (std::move (outer_attrs));
+ auto ret = parse_while_let_loop_expr (std::move (outer_attrs));
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
else
{
- return parse_while_loop_expr (std::move (outer_attrs), tl::nullopt,
- tok->get_locus ());
+ auto ret = parse_while_loop_expr (std::move (outer_attrs),
+ tl::nullopt, tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
case FOR:
- return parse_for_loop_expr (std::move (outer_attrs), tl::nullopt);
+ {
+ auto ret = parse_for_loop_expr (std::move (outer_attrs), tl::nullopt);
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case MATCH_KW:
// also an expression with block
- return parse_match_expr (std::move (outer_attrs), tok->get_locus ());
+ {
+ auto ret
+ = parse_match_expr (std::move (outer_attrs), tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
+
case LEFT_SQUARE:
// array definition expr (not indexing)
- return parse_array_expr (std::move (outer_attrs), tok->get_locus ());
+ {
+ auto ret
+ = parse_array_expr (std::move (outer_attrs), tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case UNSAFE:
- return parse_unsafe_block_expr (std::move (outer_attrs),
- tok->get_locus ());
+ {
+ auto ret = parse_unsafe_block_expr (std::move (outer_attrs),
+ tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case BOX:
- return parse_box_expr (std::move (outer_attrs), tok->get_locus ());
+ {
+ auto ret = parse_box_expr (std::move (outer_attrs), tok->get_locus ());
+ if (ret)
+ return std::move (ret.value ());
+ else
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
+ }
case UNDERSCORE:
add_error (
Error (tok->get_locus (),
"use of %qs is not allowed on the right-side of an assignment",
tok->get_token_description ()));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
case CONST:
{
- auto const_block
+ auto ret
= parse_const_block_expr (std::move (outer_attrs), tok->get_locus ());
- if (const_block)
- return std::move (const_block.value ());
+ if (ret)
+ return std::move (ret.value ());
else
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
default:
if (!restrictions.expr_can_be_null)
add_error (Error (tok->get_locus (),
"found unexpected token %qs in null denotation",
tok->get_token_description ()));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
}
* operators or other punctuation. Returns a function pointer to member
* function that implements the left denotation for the token given. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::Expr>
+tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
{
location_t left_locus = left->get_locus ();
// error propagation expression - unary postfix
- return std::unique_ptr<AST::ErrorPropagationExpr> (
- new AST::ErrorPropagationExpr (std::move (left),
- std::move (outer_attrs), left_locus));
+ return std::make_unique<AST::ErrorPropagationExpr> (
+ std::move (left), std::move (outer_attrs), left_locus);
}
case PLUS:
// sum expression - binary infix
"found scope resolution operator in left denotation "
"function - this should probably be handled elsewhere"));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
case DOT:
{
/* field expression or method call - relies on parentheses after next
"found unexpected token %qs in left denotation",
tok->get_token_description ()));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
}
// Parses an arithmetic or logical expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_arithmetic_or_logical_expr (
const_TokenPtr, std::unique_ptr<AST::Expr> left, AST::AttrVec,
AST::ArithmeticOrLogicalExpr::ExprType expr_type,
ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (get_lbp_for_arithmetic_or_logical_expr (expr_type),
- AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (get_lbp_for_arithmetic_or_logical_expr (expr_type),
+ AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- expr_type, locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()), expr_type, locus);
}
// Parses a binary addition expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_plus_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_PLUS, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_PLUS, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::ADD, locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::ADD, locus);
}
// Parses a binary subtraction expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_minus_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_MINUS, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_MINUS, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::SUBTRACT,
- locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::SUBTRACT, locus);
}
// Parses a binary multiplication expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_mult_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_MUL, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_MUL, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::MULTIPLY,
- locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::MULTIPLY, locus);
}
// Parses a binary division expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_div_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_DIV, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_DIV, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::DIVIDE,
- locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::DIVIDE, locus);
}
// Parses a binary modulo expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_mod_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_MOD, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_MOD, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::MODULUS,
- locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::MODULUS, locus);
}
/* Parses a binary bitwise (or eager logical) and expression (with Pratt
* parsing). */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_bitwise_and_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_AMP, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_AMP, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::BITWISE_AND,
- locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::BITWISE_AND, locus);
}
/* Parses a binary bitwise (or eager logical) or expression (with Pratt
* parsing). */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_bitwise_or_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_PIPE, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_PIPE, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::BITWISE_OR,
- locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::BITWISE_OR, locus);
}
/* Parses a binary bitwise (or eager logical) xor expression (with Pratt
* parsing). */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_bitwise_xor_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_CARET, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_CARET, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::BITWISE_XOR,
- locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::BITWISE_XOR, locus);
}
// Parses a binary left shift expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_left_shift_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_L_SHIFT, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_L_SHIFT, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::LEFT_SHIFT,
- locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::LEFT_SHIFT, locus);
}
// Parses a binary right shift expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_right_shift_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_R_SHIFT, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_R_SHIFT, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
- new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
- ArithmeticOrLogicalOperator::RIGHT_SHIFT,
- locus));
+ return std::make_unique<AST::ArithmeticOrLogicalExpr> (
+ std::move (left), std::move (right.value ()),
+ ArithmeticOrLogicalOperator::RIGHT_SHIFT, locus);
}
/* Returns the left binding power for the given ComparisonExpr type.
* specify one and have the other looked up - e.g. specify ExprType and
* binding power is looked up? */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ComparisonExpr>
+tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_comparison_expr (
const_TokenPtr, std::unique_ptr<AST::Expr> left, AST::AttrVec,
AST::ComparisonExpr::ExprType expr_type, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (get_lbp_for_comparison_expr (expr_type), AST::AttrVec (),
- restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (get_lbp_for_comparison_expr (expr_type),
+ AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ComparisonExpr> (
- new AST::ComparisonExpr (std::move (left), std::move (right), expr_type,
- locus));
+ return std::make_unique<AST::ComparisonExpr> (std::move (left),
+ std::move (right.value ()),
+ expr_type, locus);
}
// Parses a binary equal to expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ComparisonExpr>
+tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_equal_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_EQUAL, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_EQUAL, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ComparisonExpr> (
- new AST::ComparisonExpr (std::move (left), std::move (right),
- ComparisonOperator::EQUAL, locus));
+ return std::make_unique<AST::ComparisonExpr> (std::move (left),
+ std::move (right.value ()),
+ ComparisonOperator::EQUAL,
+ locus);
}
// Parses a binary not equal to expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ComparisonExpr>
+tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_not_equal_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_NOT_EQUAL, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_NOT_EQUAL, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ComparisonExpr> (
- new AST::ComparisonExpr (std::move (left), std::move (right),
- ComparisonOperator::NOT_EQUAL, locus));
+ return std::make_unique<AST::ComparisonExpr> (std::move (left),
+ std::move (right.value ()),
+ ComparisonOperator::NOT_EQUAL,
+ locus);
}
// Parses a binary greater than expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ComparisonExpr>
+tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_greater_than_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_GREATER_THAN, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_GREATER_THAN, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ComparisonExpr> (
- new AST::ComparisonExpr (std::move (left), std::move (right),
- ComparisonOperator::GREATER_THAN, locus));
+ return std::make_unique<AST::ComparisonExpr> (
+ std::move (left), std::move (right.value ()),
+ ComparisonOperator::GREATER_THAN, locus);
}
// Parses a binary less than expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ComparisonExpr>
+tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_less_than_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_SMALLER_THAN, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_SMALLER_THAN, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ComparisonExpr> (
- new AST::ComparisonExpr (std::move (left), std::move (right),
- ComparisonOperator::LESS_THAN, locus));
+ return std::make_unique<AST::ComparisonExpr> (std::move (left),
+ std::move (right.value ()),
+ ComparisonOperator::LESS_THAN,
+ locus);
}
// Parses a binary greater than or equal to expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ComparisonExpr>
+tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_greater_equal_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_GREATER_EQUAL, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_GREATER_EQUAL, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ComparisonExpr> (
- new AST::ComparisonExpr (std::move (left), std::move (right),
- ComparisonOperator::GREATER_OR_EQUAL, locus));
+ return std::make_unique<AST::ComparisonExpr> (
+ std::move (left), std::move (right.value ()),
+ ComparisonOperator::GREATER_OR_EQUAL, locus);
}
// Parses a binary less than or equal to expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ComparisonExpr>
+tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_binary_less_equal_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_SMALLER_EQUAL, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_SMALLER_EQUAL, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::ComparisonExpr> (
- new AST::ComparisonExpr (std::move (left), std::move (right),
- ComparisonOperator::LESS_OR_EQUAL, locus));
+ return std::make_unique<AST::ComparisonExpr> (
+ std::move (left), std::move (right.value ()),
+ ComparisonOperator::LESS_OR_EQUAL, locus);
}
// Parses a binary lazy boolean or expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::LazyBooleanExpr>
+tl::expected<std::unique_ptr<AST::LazyBooleanExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_lazy_or_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_LOGICAL_OR, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_LOGICAL_OR, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::LazyBooleanExpr> (
- new AST::LazyBooleanExpr (std::move (left), std::move (right),
- LazyBooleanOperator::LOGICAL_OR, locus));
+ return std::make_unique<AST::LazyBooleanExpr> (
+ std::move (left), std::move (right.value ()),
+ LazyBooleanOperator::LOGICAL_OR, locus);
}
// Parses a binary lazy boolean and expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::LazyBooleanExpr>
+tl::expected<std::unique_ptr<AST::LazyBooleanExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_lazy_and_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_LOGICAL_AND, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_LOGICAL_AND, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::LazyBooleanExpr> (
- new AST::LazyBooleanExpr (std::move (left), std::move (right),
- LazyBooleanOperator::LOGICAL_AND, locus));
+ return std::make_unique<AST::LazyBooleanExpr> (
+ std::move (left), std::move (right.value ()),
+ LazyBooleanOperator::LOGICAL_AND, locus);
}
// Parses a pseudo-binary infix type cast expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::TypeCastExpr>
+tl::expected<std::unique_ptr<AST::TypeCastExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_type_cast_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> expr_to_cast,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED,
ParseRestrictions restrictions ATTRIBUTE_UNUSED)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::TypeNoBounds> type = parse_type_no_bounds ();
- if (type == nullptr)
- return nullptr;
+ auto type = parse_type_no_bounds ();
+ if (!type)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: how do I get precedence put in here?
// TODO: check types. actually, do so during semantic analysis
location_t locus = expr_to_cast->get_locus ();
- return std::unique_ptr<AST::TypeCastExpr> (
- new AST::TypeCastExpr (std::move (expr_to_cast), std::move (type), locus));
+ return std::make_unique<AST::TypeCastExpr> (std::move (expr_to_cast),
+ std::move (type), locus);
}
// Parses a binary assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::AssignmentExpr>
+tl::expected<std::unique_ptr<AST::AssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_ASSIG - 1, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
- // TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::AssignmentExpr> (
- new AST::AssignmentExpr (std::move (left), std::move (right),
- std::move (outer_attrs), locus));
+ return std::make_unique<AST::AssignmentExpr> (std::move (left),
+ std::move (right.value ()),
+ std::move (outer_attrs), locus);
}
/* Returns the left binding power for the given CompoundAssignmentExpr type.
// Parses a compound assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_compound_assignment_expr (
const_TokenPtr, std::unique_ptr<AST::Expr> left, AST::AttrVec,
AST::CompoundAssignmentExpr::ExprType expr_type,
ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (get_lbp_for_compound_assignment_expr (expr_type) - 1,
- AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (get_lbp_for_compound_assignment_expr (expr_type) - 1,
+ AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- expr_type, locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()), expr_type, locus);
}
// Parses a binary add-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_plus_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_PLUS_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_PLUS_ASSIG - 1, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::ADD, locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::ADD, locus);
}
// Parses a binary minus-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_minus_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_MINUS_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_MINUS_ASSIG - 1, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::SUBTRACT,
- locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::SUBTRACT, locus);
}
// Parses a binary multiplication-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_mult_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_MULT_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_MULT_ASSIG - 1, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::MULTIPLY,
- locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::MULTIPLY, locus);
}
// Parses a binary division-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_div_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_DIV_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_DIV_ASSIG - 1, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::DIVIDE,
- locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::DIVIDE, locus);
}
// Parses a binary modulo-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_mod_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_MOD_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_MOD_ASSIG - 1, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::MODULUS,
- locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::MODULUS, locus);
}
// Parses a binary and-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_and_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_AMP_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_AMP_ASSIG - 1, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::BITWISE_AND,
- locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::BITWISE_AND, locus);
}
// Parses a binary or-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_or_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_PIPE_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_PIPE_ASSIG - 1, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::BITWISE_OR,
- locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::BITWISE_OR, locus);
}
// Parses a binary xor-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_xor_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_CARET_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_CARET_ASSIG - 1, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::BITWISE_XOR,
- locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::BITWISE_XOR, locus);
}
// Parses a binary left shift-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_left_shift_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
+ auto right
= parse_expr (LBP_L_SHIFT_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::LEFT_SHIFT,
- locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::LEFT_SHIFT, locus);
}
// Parses a binary right shift-assignment expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CompoundAssignmentExpr>
+tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_right_shift_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
+ auto right
= parse_expr (LBP_R_SHIFT_ASSIG - 1, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::CompoundAssignmentExpr> (
- new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
- CompoundAssignmentOperator::RIGHT_SHIFT,
- locus));
+ return std::make_unique<AST::CompoundAssignmentExpr> (
+ std::move (left), std::move (right.value ()),
+ CompoundAssignmentOperator::RIGHT_SHIFT, locus);
}
// Parses a postfix unary await expression (with Pratt parsing).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::AwaitExpr>
+tl::expected<std::unique_ptr<AST::AwaitExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_await_expr (
const_TokenPtr tok, std::unique_ptr<AST::Expr> expr_to_await,
AST::AttrVec outer_attrs)
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
// TODO: check inside async block in semantic analysis
/* Parses an exclusive range ('..') in left denotation position (i.e.
* RangeFromExpr or RangeFromToExpr). */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::RangeExpr>
+tl::expected<std::unique_ptr<AST::RangeExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_led_range_exclusive_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
// Can be nullptr, in which case it is a RangeFromExpr, otherwise a
// RangeFromToExpr.
restrictions.expr_can_be_null = true;
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_DOT_DOT, AST::AttrVec (), restrictions);
+ auto right = parse_expr (LBP_DOT_DOT, AST::AttrVec (), restrictions);
location_t locus = left->get_locus ();
- if (right == nullptr)
+ if (!right)
{
// range from expr
- return std::unique_ptr<AST::RangeFromExpr> (
- new AST::RangeFromExpr (std::move (left), locus));
+ return std::make_unique<AST::RangeFromExpr> (std::move (left), locus);
}
else
{
- return std::unique_ptr<AST::RangeFromToExpr> (
- new AST::RangeFromToExpr (std::move (left), std::move (right), locus));
+ return std::make_unique<AST::RangeFromToExpr> (std::move (left),
+ std::move (right.value ()),
+ locus);
}
// FIXME: make non-associative
}
/* Parses an exclusive range ('..') in null denotation position (i.e.
* RangeToExpr or RangeFullExpr). */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::RangeExpr>
+tl::expected<std::unique_ptr<AST::RangeExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_nud_range_exclusive_expr (
const_TokenPtr tok, AST::AttrVec outer_attrs ATTRIBUTE_UNUSED)
{
// FIXME: this probably parses expressions accidently or whatever
// try parsing RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_DOT_DOT, AST::AttrVec (), restrictions);
+ auto right = parse_expr (LBP_DOT_DOT, AST::AttrVec (), restrictions);
location_t locus = tok->get_locus ();
- if (right == nullptr)
+ if (!right)
{
// range from expr
- return std::unique_ptr<AST::RangeFullExpr> (
- new AST::RangeFullExpr (locus));
+ return std::make_unique<AST::RangeFullExpr> (locus);
}
else
{
- return std::unique_ptr<AST::RangeToExpr> (
- new AST::RangeToExpr (std::move (right), locus));
+ return std::make_unique<AST::RangeToExpr> (std::move (right.value ()),
+ locus);
}
// FIXME: make non-associative
}
// Parses a full binary range inclusive expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::RangeFromToInclExpr>
+tl::expected<std::unique_ptr<AST::RangeFromToInclExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_range_inclusive_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right
- = parse_expr (LBP_DOT_DOT_EQ, AST::AttrVec (), restrictions);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_DOT_DOT_EQ, AST::AttrVec (), restrictions);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: make non-associative
// TODO: check types. actually, do so during semantic analysis
location_t locus = left->get_locus ();
- return std::unique_ptr<AST::RangeFromToInclExpr> (
- new AST::RangeFromToInclExpr (std::move (left), std::move (right), locus));
+ return std::make_unique<AST::RangeFromToInclExpr> (std::move (left),
+ std::move (right.value ()),
+ locus);
}
// Parses an inclusive range-to prefix unary expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::RangeToInclExpr>
+tl::expected<std::unique_ptr<AST::RangeToInclExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_range_to_inclusive_expr (
const_TokenPtr tok, AST::AttrVec outer_attrs ATTRIBUTE_UNUSED)
{
// parse RHS (as tok has already been consumed in parse_expression)
- std::unique_ptr<AST::Expr> right = parse_expr (LBP_DOT_DOT_EQ);
- if (right == nullptr)
- return nullptr;
+ auto right = parse_expr (LBP_DOT_DOT_EQ);
+ if (!right)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// FIXME: make non-associative
// TODO: check types. actually, do so during semantic analysis
- return std::unique_ptr<AST::RangeToInclExpr> (
- new AST::RangeToInclExpr (std::move (right), tok->get_locus ()));
+ return std::make_unique<AST::RangeToInclExpr> (std::move (right.value ()),
+ tok->get_locus ());
}
// Parses a pseudo-binary infix tuple index expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::TupleIndexExpr>
+tl::expected<std::unique_ptr<AST::TupleIndexExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_tuple_index_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> tuple_expr,
AST::AttrVec outer_attrs, ParseRestrictions restrictions ATTRIBUTE_UNUSED)
// parse int literal (as token already skipped)
const_TokenPtr index_tok = expect_token (INT_LITERAL);
if (index_tok == nullptr)
- {
- return nullptr;
- }
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
+
std::string index = index_tok->get_str ();
// convert to integer
location_t locus = tuple_expr->get_locus ();
- return std::unique_ptr<AST::TupleIndexExpr> (
- new AST::TupleIndexExpr (std::move (tuple_expr), index_int,
- std::move (outer_attrs), locus));
+ return std::make_unique<AST::TupleIndexExpr> (std::move (tuple_expr),
+ index_int,
+ std::move (outer_attrs), locus);
}
// Parses a pseudo-binary infix array (or slice) index expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ArrayIndexExpr>
+tl::expected<std::unique_ptr<AST::ArrayIndexExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_index_expr (
const_TokenPtr, std::unique_ptr<AST::Expr> array_expr,
AST::AttrVec outer_attrs, ParseRestrictions)
= parse_expr (LBP_ARRAY_REF, AST::AttrVec (),
restrictions);*/
// TODO: conceptually, should treat [] as brackets, so just parse all expr
- std::unique_ptr<AST::Expr> index_expr = parse_expr ();
- if (index_expr == nullptr)
- return nullptr;
+ auto index_expr = parse_expr ();
+ if (!index_expr)
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
// skip ']' at end of array
if (!skip_token (RIGHT_SQUARE))
{
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
// TODO: check types. actually, do so during semantic analysis
location_t locus = array_expr->get_locus ();
- return std::unique_ptr<AST::ArrayIndexExpr> (
- new AST::ArrayIndexExpr (std::move (array_expr), std::move (index_expr),
- std::move (outer_attrs), locus));
+ return std::make_unique<AST::ArrayIndexExpr> (std::move (array_expr),
+ std::move (index_expr.value ()),
+ std::move (outer_attrs), locus);
}
// Parses a pseudo-binary infix struct field access expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::FieldAccessExpr>
+tl::expected<std::unique_ptr<AST::FieldAccessExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_field_access_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> struct_expr,
AST::AttrVec outer_attrs, ParseRestrictions restrictions ATTRIBUTE_UNUSED)
* not await, for instance) */
const_TokenPtr ident_tok = expect_token (IDENTIFIER);
if (ident_tok == nullptr)
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
Identifier ident{ident_tok};
location_t locus = struct_expr->get_locus ();
// TODO: check types. actually, do so during semantic analysis
- return std::unique_ptr<AST::FieldAccessExpr> (
- new AST::FieldAccessExpr (std::move (struct_expr), std::move (ident),
- std::move (outer_attrs), locus));
+ return std::make_unique<AST::FieldAccessExpr> (std::move (struct_expr),
+ std::move (ident),
+ std::move (outer_attrs),
+ locus);
}
// Parses a pseudo-binary infix method call expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::MethodCallExpr>
+tl::expected<std::unique_ptr<AST::MethodCallExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_method_call_expr (
const_TokenPtr tok, std::unique_ptr<AST::Expr> receiver_expr,
AST::AttrVec outer_attrs, ParseRestrictions)
"failed to parse path expr segment of method call expr");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
// skip left parentheses
if (!skip_token (LEFT_PAREN))
{
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
// parse method params (if they exist)
const_TokenPtr t = lexer.peek_token ();
while (t->get_id () != RIGHT_PAREN)
{
- std::unique_ptr<AST::Expr> param = parse_expr ();
- if (param == nullptr)
+ auto param = parse_expr ();
+ if (!param)
{
Error error (t->get_locus (),
"failed to parse method param in method call");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
- params.push_back (std::move (param));
+ params.push_back (std::move (param.value ()));
if (lexer.peek_token ()->get_id () != COMMA)
break;
// skip right paren
if (!skip_token (RIGHT_PAREN))
{
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
// TODO: check types. actually do so in semantic analysis pass.
location_t locus = receiver_expr->get_locus ();
- return std::unique_ptr<AST::MethodCallExpr> (
- new AST::MethodCallExpr (std::move (receiver_expr), std::move (segment),
- std::move (params), std::move (outer_attrs),
- locus));
+ return std::make_unique<AST::MethodCallExpr> (std::move (receiver_expr),
+ std::move (segment),
+ std::move (params),
+ std::move (outer_attrs), locus);
}
// Parses a pseudo-binary infix function call expression.
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CallExpr>
+tl::expected<std::unique_ptr<AST::CallExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_function_call_expr (
const_TokenPtr, std::unique_ptr<AST::Expr> function_expr,
AST::AttrVec outer_attrs, ParseRestrictions)
const_TokenPtr t = lexer.peek_token ();
while (t->get_id () != RIGHT_PAREN)
{
- std::unique_ptr<AST::Expr> param = parse_expr ();
- if (param == nullptr)
+ auto param = parse_expr ();
+ if (!param)
{
Error error (t->get_locus (),
"failed to parse function param in function call");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
- params.push_back (std::move (param));
+ params.push_back (std::move (param.value ()));
if (lexer.peek_token ()->get_id () != COMMA)
break;
if (!skip_token (RIGHT_PAREN))
{
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
// TODO: check types. actually, do so during semantic analysis
location_t locus = function_expr->get_locus ();
- return std::unique_ptr<AST::CallExpr> (
- new AST::CallExpr (std::move (function_expr), std::move (params),
- std::move (outer_attrs), locus));
+ return std::make_unique<AST::CallExpr> (std::move (function_expr),
+ std::move (params),
+ std::move (outer_attrs), locus);
}
/* Parses a struct expr struct with a path in expression already parsed (but
* not
* '{' token). */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::StructExprStruct>
+tl::expected<std::unique_ptr<AST::StructExprStruct>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_struct_expr_struct_partial (
AST::PathInExpression path, AST::AttrVec outer_attrs)
{
// lookup) again, make statement if final ';'
if (!skip_token (LEFT_CURLY))
{
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
// parse inner attributes
// struct with no body
lexer.skip_token ();
- return std::unique_ptr<AST::StructExprStruct> (
- new AST::StructExprStruct (std::move (path), std::move (inner_attrs),
- std::move (outer_attrs), path_locus));
+ return std::make_unique<AST::StructExprStruct> (std::move (path),
+ std::move (inner_attrs),
+ std::move (outer_attrs),
+ path_locus);
case DOT_DOT:
/* technically this would give a struct base-only struct, but this
* algorithm should work too. As such, AST type not happening. */
while (t->get_id () != RIGHT_CURLY && t->get_id () != DOT_DOT)
{
- std::unique_ptr<AST::StructExprField> field
- = parse_struct_expr_field ();
- if (field == nullptr)
+ auto field = parse_struct_expr_field ();
+ if (!field
+ && field.error () != Parse::Error::StructExprField::STRUCT_BASE)
{
Error error (t->get_locus (),
"failed to parse struct (or enum) expr field");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
// DEBUG:
rust_debug ("struct/enum expr field validated to not be null");
- fields.push_back (std::move (field));
+ fields.push_back (std::move (field.value ()));
// DEBUG:
rust_debug ("struct/enum expr field pushed back");
lexer.skip_token ();
// parse required struct base expr
- std::unique_ptr<AST::Expr> base_expr = parse_expr ();
- if (base_expr == nullptr)
+ auto base_expr = parse_expr ();
+ if (!base_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse struct base expression in struct "
"expression");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
// DEBUG:
rust_debug ("struct/enum expr - parsed and validated base expr");
- struct_base
- = AST::StructBase (std::move (base_expr), dot_dot_location);
+ struct_base = AST::StructBase (std::move (base_expr.value ()),
+ dot_dot_location);
// DEBUG:
rust_debug ("assigned struct base to new struct base ");
if (!skip_token (RIGHT_CURLY))
{
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
// DEBUG:
rust_debug (
"struct/enum expr skipped right curly - done and ready to return");
- return std::unique_ptr<AST::StructExprStructFields> (
- new AST::StructExprStructFields (std::move (path), std::move (fields),
- path_locus, std::move (struct_base),
- std::move (inner_attrs),
- std::move (outer_attrs)));
+ return std::make_unique<AST::StructExprStructFields> (
+ std::move (path), std::move (fields), path_locus,
+ std::move (struct_base), std::move (inner_attrs),
+ std::move (outer_attrs));
}
default:
add_error (
"expected %<}%>, identifier, integer literal, or %<..%>",
t->get_token_description ()));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
}
* A better solution would be to just get this to call that function directly.
* */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::CallExpr>
+tl::expected<std::unique_ptr<AST::CallExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_struct_expr_tuple_partial (
AST::PathInExpression path, AST::AttrVec outer_attrs)
{
if (!skip_token (LEFT_PAREN))
{
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
AST::AttrVec inner_attrs = parse_inner_attributes ();
while (t->get_id () != RIGHT_PAREN)
{
// parse expression (required)
- std::unique_ptr<AST::Expr> expr = parse_expr ();
- if (expr == nullptr)
+ auto expr = parse_expr ();
+ if (!expr)
{
Error error (t->get_locus (), "failed to parse expression in "
"struct (or enum) expression tuple");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
- exprs.push_back (std::move (expr));
+ exprs.push_back (std::move (expr.value ()));
if (lexer.peek_token ()->get_id () != COMMA)
break;
if (!skip_token (RIGHT_PAREN))
{
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
location_t path_locus = path.get_locus ();
- auto pathExpr = std::unique_ptr<AST::PathInExpression> (
- new AST::PathInExpression (std::move (path)));
+ auto pathExpr = std::make_unique<AST::PathInExpression> (std::move (path));
- return std::unique_ptr<AST::CallExpr> (
- new AST::CallExpr (std::move (pathExpr), std::move (exprs),
- std::move (outer_attrs), path_locus));
+ return std::make_unique<AST::CallExpr> (std::move (pathExpr),
+ std::move (exprs),
+ std::move (outer_attrs), path_locus);
}
// Parses a closure expression with pratt parsing (from null denotation).
template <typename ManagedTokenSource>
-std::unique_ptr<AST::ClosureExpr>
+tl::expected<std::unique_ptr<AST::ClosureExpr>, Parse::Error::Expr>
Parser<ManagedTokenSource>::parse_closure_expr_pratt (const_TokenPtr tok,
AST::AttrVec outer_attrs)
{
Error error (t->get_locus (), "could not parse closure param");
add_error (std::move (error));
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
params.push_back (std::move (param));
if (!skip_token (PIPE))
{
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
break;
}
tok->get_token_description ()));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::MALFORMED);
}
// again branch based on next token
lexer.skip_token ();
// parse actual type, which is required
- std::unique_ptr<AST::TypeNoBounds> type = parse_type_no_bounds ();
- if (type == nullptr)
+ auto type = parse_type_no_bounds ();
+ if (!type)
{
// error
Error error (tok->get_locus (), "failed to parse type for closure");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
// parse block expr, which is required
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
- return std::unique_ptr<AST::ClosureExprInnerTyped> (
- new AST::ClosureExprInnerTyped (std::move (type),
- std::move (block.value ()),
- std::move (params), locus, has_move,
- std::move (outer_attrs)));
+ return std::make_unique<AST::ClosureExprInnerTyped> (
+ std::move (type), std::move (block.value ()), std::move (params), locus,
+ has_move, std::move (outer_attrs));
}
else
{
// must be expr-only closure
// parse expr, which is required
- std::unique_ptr<AST::Expr> expr = parse_expr ();
- if (expr == nullptr)
+ auto expr = parse_expr ();
+ if (!expr)
{
Error error (tok->get_locus (),
"failed to parse expression in closure");
add_error (std::move (error));
// skip somewhere?
- return nullptr;
+ return tl::unexpected (Parse::Error::Expr::CHILD_ERROR);
}
- return std::unique_ptr<AST::ClosureExprInner> (
- new AST::ClosureExprInner (std::move (expr), std::move (params), locus,
- has_move, std::move (outer_attrs)));
+ return std::make_unique<AST::ClosureExprInner> (std::move (expr.value ()),
+ std::move (params), locus,
+ has_move,
+ std::move (outer_attrs));
}
}
: expr (std::move (macro))
{}
- // Returns whether this object is in an error state.
- bool is_error () const
- {
- return (expr == nullptr && stmt == nullptr)
- || (expr != nullptr && stmt != nullptr);
- }
-
- // Returns an error state object.
- static ExprOrStmt create_error () { return ExprOrStmt (nullptr, nullptr); }
-
~ExprOrStmt () = default;
/* no copy constructors/assignment as simple object like this shouldn't
*/
bool maybe_skip_token (TokenId t);
- std::unique_ptr<AST::Expr>
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
parse_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
ParseRestrictions restrictions = ParseRestrictions ());
AST::AttrVec outer_attrs);
// Expression-related (Pratt parsed)
- std::unique_ptr<AST::Expr>
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
parse_expr (int right_binding_power,
AST::AttrVec outer_attrs = AST::AttrVec (),
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::Expr>
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
null_denotation (AST::AttrVec outer_attrs = AST::AttrVec (),
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::Expr>
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
null_denotation_path (AST::PathInExpression path, AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::Expr>
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
null_denotation_not_path (const_TokenPtr t, AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- std::unique_ptr<AST::Expr>
- left_denotations (std::unique_ptr<AST::Expr> null_denotation,
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
+ left_denotations (tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
+ null_denotation,
int right_binding_power, AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::Expr>
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Expr>
left_denotation (const_TokenPtr t, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs = AST::AttrVec (),
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_arithmetic_or_logical_expr (
const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs, AST::ArithmeticOrLogicalExpr::ExprType expr_type,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_binary_plus_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_binary_minus_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_binary_mult_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_binary_div_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_binary_mod_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_bitwise_and_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_bitwise_or_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_bitwise_xor_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_left_shift_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ tl::expected<std::unique_ptr<AST::ArithmeticOrLogicalExpr>,
+ Parse::Error::Expr>
parse_right_shift_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- std::unique_ptr<AST::ComparisonExpr>
+ tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
parse_comparison_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
AST::ComparisonExpr::ExprType expr_type,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ComparisonExpr>
+ tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
parse_binary_equal_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- std::unique_ptr<AST::ComparisonExpr> parse_binary_not_equal_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ComparisonExpr> parse_binary_greater_than_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ComparisonExpr> parse_binary_less_than_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ComparisonExpr> parse_binary_greater_equal_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ComparisonExpr> parse_binary_less_equal_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::LazyBooleanExpr>
+ tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
+ parse_binary_not_equal_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> left,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
+ parse_binary_greater_than_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> left,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
+ parse_binary_less_than_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> left,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
+ parse_binary_greater_equal_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> left,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::ComparisonExpr>, Parse::Error::Expr>
+ parse_binary_less_equal_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> left,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::LazyBooleanExpr>, Parse::Error::Expr>
parse_lazy_or_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::LazyBooleanExpr>
+ tl::expected<std::unique_ptr<AST::LazyBooleanExpr>, Parse::Error::Expr>
parse_lazy_and_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::TypeCastExpr>
+ tl::expected<std::unique_ptr<AST::TypeCastExpr>, Parse::Error::Expr>
parse_type_cast_expr (const_TokenPtr tok,
std::unique_ptr<AST::Expr> expr_to_cast,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::AssignmentExpr>
+ tl::expected<std::unique_ptr<AST::AssignmentExpr>, Parse::Error::Expr>
parse_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr> parse_compound_assignment_expr (
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
+ parse_compound_assignment_expr (
const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs, AST::CompoundAssignmentExpr::ExprType expr_type,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr>
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
parse_plus_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr>
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
parse_minus_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr>
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
parse_mult_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr>
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
parse_div_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr>
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
parse_mod_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr>
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
parse_and_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr>
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
parse_or_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr>
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
parse_xor_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr> parse_left_shift_assig_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CompoundAssignmentExpr> parse_right_shift_assig_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::AwaitExpr>
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
+ parse_left_shift_assig_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> left,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::CompoundAssignmentExpr>, Parse::Error::Expr>
+ parse_right_shift_assig_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> left,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::AwaitExpr>, Parse::Error::Expr>
parse_await_expr (const_TokenPtr tok,
std::unique_ptr<AST::Expr> expr_to_await,
AST::AttrVec outer_attrs);
- std::unique_ptr<AST::MethodCallExpr> parse_method_call_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> receiver_expr,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::CallExpr> parse_function_call_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> function_expr,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::RangeExpr> parse_led_range_exclusive_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::RangeExpr>
+ tl::expected<std::unique_ptr<AST::MethodCallExpr>, Parse::Error::Expr>
+ parse_method_call_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> receiver_expr,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::CallExpr>, Parse::Error::Expr>
+ parse_function_call_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> function_expr,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::RangeExpr>, Parse::Error::Expr>
+ parse_led_range_exclusive_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> left,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::RangeExpr>, Parse::Error::Expr>
parse_nud_range_exclusive_expr (const_TokenPtr tok, AST::AttrVec outer_attrs);
- std::unique_ptr<AST::RangeFromToInclExpr> parse_range_inclusive_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> left,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::RangeToInclExpr>
+ tl::expected<std::unique_ptr<AST::RangeFromToInclExpr>, Parse::Error::Expr>
+ parse_range_inclusive_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> left,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::RangeToInclExpr>, Parse::Error::Expr>
parse_range_to_inclusive_expr (const_TokenPtr tok, AST::AttrVec outer_attrs);
- std::unique_ptr<AST::TupleIndexExpr> parse_tuple_index_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> tuple_expr,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::FieldAccessExpr> parse_field_access_expr (
- const_TokenPtr tok, std::unique_ptr<AST::Expr> struct_expr,
- AST::AttrVec outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::ArrayIndexExpr>
+ tl::expected<std::unique_ptr<AST::TupleIndexExpr>, Parse::Error::Expr>
+ parse_tuple_index_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> tuple_expr,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::FieldAccessExpr>, Parse::Error::Expr>
+ parse_field_access_expr (const_TokenPtr tok,
+ std::unique_ptr<AST::Expr> struct_expr,
+ AST::AttrVec outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ tl::expected<std::unique_ptr<AST::ArrayIndexExpr>, Parse::Error::Expr>
parse_index_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> array_expr,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
std::unique_ptr<AST::MacroInvocation> parse_macro_invocation_partial (
AST::PathInExpression path, AST::AttrVec outer_attrs,
ParseRestrictions restrictions = ParseRestrictions ());
- std::unique_ptr<AST::StructExprStruct>
+ tl::expected<std::unique_ptr<AST::StructExprStruct>, Parse::Error::Expr>
parse_struct_expr_struct_partial (AST::PathInExpression path,
AST::AttrVec outer_attrs);
- std::unique_ptr<AST::CallExpr>
+ tl::expected<std::unique_ptr<AST::CallExpr>, Parse::Error::Expr>
parse_struct_expr_tuple_partial (AST::PathInExpression path,
AST::AttrVec outer_attrs);
- std::unique_ptr<AST::ClosureExpr>
+ tl::expected<std::unique_ptr<AST::ClosureExpr>, Parse::Error::Expr>
parse_closure_expr_pratt (const_TokenPtr tok,
AST::AttrVec outer_attrs = AST::AttrVec ());
std::unique_ptr<AST::TupleIndexExpr> parse_tuple_index_expr_float (
// When given a pratt_parsed_loc, use it as the location of the
// first token parsed in the expression (the parsing of that first
// token should be skipped).
- std::unique_ptr<AST::IfExpr>
+ tl::expected<std::unique_ptr<AST::IfExpr>, Parse::Error::Node>
parse_if_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::IfLetExpr>
+ tl::expected<std::unique_ptr<AST::IfLetExpr>, Parse::Error::Node>
parse_if_let_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::LoopExpr>
+ tl::expected<std::unique_ptr<AST::LoopExpr>, Parse::Error::Node>
parse_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
tl::optional<AST::LoopLabel> label = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::WhileLoopExpr>
+ tl::expected<std::unique_ptr<AST::WhileLoopExpr>, Parse::Error::Node>
parse_while_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
tl::optional<AST::LoopLabel> label = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::WhileLetLoopExpr>
+ tl::expected<std::unique_ptr<AST::WhileLetLoopExpr>, Parse::Error::Node>
parse_while_let_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
tl::optional<AST::LoopLabel> label = tl::nullopt);
- std::unique_ptr<AST::ForLoopExpr>
+ tl::expected<std::unique_ptr<AST::ForLoopExpr>, Parse::Error::Node>
parse_for_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
tl::optional<AST::LoopLabel> label = tl::nullopt);
- std::unique_ptr<AST::MatchExpr>
+ tl::expected<std::unique_ptr<AST::MatchExpr>, Parse::Error::Node>
parse_match_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
AST::MatchArm parse_match_arm ();
std::unique_ptr<AST::Pattern> parse_match_arm_pattern (TokenId end_token_id);
- std::unique_ptr<AST::Expr> parse_labelled_loop_expr (const_TokenPtr tok,
- AST::AttrVec outer_attrs
- = AST::AttrVec ());
+ tl::expected<std::unique_ptr<AST::Expr>, Parse::Error::Node>
+ parse_labelled_loop_expr (const_TokenPtr tok,
+ AST::AttrVec outer_attrs = AST::AttrVec ());
tl::expected<AST::LoopLabel, Parse::Error::LoopLabel>
parse_loop_label (const_TokenPtr tok);
- std::unique_ptr<AST::AsyncBlockExpr>
+ tl::expected<std::unique_ptr<AST::AsyncBlockExpr>, Parse::Error::Node>
parse_async_block_expr (AST::AttrVec outer_attrs = AST::AttrVec ());
tl::expected<std::unique_ptr<AST::GroupedExpr>, Parse::Error::Node>
parse_grouped_expr (AST::AttrVec outer_attrs = AST::AttrVec ());
parse_closure_expr (AST::AttrVec outer_attrs = AST::AttrVec ());
AST::ClosureParam parse_closure_param ();
- std::unique_ptr<AST::BoxExpr> parse_box_expr (AST::AttrVec outer_attrs,
- location_t pratt_parsed_loc
- = UNKNOWN_LOCATION);
+ tl::expected<std::unique_ptr<AST::BoxExpr>, Parse::Error::Node>
+ parse_box_expr (AST::AttrVec outer_attrs,
+ location_t pratt_parsed_loc = UNKNOWN_LOCATION);
// When given a pratt_parsed_loc, use it as the location of the
// first token parsed in the expression (the parsing of that first
// token should be skipped).
- std::unique_ptr<AST::ReturnExpr>
+ tl::expected<std::unique_ptr<AST::ReturnExpr>, Parse::Error::Node>
parse_return_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::TryExpr>
+ tl::expected<std::unique_ptr<AST::TryExpr>, Parse::Error::Node>
parse_try_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::BreakExpr>
+ tl::expected<std::unique_ptr<AST::BreakExpr>, Parse::Error::Node>
parse_break_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::ContinueExpr>
parse_continue_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::UnsafeBlockExpr>
+ tl::expected<std::unique_ptr<AST::UnsafeBlockExpr>, Parse::Error::Node>
parse_unsafe_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::ArrayExpr>
+ tl::expected<std::unique_ptr<AST::ArrayExpr>, Parse::Error::Node>
parse_array_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::ExprWithoutBlock>
+ tl::expected<std::unique_ptr<AST::ExprWithoutBlock>, Parse::Error::Node>
parse_grouped_or_tuple_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- std::unique_ptr<AST::StructExprField> parse_struct_expr_field ();
+ tl::expected<std::unique_ptr<AST::StructExprField>,
+ Parse::Error::StructExprField>
+ parse_struct_expr_field ();
bool will_be_expr_with_block ();
// Type-related
std::unique_ptr<AST::Stmt> parse_expr_stmt (AST::AttrVec outer_attrs,
ParseRestrictions restrictions
= ParseRestrictions ());
- ExprOrStmt parse_stmt_or_expr ();
+ tl::expected<ExprOrStmt, Parse::Error::Node> parse_stmt_or_expr ();
// Pattern-related
std::unique_ptr<AST::Pattern> parse_literal_or_range_pattern ();