Convert Statement to use Ptr (#788)

Note this makes a few cases where the Statement was optional explicit (Block, If, Sequence). I do add a few CHECKs around where statements were optional and assumed but unverified.

I switch TypeCheckStmt to not take an optional Statement because I think it makes the call sites clearer in behavior. It's also a smaller change than the converse, because taking an optional Statement means the returned statement would also need to be optional. Arguably a wrapper for optional statements could be added, but this still seems cleaner to me, and there aren't that many cases of an optional statement.

Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
Jon Meow
2021-08-30 14:41:14 -07:00
committed by GitHub
co-authored by Geoff Romer
parent ed2d171703
commit 36ed79dc25
12 changed files with 166 additions and 138 deletions
+28 -28
View File
@@ -101,12 +101,12 @@ void Carbon::Parser::error(const location_type&, const std::string& message) {
%type <BisonWrap<Ptr<const FunctionDefinition>>> function_declaration
%type <BisonWrap<Ptr<const FunctionDefinition>>> function_definition
%type <std::list<Ptr<const Declaration>>> declaration_list
%type <const Statement*> statement
%type <const Statement*> if_statement
%type <const Statement*> optional_else
%type <BisonWrap<Ptr<const Statement>>> statement
%type <BisonWrap<Ptr<const Statement>>> if_statement
%type <std::optional<Ptr<const Statement>>> optional_else
%type <BisonWrap<std::pair<Ptr<const Expression>, bool>>> return_expression
%type <const Statement*> block
%type <const Statement*> statement_list
%type <BisonWrap<Ptr<const Statement>>> block
%type <std::optional<Ptr<const Statement>>> statement_list
%type <BisonWrap<Ptr<const Expression>>> expression
%type <BisonWrap<GenericBinding>> generic_binding
%type <std::vector<GenericBinding>> deduced_params
@@ -131,8 +131,8 @@ void Carbon::Parser::error(const location_type&, const std::string& message) {
%type <ParenContents<Pattern>> paren_pattern_contents
%type <BisonWrap<std::pair<std::string, Ptr<const Expression>>>> alternative
%type <std::list<std::pair<std::string, Ptr<const Expression>>>> alternative_list
%type <std::pair<Ptr<const Pattern>, const Statement*>*> clause
%type <std::list<std::pair<Ptr<const Pattern>, const Statement*>>*> clause_list
%type <std::pair<Ptr<const Pattern>, Ptr<const Statement>>*> clause
%type <std::list<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>*> clause_list
%token END_OF_FILE 0
%token AND
%token OR
@@ -408,61 +408,61 @@ maybe_empty_tuple_pattern:
;
clause:
CASE pattern DBLARROW statement
{ $$ = global_arena->RawNew<std::pair<Ptr<const Pattern>, const Statement*>>($2, $4); }
{ $$ = global_arena->RawNew<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>($2, $4); }
| DEFAULT DBLARROW statement
{
auto vp = global_arena->New<BindingPattern>(
context.SourceLoc(), std::nullopt, global_arena->New<AutoPattern>(context.SourceLoc()));
$$ = global_arena->RawNew<std::pair<Ptr<const Pattern>, const Statement*>>(vp, $3);
$$ = global_arena->RawNew<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>(vp, $3);
}
;
clause_list:
// Empty
{
$$ = global_arena->RawNew<std::list<
std::pair<Ptr<const Pattern>, const Statement*>>>();
std::pair<Ptr<const Pattern>, Ptr<const Statement>>>>();
}
| clause clause_list
{ $$ = $2; $$->push_front(*$1); }
;
statement:
expression "=" expression ";"
{ $$ = global_arena->RawNew<Assign>(context.SourceLoc(), $1, $3); }
{ $$ = global_arena->New<Assign>(context.SourceLoc(), $1, $3); }
| VAR pattern "=" expression ";"
{ $$ = global_arena->RawNew<VariableDefinition>(context.SourceLoc(), $2, $4); }
{ $$ = global_arena->New<VariableDefinition>(context.SourceLoc(), $2, $4); }
| expression ";"
{ $$ = global_arena->RawNew<ExpressionStatement>(context.SourceLoc(), $1); }
{ $$ = global_arena->New<ExpressionStatement>(context.SourceLoc(), $1); }
| if_statement
{ $$ = $1; }
| WHILE "(" expression ")" block
{ $$ = global_arena->RawNew<While>(context.SourceLoc(), $3, $5); }
{ $$ = global_arena->New<While>(context.SourceLoc(), $3, $5); }
| BREAK ";"
{ $$ = global_arena->RawNew<Break>(context.SourceLoc()); }
{ $$ = global_arena->New<Break>(context.SourceLoc()); }
| CONTINUE ";"
{ $$ = global_arena->RawNew<Continue>(context.SourceLoc()); }
{ $$ = global_arena->New<Continue>(context.SourceLoc()); }
| RETURN return_expression ";"
{
auto [return_exp, is_omitted_exp] = $2.Release();
$$ = global_arena->RawNew<Return>(context.SourceLoc(), return_exp, is_omitted_exp);
$$ = global_arena->New<Return>(context.SourceLoc(), return_exp, is_omitted_exp);
}
| block
{ $$ = $1; }
| MATCH "(" expression ")" "{" clause_list "}"
{ $$ = global_arena->RawNew<Match>(context.SourceLoc(), $3, $6); }
{ $$ = global_arena->New<Match>(context.SourceLoc(), $3, $6); }
| CONTINUATION identifier statement
{ $$ = global_arena->RawNew<Continuation>(context.SourceLoc(), $2, $3); }
{ $$ = global_arena->New<Continuation>(context.SourceLoc(), $2, $3); }
| RUN expression ";"
{ $$ = global_arena->RawNew<Run>(context.SourceLoc(), $2); }
{ $$ = global_arena->New<Run>(context.SourceLoc(), $2); }
| AWAIT ";"
{ $$ = global_arena->RawNew<Await>(context.SourceLoc()); }
{ $$ = global_arena->New<Await>(context.SourceLoc()); }
;
if_statement:
IF "(" expression ")" block optional_else
{ $$ = global_arena->RawNew<If>(context.SourceLoc(), $3, $5, $6); }
{ $$ = global_arena->New<If>(context.SourceLoc(), $3, $5, $6); }
;
optional_else:
// Empty
{ $$ = 0; }
{ $$ = std::nullopt; }
| ELSE if_statement
{ $$ = $2; }
| ELSE block
@@ -476,13 +476,13 @@ return_expression:
;
statement_list:
// Empty
{ $$ = 0; }
{ $$ = std::nullopt; }
| statement statement_list
{ $$ = global_arena->RawNew<Sequence>(context.SourceLoc(), $1, $2); }
{ $$ = global_arena->New<Sequence>(context.SourceLoc(), $1, $2); }
;
block:
"{" statement_list "}"
{ $$ = global_arena->RawNew<Block>(context.SourceLoc(), $2); }
{ $$ = global_arena->New<Block>(context.SourceLoc(), $2); }
;
return_type:
// Empty
@@ -532,7 +532,7 @@ function_definition:
$$ = global_arena->New<FunctionDefinition>(
context.SourceLoc(), $2, $3, $4,
global_arena->New<AutoPattern>(context.SourceLoc()), true,
global_arena->RawNew<Return>(context.SourceLoc(), $6, true));
global_arena->New<Return>(context.SourceLoc(), $6, true));
}
;
function_declaration:
@@ -542,7 +542,7 @@ function_declaration:
$$ = global_arena->New<FunctionDefinition>(
context.SourceLoc(), $2, $3, $4,
global_arena->New<ExpressionPattern>(return_exp),
is_omitted_exp, nullptr);
is_omitted_exp, std::nullopt);
}
;
variable_declaration: identifier ":" pattern
@@ -22,11 +22,11 @@ static void AddIntrinsics(std::list<Ptr<const Declaration>>* fs) {
loc, "format_str",
global_arena->New<ExpressionPattern>(
global_arena->New<StringTypeLiteral>(loc))))};
auto* print_return = global_arena->RawNew<Return>(
loc,
global_arena->New<IntrinsicExpression>(
IntrinsicExpression::IntrinsicKind::Print),
false);
auto print_return =
global_arena->New<Return>(loc,
global_arena->New<IntrinsicExpression>(
IntrinsicExpression::IntrinsicKind::Print),
false);
auto print = global_arena->New<FunctionDeclaration>(
global_arena->New<FunctionDefinition>(
loc, "Print", std::vector<GenericBinding>(),