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
@@ -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{};
}