mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 11:51:04 +01:00
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:
@@ -22,10 +22,15 @@ static void AddIntrinsics(Nonnull<Arena*> arena,
|
||||
source_loc, "format_str",
|
||||
arena->New<ExpressionPattern>(
|
||||
arena->New<StringTypeLiteral>(source_loc)))};
|
||||
auto print_return = arena->New<Return>(
|
||||
auto print_return = arena->New<Block>(
|
||||
source_loc,
|
||||
arena->New<IntrinsicExpression>(IntrinsicExpression::Intrinsic::Print),
|
||||
false);
|
||||
arena->New<Sequence>(
|
||||
source_loc,
|
||||
arena->New<Return>(source_loc,
|
||||
arena->New<IntrinsicExpression>(
|
||||
IntrinsicExpression::Intrinsic::Print),
|
||||
false),
|
||||
std::nullopt));
|
||||
auto print = arena->New<FunctionDeclaration>(
|
||||
source_loc, "Print", std::vector<GenericBinding>(),
|
||||
arena->New<TuplePattern>(source_loc, print_params),
|
||||
|
||||
@@ -859,9 +859,9 @@ auto Interpreter::StepStmt() -> Transition {
|
||||
case Statement::Kind::Block: {
|
||||
if (act->pos() == 0) {
|
||||
const Block& block = cast<Block>(stmt);
|
||||
if (block.statement()) {
|
||||
if (block.sequence()) {
|
||||
act->StartScope(Scope(CurrentEnv()));
|
||||
return Spawn{arena_->New<StatementAction>(*block.statement())};
|
||||
return Spawn{arena_->New<StatementAction>(*block.sequence())};
|
||||
} else {
|
||||
return Done{};
|
||||
}
|
||||
@@ -937,13 +937,13 @@ auto Interpreter::StepStmt() -> Transition {
|
||||
// S, H}
|
||||
// -> { { then_stmt :: C, E, F } :: S, H}
|
||||
return Delegate{
|
||||
arena_->New<StatementAction>(&cast<If>(stmt).then_statement())};
|
||||
} else if (cast<If>(stmt).else_statement()) {
|
||||
arena_->New<StatementAction>(&cast<If>(stmt).then_block())};
|
||||
} else if (cast<If>(stmt).else_block()) {
|
||||
// { {false :: if ([]) then_stmt else else_stmt :: C, E, F} ::
|
||||
// S, H}
|
||||
// -> { { else_stmt :: C, E, F } :: S, H}
|
||||
return Delegate{
|
||||
arena_->New<StatementAction>(*cast<If>(stmt).else_statement())};
|
||||
arena_->New<StatementAction>(*cast<If>(stmt).else_block())};
|
||||
} else {
|
||||
return Done{};
|
||||
}
|
||||
|
||||
@@ -45,9 +45,9 @@ static void ResolveControlFlow(
|
||||
return;
|
||||
case Statement::Kind::If: {
|
||||
auto& if_stmt = cast<If>(*statement);
|
||||
ResolveControlFlow(&if_stmt.then_statement(), function, loop);
|
||||
if (if_stmt.else_statement().has_value()) {
|
||||
ResolveControlFlow(*if_stmt.else_statement(), function, loop);
|
||||
ResolveControlFlow(&if_stmt.then_block(), function, loop);
|
||||
if (if_stmt.else_block().has_value()) {
|
||||
ResolveControlFlow(*if_stmt.else_block(), function, loop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -61,8 +61,8 @@ static void ResolveControlFlow(
|
||||
}
|
||||
case Statement::Kind::Block: {
|
||||
auto& block = cast<Block>(*statement);
|
||||
if (block.statement().has_value()) {
|
||||
ResolveControlFlow(*block.statement(), function, loop);
|
||||
if (block.sequence().has_value()) {
|
||||
ResolveControlFlow(*block.sequence(), function, loop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -868,8 +868,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
||||
return TCResult(types);
|
||||
case Statement::Kind::Block: {
|
||||
auto& block = cast<Block>(*s);
|
||||
if (block.statement()) {
|
||||
TypeCheckStmt(*block.statement(), types, values, return_type_context);
|
||||
if (block.sequence()) {
|
||||
TypeCheckStmt(*block.sequence(), types, values, return_type_context);
|
||||
return TCResult(types);
|
||||
} else {
|
||||
return TCResult(types);
|
||||
@@ -911,10 +911,9 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
||||
TypeCheckExp(&if_stmt.condition(), types, values);
|
||||
ExpectType(s->source_loc(), "condition of `if`", arena_->New<BoolType>(),
|
||||
&if_stmt.condition().static_type());
|
||||
TypeCheckStmt(&if_stmt.then_statement(), types, values,
|
||||
return_type_context);
|
||||
if (if_stmt.else_statement()) {
|
||||
TypeCheckStmt(*if_stmt.else_statement(), types, values,
|
||||
TypeCheckStmt(&if_stmt.then_block(), types, values, return_type_context);
|
||||
if (if_stmt.else_block()) {
|
||||
TypeCheckStmt(*if_stmt.else_block(), types, values,
|
||||
return_type_context);
|
||||
}
|
||||
return TCResult(types);
|
||||
@@ -1005,13 +1004,12 @@ void TypeChecker::ExpectReturnOnAllPaths(
|
||||
return;
|
||||
}
|
||||
case Statement::Kind::Block:
|
||||
ExpectReturnOnAllPaths(cast<Block>(*stmt).statement(),
|
||||
stmt->source_loc());
|
||||
ExpectReturnOnAllPaths(cast<Block>(*stmt).sequence(), stmt->source_loc());
|
||||
return;
|
||||
case Statement::Kind::If: {
|
||||
auto& if_stmt = cast<If>(*stmt);
|
||||
ExpectReturnOnAllPaths(&if_stmt.then_statement(), stmt->source_loc());
|
||||
ExpectReturnOnAllPaths(if_stmt.else_statement(), stmt->source_loc());
|
||||
ExpectReturnOnAllPaths(&if_stmt.then_block(), stmt->source_loc());
|
||||
ExpectReturnOnAllPaths(if_stmt.else_block(), stmt->source_loc());
|
||||
return;
|
||||
}
|
||||
case Statement::Kind::Return:
|
||||
|
||||
Reference in New Issue
Block a user