Be more explicit about AST types (#921)

This was born out of wanting FunctionDeclaration to explicitly have a Block for a body, and became a bit more of specifying types around. Note this forces exec_program to generate a Block for print()'s body, which is probably more correct as now we can expect a standard FunctionDeclaration AST structure, even for the built-ins.

There is a syntactic change here: a continuation's body is now a Block, not just a Statement. I've added an example disallowed test case. I think this is more reasonable syntax.

Other than that, note that optional_else now generates a valid Block. This has me thinking about whether we can eliminate Sequence, but that seemed well out of scope for this.
This commit is contained in:
Jon Meow
2021-10-28 13:54:45 -07:00
committed by GitHub
parent dea277d8e1
commit bbd4940e6d
11 changed files with 143 additions and 122 deletions
+15 -11
View File
@@ -101,13 +101,13 @@
%type <Nonnull<FunctionDeclaration*>> function_declaration
%type <std::vector<Nonnull<Declaration*>>> declaration_list
%type <Nonnull<Statement*>> statement
%type <Nonnull<Statement*>> if_statement
%type <std::optional<Nonnull<Statement*>>> optional_else
%type <Nonnull<If*>> if_statement
%type <std::optional<Nonnull<Block*>>> optional_else
%type <std::pair<Nonnull<Expression*>, bool>> return_expression
%type <Nonnull<Statement*>> nonempty_block
%type <Nonnull<Statement*>> block
%type <Nonnull<Statement*>> nonempty_statement_list
%type <std::optional<Nonnull<Statement*>>> statement_list
%type <Nonnull<Block*>> nonempty_block
%type <Nonnull<Block*>> block
%type <Nonnull<Sequence*>> nonempty_statement_list
%type <std::optional<Nonnull<Sequence*>>> statement_list
%type <Nonnull<Expression*>> expression
%type <GenericBinding> generic_binding
%type <std::vector<GenericBinding>> deduced_params
@@ -116,11 +116,11 @@
%type <Nonnull<Pattern*>> non_expression_pattern
%type <std::pair<Nonnull<Expression*>, bool>> return_type
%type <Nonnull<Expression*>> paren_expression
%type <Nonnull<Expression*>> struct_literal
%type <Nonnull<StructLiteral*>> struct_literal
%type <std::vector<FieldInitializer>> struct_literal_contents
%type <Nonnull<Expression*>> struct_type_literal
%type <Nonnull<StructTypeLiteral*>> struct_type_literal
%type <std::vector<FieldInitializer>> struct_type_literal_contents
%type <Nonnull<Expression*>> tuple
%type <Nonnull<TupleLiteral*>> tuple
%type <std::optional<std::string>> binding_lhs
%type <Nonnull<BindingPattern*>> variable_declaration
%type <Nonnull<Member*>> member
@@ -577,7 +577,7 @@ statement:
| MATCH LEFT_PARENTHESIS expression RIGHT_PARENTHESIS LEFT_CURLY_BRACE
clause_list RIGHT_CURLY_BRACE
{ $$ = arena->New<Match>(context.source_loc(), $3, $6); }
| CONTINUATION identifier statement
| CONTINUATION identifier block
{ $$ = arena->New<Continuation>(context.source_loc(), $2, $3); }
| RUN expression SEMICOLON
{ $$ = arena->New<Run>(context.source_loc(), $2); }
@@ -592,7 +592,11 @@ optional_else:
// Empty
{ $$ = std::nullopt; }
| ELSE if_statement
{ $$ = $2; }
{
$$ = arena->New<Block>(
context.source_loc(),
arena->New<Sequence>(context.source_loc(), $2, std::nullopt));
}
| ELSE block
{ $$ = $2; }
;