Define a base class for all AST nodes. (#947)

Also implement code-generation to manage the resulting boilerplate.
This commit is contained in:
Geoff Romer
2021-11-16 11:54:47 -08:00
committed by GitHub
parent d854fb93cb
commit 7a5b8434c8
24 changed files with 965 additions and 543 deletions
@@ -34,7 +34,7 @@ static void ResolveControlFlow(Nonnull<Statement*> statement,
std::optional<Nonnull<const Statement*>> loop,
std::optional<Nonnull<FunctionData*>> function) {
switch (statement->kind()) {
case Statement::Kind::Return: {
case StatementKind::Return: {
if (!function.has_value()) {
FATAL_COMPILATION_ERROR(statement->source_loc())
<< "return is not within a function body";
@@ -58,21 +58,21 @@ static void ResolveControlFlow(Nonnull<Statement*> statement,
}
return;
}
case Statement::Kind::Break:
case StatementKind::Break:
if (!loop.has_value()) {
FATAL_COMPILATION_ERROR(statement->source_loc())
<< "break is not within a loop body";
}
cast<Break>(*statement).set_loop(*loop);
return;
case Statement::Kind::Continue:
case StatementKind::Continue:
if (!loop.has_value()) {
FATAL_COMPILATION_ERROR(statement->source_loc())
<< "continue is not within a loop body";
}
cast<Continue>(*statement).set_loop(*loop);
return;
case Statement::Kind::If: {
case StatementKind::If: {
auto& if_stmt = cast<If>(*statement);
ResolveControlFlow(&if_stmt.then_block(), loop, function);
if (if_stmt.else_block().has_value()) {
@@ -80,39 +80,39 @@ static void ResolveControlFlow(Nonnull<Statement*> statement,
}
return;
}
case Statement::Kind::Block: {
case StatementKind::Block: {
auto& block = cast<Block>(*statement);
for (auto* block_statement : block.statements()) {
ResolveControlFlow(block_statement, loop, function);
}
return;
}
case Statement::Kind::While:
case StatementKind::While:
ResolveControlFlow(&cast<While>(*statement).body(), statement, function);
return;
case Statement::Kind::Match: {
case StatementKind::Match: {
auto& match = cast<Match>(*statement);
for (Match::Clause& clause : match.clauses()) {
ResolveControlFlow(&clause.statement(), loop, function);
}
return;
}
case Statement::Kind::Continuation:
case StatementKind::Continuation:
ResolveControlFlow(&cast<Continuation>(*statement).body(), std::nullopt,
std::nullopt);
return;
case Statement::Kind::ExpressionStatement:
case Statement::Kind::Assign:
case Statement::Kind::VariableDefinition:
case Statement::Kind::Run:
case Statement::Kind::Await:
case StatementKind::ExpressionStatement:
case StatementKind::Assign:
case StatementKind::VariableDefinition:
case StatementKind::Run:
case StatementKind::Await:
return;
}
}
void ResolveControlFlow(AST& ast) {
for (auto declaration : ast.declarations) {
if (declaration->kind() != Declaration::Kind::FunctionDeclaration) {
if (declaration->kind() != DeclarationKind::FunctionDeclaration) {
continue;
}
auto& function = cast<FunctionDeclaration>(*declaration);