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
@@ -111,7 +111,7 @@ auto Interpreter::EvalPrim(Operator op,
void Interpreter::InitEnv(const Declaration& d, Env* env) {
switch (d.kind()) {
case Declaration::Kind::FunctionDeclaration: {
case DeclarationKind::FunctionDeclaration: {
const auto& func_def = cast<FunctionDeclaration>(d);
Env new_env = *env;
// Bring the deduced parameters into scope.
@@ -127,13 +127,13 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
break;
}
case Declaration::Kind::ClassDeclaration: {
case DeclarationKind::ClassDeclaration: {
const auto& class_decl = cast<ClassDeclaration>(d);
std::vector<NamedValue> fields;
std::vector<NamedValue> methods;
for (Nonnull<const Member*> m : class_decl.members()) {
switch (m->kind()) {
case Member::Kind::FieldMember: {
case MemberKind::FieldMember: {
const BindingPattern& binding = cast<FieldMember>(*m).binding();
const Expression& type_expression =
cast<ExpressionPattern>(binding.type()).expression();
@@ -150,10 +150,10 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
break;
}
case Declaration::Kind::ChoiceDeclaration: {
case DeclarationKind::ChoiceDeclaration: {
const auto& choice = cast<ChoiceDeclaration>(d);
std::vector<NamedValue> alts;
for (Nonnull<const ChoiceDeclaration::Alternative*> alternative :
for (Nonnull<const AlternativeSignature*> alternative :
choice.alternatives()) {
auto t = InterpExp(Env(arena_), &alternative->signature());
alts.push_back({.name = alternative->name(), .value = t});
@@ -164,7 +164,7 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
break;
}
case Declaration::Kind::VariableDeclaration: {
case DeclarationKind::VariableDeclaration: {
const auto& var = cast<VariableDeclaration>(d);
// Adds an entry in `globals` mapping the variable's name to the
// result of evaluating the initializer.
@@ -363,7 +363,7 @@ auto Interpreter::StepLvalue() -> Transition {
<< ") --->\n";
}
switch (exp.kind()) {
case Expression::Kind::IdentifierExpression: {
case ExpressionKind::IdentifierExpression: {
// { {x :: C, E, F} :: S, H}
// -> { {E(x) :: C, E, F} :: S, H}
Address pointer =
@@ -371,7 +371,7 @@ auto Interpreter::StepLvalue() -> Transition {
Nonnull<const Value*> v = arena_->New<PointerValue>(pointer);
return Done{v};
}
case Expression::Kind::FieldAccessExpression: {
case ExpressionKind::FieldAccessExpression: {
if (act.pos() == 0) {
// { {e.f :: C, E, F} :: S, H}
// -> { e :: [].f :: C, E, F} :: S, H}
@@ -386,7 +386,7 @@ auto Interpreter::StepLvalue() -> Transition {
return Done{arena_->New<PointerValue>(field)};
}
}
case Expression::Kind::IndexExpression: {
case ExpressionKind::IndexExpression: {
if (act.pos() == 0) {
// { {e[i] :: C, E, F} :: S, H}
// -> { e :: [][i] :: C, E, F} :: S, H}
@@ -406,7 +406,7 @@ auto Interpreter::StepLvalue() -> Transition {
return Done{arena_->New<PointerValue>(field)};
}
}
case Expression::Kind::TupleLiteral: {
case ExpressionKind::TupleLiteral: {
if (act.pos() <
static_cast<int>(cast<TupleLiteral>(exp).fields().size())) {
// { { vk :: (f1=v1,..., fk=[],fk+1=ek+1,...) :: C, E, F} :: S,
@@ -419,20 +419,20 @@ auto Interpreter::StepLvalue() -> Transition {
return Done{arena_->New<TupleValue>(act.results())};
}
}
case Expression::Kind::StructLiteral:
case Expression::Kind::StructTypeLiteral:
case Expression::Kind::IntLiteral:
case Expression::Kind::BoolLiteral:
case Expression::Kind::CallExpression:
case Expression::Kind::PrimitiveOperatorExpression:
case Expression::Kind::IntTypeLiteral:
case Expression::Kind::BoolTypeLiteral:
case Expression::Kind::TypeTypeLiteral:
case Expression::Kind::FunctionTypeLiteral:
case Expression::Kind::ContinuationTypeLiteral:
case Expression::Kind::StringLiteral:
case Expression::Kind::StringTypeLiteral:
case Expression::Kind::IntrinsicExpression:
case ExpressionKind::StructLiteral:
case ExpressionKind::StructTypeLiteral:
case ExpressionKind::IntLiteral:
case ExpressionKind::BoolLiteral:
case ExpressionKind::CallExpression:
case ExpressionKind::PrimitiveOperatorExpression:
case ExpressionKind::IntTypeLiteral:
case ExpressionKind::BoolTypeLiteral:
case ExpressionKind::TypeTypeLiteral:
case ExpressionKind::FunctionTypeLiteral:
case ExpressionKind::ContinuationTypeLiteral:
case ExpressionKind::StringLiteral:
case ExpressionKind::StringTypeLiteral:
case ExpressionKind::IntrinsicExpression:
FATAL_RUNTIME_ERROR_NO_LINE()
<< "Can't treat expression as lvalue: " << exp;
}
@@ -513,7 +513,7 @@ auto Interpreter::StepExp() -> Transition {
<< ") --->\n";
}
switch (exp.kind()) {
case Expression::Kind::IndexExpression: {
case ExpressionKind::IndexExpression: {
if (act.pos() == 0) {
// { { e[i] :: C, E, F} :: S, H}
// -> { { e :: [][i] :: C, E, F} :: S, H}
@@ -534,7 +534,7 @@ auto Interpreter::StepExp() -> Transition {
return Done{tuple.elements()[i]};
}
}
case Expression::Kind::TupleLiteral: {
case ExpressionKind::TupleLiteral: {
if (act.pos() <
static_cast<int>(cast<TupleLiteral>(exp).fields().size())) {
// { { vk :: (f1=v1,..., fk=[],fk+1=ek+1,...) :: C, E, F} :: S,
@@ -547,7 +547,7 @@ auto Interpreter::StepExp() -> Transition {
return Done{arena_->New<TupleValue>(act.results())};
}
}
case Expression::Kind::StructLiteral: {
case ExpressionKind::StructLiteral: {
const auto& literal = cast<StructLiteral>(exp);
if (act.pos() < static_cast<int>(literal.fields().size())) {
return Spawn{std::make_unique<ExpressionAction>(
@@ -556,7 +556,7 @@ auto Interpreter::StepExp() -> Transition {
return Done{CreateStruct(literal.fields(), act.results())};
}
}
case Expression::Kind::StructTypeLiteral: {
case ExpressionKind::StructTypeLiteral: {
const auto& struct_type = cast<StructTypeLiteral>(exp);
if (act.pos() < static_cast<int>(struct_type.fields().size())) {
return Spawn{std::make_unique<ExpressionAction>(
@@ -569,7 +569,7 @@ auto Interpreter::StepExp() -> Transition {
return Done{arena_->New<StructType>(std::move(fields))};
}
}
case Expression::Kind::FieldAccessExpression: {
case ExpressionKind::FieldAccessExpression: {
const auto& access = cast<FieldAccessExpression>(exp);
if (act.pos() == 0) {
// { { e.f :: C, E, F} :: S, H}
@@ -582,22 +582,22 @@ auto Interpreter::StepExp() -> Transition {
arena_, FieldPath(access.field()), exp.source_loc())};
}
}
case Expression::Kind::IdentifierExpression: {
case ExpressionKind::IdentifierExpression: {
CHECK(act.pos() == 0);
const auto& ident = cast<IdentifierExpression>(exp);
// { {x :: C, E, F} :: S, H} -> { {H(E(x)) :: C, E, F} :: S, H}
Address pointer = GetFromEnv(exp.source_loc(), ident.name());
return Done{heap_.Read(pointer, exp.source_loc())};
}
case Expression::Kind::IntLiteral:
case ExpressionKind::IntLiteral:
CHECK(act.pos() == 0);
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
return Done{arena_->New<IntValue>(cast<IntLiteral>(exp).value())};
case Expression::Kind::BoolLiteral:
case ExpressionKind::BoolLiteral:
CHECK(act.pos() == 0);
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
return Done{arena_->New<BoolValue>(cast<BoolLiteral>(exp).value())};
case Expression::Kind::PrimitiveOperatorExpression: {
case ExpressionKind::PrimitiveOperatorExpression: {
const auto& op = cast<PrimitiveOperatorExpression>(exp);
if (act.pos() != static_cast<int>(op.arguments().size())) {
// { {v :: op(vs,[],e,es) :: C, E, F} :: S, H}
@@ -610,7 +610,7 @@ auto Interpreter::StepExp() -> Transition {
return Done{EvalPrim(op.op(), act.results(), exp.source_loc())};
}
}
case Expression::Kind::CallExpression:
case ExpressionKind::CallExpression:
if (act.pos() == 0) {
// { {e1(e2) :: C, E, F} :: S, H}
// -> { {e1 :: [](e2) :: C, E, F} :: S, H}
@@ -651,7 +651,7 @@ auto Interpreter::StepExp() -> Transition {
} else {
FATAL() << "in handle_value with Call pos " << act.pos();
}
case Expression::Kind::IntrinsicExpression:
case ExpressionKind::IntrinsicExpression:
CHECK(act.pos() == 0);
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
switch (cast<IntrinsicExpression>(exp).intrinsic()) {
@@ -664,19 +664,19 @@ auto Interpreter::StepExp() -> Transition {
return Done{TupleValue::Empty()};
}
case Expression::Kind::IntTypeLiteral: {
case ExpressionKind::IntTypeLiteral: {
CHECK(act.pos() == 0);
return Done{arena_->New<IntType>()};
}
case Expression::Kind::BoolTypeLiteral: {
case ExpressionKind::BoolTypeLiteral: {
CHECK(act.pos() == 0);
return Done{arena_->New<BoolType>()};
}
case Expression::Kind::TypeTypeLiteral: {
case ExpressionKind::TypeTypeLiteral: {
CHECK(act.pos() == 0);
return Done{arena_->New<TypeType>()};
}
case Expression::Kind::FunctionTypeLiteral: {
case ExpressionKind::FunctionTypeLiteral: {
if (act.pos() == 0) {
return Spawn{std::make_unique<ExpressionAction>(
&cast<FunctionTypeLiteral>(exp).parameter())};
@@ -693,15 +693,15 @@ auto Interpreter::StepExp() -> Transition {
act.results()[1])};
}
}
case Expression::Kind::ContinuationTypeLiteral: {
case ExpressionKind::ContinuationTypeLiteral: {
CHECK(act.pos() == 0);
return Done{arena_->New<ContinuationType>()};
}
case Expression::Kind::StringLiteral:
case ExpressionKind::StringLiteral:
CHECK(act.pos() == 0);
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
return Done{arena_->New<StringValue>(cast<StringLiteral>(exp).value())};
case Expression::Kind::StringTypeLiteral: {
case ExpressionKind::StringTypeLiteral: {
CHECK(act.pos() == 0);
return Done{arena_->New<StringType>()};
}
@@ -716,11 +716,11 @@ auto Interpreter::StepPattern() -> Transition {
<< pattern.source_loc() << ") --->\n";
}
switch (pattern.kind()) {
case Pattern::Kind::AutoPattern: {
case PatternKind::AutoPattern: {
CHECK(act.pos() == 0);
return Done{arena_->New<AutoType>()};
}
case Pattern::Kind::BindingPattern: {
case PatternKind::BindingPattern: {
const auto& binding = cast<BindingPattern>(pattern);
if (act.pos() == 0) {
return Spawn{std::make_unique<PatternAction>(&binding.type())};
@@ -729,7 +729,7 @@ auto Interpreter::StepPattern() -> Transition {
act.results()[0])};
}
}
case Pattern::Kind::TuplePattern: {
case PatternKind::TuplePattern: {
const auto& tuple = cast<TuplePattern>(pattern);
if (act.pos() < static_cast<int>(tuple.fields().size())) {
// { { vk :: (f1=v1,..., fk=[],fk+1=ek+1,...) :: C, E, F} :: S,
@@ -742,7 +742,7 @@ auto Interpreter::StepPattern() -> Transition {
return Done{arena_->New<TupleValue>(act.results())};
}
}
case Pattern::Kind::AlternativePattern: {
case PatternKind::AlternativePattern: {
const auto& alternative = cast<AlternativePattern>(pattern);
if (act.pos() == 0) {
return Spawn{
@@ -757,7 +757,7 @@ auto Interpreter::StepPattern() -> Transition {
act.results()[1])};
}
}
case Pattern::Kind::ExpressionPattern:
case PatternKind::ExpressionPattern:
return Delegate{std::make_unique<ExpressionAction>(
&cast<ExpressionPattern>(pattern).expression())};
}
@@ -777,7 +777,7 @@ auto Interpreter::StepStmt() -> Transition {
llvm::outs() << " (" << stmt.source_loc() << ") --->\n";
}
switch (stmt.kind()) {
case Statement::Kind::Match: {
case StatementKind::Match: {
const auto& match_stmt = cast<Match>(stmt);
if (act.pos() == 0) {
// { { (match (e) ...) :: C, E, F} :: S, H}
@@ -808,7 +808,7 @@ auto Interpreter::StepStmt() -> Transition {
}
}
}
case Statement::Kind::While:
case StatementKind::While:
if (act.pos() % 2 == 0) {
// { { (while (e) s) :: C, E, F} :: S, H}
// -> { { e :: (while ([]) s) :: C, E, F} :: S, H}
@@ -829,19 +829,19 @@ auto Interpreter::StepStmt() -> Transition {
return Done{};
}
}
case Statement::Kind::Break: {
case StatementKind::Break: {
CHECK(act.pos() == 0);
// { { break; :: ... :: (while (e) s) :: C, E, F} :: S, H}
// -> { { C, E', F} :: S, H}
return UnwindPast{.ast_node = &cast<Break>(stmt).loop()};
}
case Statement::Kind::Continue: {
case StatementKind::Continue: {
CHECK(act.pos() == 0);
// { { continue; :: ... :: (while (e) s) :: C, E, F} :: S, H}
// -> { { (while (e) s) :: C, E', F} :: S, H}
return UnwindTo{.ast_node = &cast<Continue>(stmt).loop()};
}
case Statement::Kind::Block: {
case StatementKind::Block: {
const auto& block = cast<Block>(stmt);
if (act.pos() >= static_cast<int>(block.statements().size())) {
// If the position is past the end of the block, end processing. Note
@@ -857,7 +857,7 @@ auto Interpreter::StepStmt() -> Transition {
return Spawn{
std::make_unique<StatementAction>(block.statements()[act.pos()])};
}
case Statement::Kind::VariableDefinition: {
case StatementKind::VariableDefinition: {
const auto& definition = cast<VariableDefinition>(stmt);
if (act.pos() == 0) {
// { {(var x = e) :: C, E, F} :: S, H}
@@ -882,7 +882,7 @@ auto Interpreter::StepStmt() -> Transition {
return Done{};
}
}
case Statement::Kind::ExpressionStatement:
case StatementKind::ExpressionStatement:
if (act.pos() == 0) {
// { {e :: C, E, F} :: S, H}
// -> { {e :: C, E, F} :: S, H}
@@ -891,7 +891,7 @@ auto Interpreter::StepStmt() -> Transition {
} else {
return Done{};
}
case Statement::Kind::Assign: {
case StatementKind::Assign: {
const auto& assign = cast<Assign>(stmt);
if (act.pos() == 0) {
// { {(lv = e) :: C, E, F} :: S, H}
@@ -910,7 +910,7 @@ auto Interpreter::StepStmt() -> Transition {
return Done{};
}
}
case Statement::Kind::If:
case StatementKind::If:
if (act.pos() == 0) {
// { {(if (e) then_stmt else else_stmt) :: C, E, F} :: S, H}
// -> { { e :: (if ([]) then_stmt else else_stmt) :: C, E, F} :: S, H}
@@ -935,7 +935,7 @@ auto Interpreter::StepStmt() -> Transition {
return Done{};
}
}
case Statement::Kind::Return:
case StatementKind::Return:
if (act.pos() == 0) {
// { {return e :: C, E, F} :: S, H}
// -> { {e :: return [] :: C, E, F} :: S, H}
@@ -950,7 +950,7 @@ auto Interpreter::StepStmt() -> Transition {
.result = Convert(act.results()[0],
&function.return_term().static_type())};
}
case Statement::Kind::Continuation: {
case StatementKind::Continuation: {
CHECK(act.pos() == 0);
// Create a continuation object by creating a frame similar the
// way one is created in a function call.
@@ -969,7 +969,7 @@ auto Interpreter::StepStmt() -> Transition {
continuation_address);
return Done{};
}
case Statement::Kind::Run: {
case StatementKind::Run: {
auto& run = cast<Run>(stmt);
if (act.pos() == 0) {
// Evaluate the argument of the run statement.
@@ -985,7 +985,7 @@ auto Interpreter::StepStmt() -> Transition {
return Done{};
}
}
case Statement::Kind::Await:
case StatementKind::Await:
CHECK(act.pos() == 0);
// Pause the current continuation
todo_.Pop();
@@ -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);
@@ -17,27 +17,27 @@ namespace {
// flow.
void PopulateNamesInPattern(const Pattern& pattern, StaticScope& static_scope) {
switch (pattern.kind()) {
case Pattern::Kind::AlternativePattern: {
case PatternKind::AlternativePattern: {
const auto& alt = cast<AlternativePattern>(pattern);
PopulateNamesInPattern(alt.arguments(), static_scope);
break;
}
case Pattern::Kind::BindingPattern: {
case PatternKind::BindingPattern: {
const auto& binding = cast<BindingPattern>(pattern);
if (binding.name().has_value()) {
static_scope.Add(*binding.name(), &binding);
}
break;
}
case Pattern::Kind::TuplePattern: {
case PatternKind::TuplePattern: {
const auto& tuple = cast<TuplePattern>(pattern);
for (auto* field : tuple.fields()) {
PopulateNamesInPattern(*field, static_scope);
}
break;
}
case Pattern::Kind::AutoPattern:
case Pattern::Kind::ExpressionPattern:
case PatternKind::AutoPattern:
case PatternKind::ExpressionPattern:
// These don't add names.
break;
}
@@ -53,7 +53,7 @@ void PopulateNamesInStatement(Arena* arena,
}
Statement& statement = **opt_statement;
switch (statement.kind()) {
case Statement::Kind::Block: {
case StatementKind::Block: {
// Defines a new scope for names.
auto& block = cast<Block>(statement);
for (const auto& statement : block.statements()) {
@@ -61,33 +61,33 @@ void PopulateNamesInStatement(Arena* arena,
}
break;
}
case Statement::Kind::Continuation: {
case StatementKind::Continuation: {
// Defines a new name and contains a block.
auto& cont = cast<Continuation>(statement);
static_scope.Add(cont.continuation_variable(), &cont);
PopulateNamesInStatement(arena, &cont.body(), static_scope);
break;
}
case Statement::Kind::VariableDefinition: {
case StatementKind::VariableDefinition: {
// Defines a new name.
const auto& var = cast<VariableDefinition>(statement);
PopulateNamesInPattern(var.pattern(), static_scope);
break;
}
case Statement::Kind::If: {
case StatementKind::If: {
// Contains blocks.
auto& if_stmt = cast<If>(statement);
PopulateNamesInStatement(arena, &if_stmt.then_block(), static_scope);
PopulateNamesInStatement(arena, if_stmt.else_block(), static_scope);
break;
}
case Statement::Kind::While: {
case StatementKind::While: {
// Contains a block.
auto& while_stmt = cast<While>(statement);
PopulateNamesInStatement(arena, &while_stmt.body(), static_scope);
break;
}
case Statement::Kind::Match: {
case StatementKind::Match: {
// Contains blocks.
auto& match = cast<Match>(statement);
for (auto& clause : match.clauses()) {
@@ -97,13 +97,13 @@ void PopulateNamesInStatement(Arena* arena,
}
break;
}
case Statement::Kind::Assign:
case Statement::Kind::Await:
case Statement::Kind::Break:
case Statement::Kind::Continue:
case Statement::Kind::ExpressionStatement:
case Statement::Kind::Return:
case Statement::Kind::Run:
case StatementKind::Assign:
case StatementKind::Await:
case StatementKind::Break:
case StatementKind::Continue:
case StatementKind::ExpressionStatement:
case StatementKind::Return:
case StatementKind::Run:
// Neither contains names nor a scope.
break;
}
@@ -114,7 +114,7 @@ void PopulateNamesInStatement(Arena* arena,
void PopulateNamesInMember(Arena* arena, const Member& member,
StaticScope& static_scope) {
switch (member.kind()) {
case Member::Kind::FieldMember: {
case MemberKind::FieldMember: {
const auto& field = cast<FieldMember>(member);
if (field.binding().name().has_value()) {
static_scope.Add(*field.binding().name(), &member);
@@ -130,7 +130,7 @@ void PopulateNamesInMember(Arena* arena, const Member& member,
void PopulateNamesInDeclaration(Arena* arena, Declaration& declaration,
StaticScope& static_scope) {
switch (declaration.kind()) {
case Declaration::Kind::FunctionDeclaration: {
case DeclarationKind::FunctionDeclaration: {
auto& func = cast<FunctionDeclaration>(declaration);
static_scope.Add(func.name(), &declaration);
for (Nonnull<const GenericBinding*> param : func.deduced_parameters()) {
@@ -140,7 +140,7 @@ void PopulateNamesInDeclaration(Arena* arena, Declaration& declaration,
PopulateNamesInStatement(arena, func.body(), static_scope);
break;
}
case Declaration::Kind::ClassDeclaration: {
case DeclarationKind::ClassDeclaration: {
auto& class_decl = cast<ClassDeclaration>(declaration);
static_scope.Add(class_decl.name(), &declaration);
for (auto* member : class_decl.members()) {
@@ -148,11 +148,10 @@ void PopulateNamesInDeclaration(Arena* arena, Declaration& declaration,
}
break;
}
case Declaration::Kind::ChoiceDeclaration: {
case DeclarationKind::ChoiceDeclaration: {
auto& choice = cast<ChoiceDeclaration>(declaration);
static_scope.Add(choice.name(), &declaration);
for (Nonnull<const ChoiceDeclaration::Alternative*> alt :
choice.alternatives()) {
for (Nonnull<const AlternativeSignature*> alt : choice.alternatives()) {
choice.static_scope().Add(alt->name(), alt);
}
// Populate name into declared_names.
@@ -160,7 +159,7 @@ void PopulateNamesInDeclaration(Arena* arena, Declaration& declaration,
// alternatives.
break;
}
case Declaration::Kind::VariableDeclaration:
case DeclarationKind::VariableDeclaration:
auto& var = cast<VariableDeclaration>(declaration);
if (var.binding().name().has_value()) {
static_scope.Add(*(var.binding().name()), &var.binding());
@@ -177,10 +176,10 @@ void PopulateNamesInDeclaration(Arena* arena, Declaration& declaration,
void ResolveNamesInDeclaration(Declaration& declaration,
const StaticScope& static_scope) {
switch (declaration.kind()) {
case Declaration::Kind::FunctionDeclaration:
case Declaration::Kind::ClassDeclaration:
case Declaration::Kind::ChoiceDeclaration:
case Declaration::Kind::VariableDeclaration:
case DeclarationKind::FunctionDeclaration:
case DeclarationKind::ClassDeclaration:
case DeclarationKind::ChoiceDeclaration:
case DeclarationKind::VariableDeclaration:
break;
}
}
@@ -434,7 +434,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
llvm::outs() << "\n";
}
switch (e->kind()) {
case Expression::Kind::IndexExpression: {
case ExpressionKind::IndexExpression: {
auto& index = cast<IndexExpression>(*e);
auto res = TypeCheckExp(&index.aggregate(), types, values);
const Value& aggregate_type = index.aggregate().static_type();
@@ -455,7 +455,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
FATAL_COMPILATION_ERROR(e->source_loc()) << "expected a tuple";
}
}
case Expression::Kind::TupleLiteral: {
case ExpressionKind::TupleLiteral: {
std::vector<Nonnull<const Value*>> arg_types;
auto new_types = types;
for (auto& arg : cast<TupleLiteral>(*e).fields()) {
@@ -466,7 +466,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
SetStaticType(e, arena_->New<TupleValue>(std::move(arg_types)));
return TCResult(new_types);
}
case Expression::Kind::StructLiteral: {
case ExpressionKind::StructLiteral: {
std::vector<FieldInitializer> new_args;
std::vector<NamedValue> arg_types;
auto new_types = types;
@@ -479,7 +479,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
SetStaticType(e, arena_->New<StructType>(std::move(arg_types)));
return TCResult(new_types);
}
case Expression::Kind::StructTypeLiteral: {
case ExpressionKind::StructTypeLiteral: {
auto& struct_type = cast<StructTypeLiteral>(*e);
std::vector<FieldInitializer> new_args;
auto new_types = types;
@@ -501,7 +501,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
}
return TCResult(new_types);
}
case Expression::Kind::FieldAccessExpression: {
case ExpressionKind::FieldAccessExpression: {
auto& access = cast<FieldAccessExpression>(*e);
auto res = TypeCheckExp(&access.aggregate(), types, values);
const Value& aggregate_type = access.aggregate().static_type();
@@ -559,7 +559,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
<< *e;
}
}
case Expression::Kind::IdentifierExpression: {
case ExpressionKind::IdentifierExpression: {
auto& ident = cast<IdentifierExpression>(*e);
std::optional<Nonnull<const Value*>> type = types.Get(ident.name());
if (type) {
@@ -570,13 +570,13 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
<< "could not find `" << ident.name() << "`";
}
}
case Expression::Kind::IntLiteral:
case ExpressionKind::IntLiteral:
SetStaticType(e, arena_->New<IntType>());
return TCResult(types);
case Expression::Kind::BoolLiteral:
case ExpressionKind::BoolLiteral:
SetStaticType(e, arena_->New<BoolType>());
return TCResult(types);
case Expression::Kind::PrimitiveOperatorExpression: {
case ExpressionKind::PrimitiveOperatorExpression: {
auto& op = cast<PrimitiveOperatorExpression>(*e);
std::vector<Nonnull<Expression*>> es;
std::vector<Nonnull<const Value*>> ts;
@@ -647,7 +647,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
}
break;
}
case Expression::Kind::CallExpression: {
case ExpressionKind::CallExpression: {
auto& call = cast<CallExpression>(*e);
auto fun_res = TypeCheckExp(&call.function(), types, values);
switch (call.function().static_type().kind()) {
@@ -687,7 +687,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
}
break;
}
case Expression::Kind::FunctionTypeLiteral: {
case ExpressionKind::FunctionTypeLiteral: {
auto& fn = cast<FunctionTypeLiteral>(*e);
ExpectIsConcreteType(fn.parameter().source_loc(),
interpreter_.InterpExp(values, &fn.parameter()));
@@ -696,20 +696,20 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
SetStaticType(&fn, arena_->New<TypeType>());
return TCResult(types);
}
case Expression::Kind::StringLiteral:
case ExpressionKind::StringLiteral:
SetStaticType(e, arena_->New<StringType>());
return TCResult(types);
case Expression::Kind::IntrinsicExpression:
case ExpressionKind::IntrinsicExpression:
switch (cast<IntrinsicExpression>(*e).intrinsic()) {
case IntrinsicExpression::Intrinsic::Print:
SetStaticType(e, TupleValue::Empty());
return TCResult(types);
}
case Expression::Kind::IntTypeLiteral:
case Expression::Kind::BoolTypeLiteral:
case Expression::Kind::StringTypeLiteral:
case Expression::Kind::TypeTypeLiteral:
case Expression::Kind::ContinuationTypeLiteral:
case ExpressionKind::IntTypeLiteral:
case ExpressionKind::BoolTypeLiteral:
case ExpressionKind::StringTypeLiteral:
case ExpressionKind::TypeTypeLiteral:
case ExpressionKind::ContinuationTypeLiteral:
SetStaticType(e, arena_->New<TypeType>());
return TCResult(types);
}
@@ -730,11 +730,11 @@ auto TypeChecker::TypeCheckPattern(
llvm::outs() << "\n";
}
switch (p->kind()) {
case Pattern::Kind::AutoPattern: {
case PatternKind::AutoPattern: {
SetStaticType(p, arena_->New<TypeType>());
return TCResult(types);
}
case Pattern::Kind::BindingPattern: {
case PatternKind::BindingPattern: {
auto& binding = cast<BindingPattern>(*p);
TypeCheckPattern(&binding.type(), types, values, std::nullopt);
Nonnull<const Value*> type =
@@ -763,7 +763,7 @@ auto TypeChecker::TypeCheckPattern(
SetValue(&binding, interpreter_.InterpPattern(values, &binding));
return TCResult(types);
}
case Pattern::Kind::TuplePattern: {
case PatternKind::TuplePattern: {
auto& tuple = cast<TuplePattern>(*p);
std::vector<Nonnull<const Value*>> field_types;
auto new_types = types;
@@ -790,7 +790,7 @@ auto TypeChecker::TypeCheckPattern(
SetValue(&tuple, interpreter_.InterpPattern(values, &tuple));
return TCResult(new_types);
}
case Pattern::Kind::AlternativePattern: {
case PatternKind::AlternativePattern: {
auto& alternative = cast<AlternativePattern>(*p);
Nonnull<const Value*> choice_type =
interpreter_.InterpExp(values, &alternative.choice_type());
@@ -816,7 +816,7 @@ auto TypeChecker::TypeCheckPattern(
SetValue(&alternative, interpreter_.InterpPattern(values, &alternative));
return TCResult(arg_results.types);
}
case Pattern::Kind::ExpressionPattern: {
case PatternKind::ExpressionPattern: {
auto& expression = cast<ExpressionPattern>(*p).expression();
TCResult result = TypeCheckExp(&expression, types, values);
SetStaticType(p, &expression.static_type());
@@ -837,7 +837,7 @@ auto TypeChecker::TypeCheckCase(Nonnull<const Value*> expected,
auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
Env values) -> TCResult {
switch (s->kind()) {
case Statement::Kind::Match: {
case StatementKind::Match: {
auto& match = cast<Match>(*s);
TypeCheckExp(&match.expression(), types, values);
std::vector<Match::Clause> new_clauses;
@@ -848,7 +848,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
}
return TCResult(types);
}
case Statement::Kind::While: {
case StatementKind::While: {
auto& while_stmt = cast<While>(*s);
TypeCheckExp(&while_stmt.condition(), types, values);
ExpectType(s->source_loc(), "condition of `while`",
@@ -857,10 +857,10 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
TypeCheckStmt(&while_stmt.body(), types, values);
return TCResult(types);
}
case Statement::Kind::Break:
case Statement::Kind::Continue:
case StatementKind::Break:
case StatementKind::Continue:
return TCResult(types);
case Statement::Kind::Block: {
case StatementKind::Block: {
auto& block = cast<Block>(*s);
for (auto* block_statement : block.statements()) {
auto result = TypeCheckStmt(block_statement, types, values);
@@ -868,14 +868,14 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
}
return TCResult(types);
}
case Statement::Kind::VariableDefinition: {
case StatementKind::VariableDefinition: {
auto& var = cast<VariableDefinition>(*s);
TypeCheckExp(&var.init(), types, values);
const Value& rhs_ty = var.init().static_type();
auto lhs_res = TypeCheckPattern(&var.pattern(), types, values, &rhs_ty);
return TCResult(lhs_res.types);
}
case Statement::Kind::Assign: {
case StatementKind::Assign: {
auto& assign = cast<Assign>(*s);
TypeCheckExp(&assign.rhs(), types, values);
auto lhs_res = TypeCheckExp(&assign.lhs(), types, values);
@@ -883,11 +883,11 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
&assign.rhs().static_type());
return TCResult(lhs_res.types);
}
case Statement::Kind::ExpressionStatement: {
case StatementKind::ExpressionStatement: {
TypeCheckExp(&cast<ExpressionStatement>(*s).expression(), types, values);
return TCResult(types);
}
case Statement::Kind::If: {
case StatementKind::If: {
auto& if_stmt = cast<If>(*s);
TypeCheckExp(&if_stmt.condition(), types, values);
ExpectType(s->source_loc(), "condition of `if`", arena_->New<BoolType>(),
@@ -898,7 +898,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
}
return TCResult(types);
}
case Statement::Kind::Return: {
case StatementKind::Return: {
auto& ret = cast<Return>(*s);
TypeCheckExp(&ret.expression(), types, values);
ReturnTerm& return_term = ret.function().return_term();
@@ -910,13 +910,13 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
}
return TCResult(types);
}
case Statement::Kind::Continuation: {
case StatementKind::Continuation: {
auto& cont = cast<Continuation>(*s);
TypeCheckStmt(&cont.body(), types, values);
types.Set(cont.continuation_variable(), arena_->New<ContinuationType>());
return TCResult(types);
}
case Statement::Kind::Run: {
case StatementKind::Run: {
auto& run = cast<Run>(*s);
TypeCheckExp(&run.argument(), types, values);
ExpectType(s->source_loc(), "argument of `run`",
@@ -924,7 +924,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
&run.argument().static_type());
return TCResult(types);
}
case Statement::Kind::Await: {
case StatementKind::Await: {
// nothing to do here
return TCResult(types);
}
@@ -939,7 +939,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
static auto IsExhaustive(const Match& match) -> bool {
for (const Match::Clause& clause : match.clauses()) {
// A pattern consisting of a single variable binding is guaranteed to match.
if (clause.pattern().kind() == Pattern::Kind::BindingPattern) {
if (clause.pattern().kind() == PatternKind::BindingPattern) {
return true;
}
}
@@ -955,7 +955,7 @@ void TypeChecker::ExpectReturnOnAllPaths(
}
Nonnull<Statement*> stmt = *opt_stmt;
switch (stmt->kind()) {
case Statement::Kind::Match: {
case StatementKind::Match: {
auto& match = cast<Match>(*stmt);
if (!IsExhaustive(match)) {
FATAL_COMPILATION_ERROR(source_loc)
@@ -968,7 +968,7 @@ void TypeChecker::ExpectReturnOnAllPaths(
}
return;
}
case Statement::Kind::Block: {
case StatementKind::Block: {
auto& block = cast<Block>(*stmt);
if (block.statements().empty()) {
FATAL_COMPILATION_ERROR(stmt->source_loc())
@@ -979,24 +979,24 @@ void TypeChecker::ExpectReturnOnAllPaths(
block.source_loc());
return;
}
case Statement::Kind::If: {
case StatementKind::If: {
auto& if_stmt = cast<If>(*stmt);
ExpectReturnOnAllPaths(&if_stmt.then_block(), stmt->source_loc());
ExpectReturnOnAllPaths(if_stmt.else_block(), stmt->source_loc());
return;
}
case Statement::Kind::Return:
case StatementKind::Return:
return;
case Statement::Kind::Continuation:
case Statement::Kind::Run:
case Statement::Kind::Await:
case StatementKind::Continuation:
case StatementKind::Run:
case StatementKind::Await:
return;
case Statement::Kind::Assign:
case Statement::Kind::ExpressionStatement:
case Statement::Kind::While:
case Statement::Kind::Break:
case Statement::Kind::Continue:
case Statement::Kind::VariableDefinition:
case StatementKind::Assign:
case StatementKind::ExpressionStatement:
case StatementKind::While:
case StatementKind::Break:
case StatementKind::Continue:
case StatementKind::VariableDefinition:
FATAL_COMPILATION_ERROR(stmt->source_loc())
<< "control-flow reaches end of function that provides a `->` "
"return type without reaching a return statement";
@@ -1069,7 +1069,7 @@ auto TypeChecker::TypeOfClassDecl(const ClassDeclaration& class_decl,
std::vector<NamedValue> methods;
for (Nonnull<const Member*> m : class_decl.members()) {
switch (m->kind()) {
case Member::Kind::FieldMember: {
case MemberKind::FieldMember: {
const BindingPattern& binding = cast<FieldMember>(*m).binding();
if (!binding.name().has_value()) {
FATAL_COMPILATION_ERROR(binding.source_loc())
@@ -1092,13 +1092,13 @@ auto TypeChecker::TypeOfClassDecl(const ClassDeclaration& class_decl,
static auto GetName(const Declaration& d) -> const std::string& {
switch (d.kind()) {
case Declaration::Kind::FunctionDeclaration:
case DeclarationKind::FunctionDeclaration:
return cast<FunctionDeclaration>(d).name();
case Declaration::Kind::ClassDeclaration:
case DeclarationKind::ClassDeclaration:
return cast<ClassDeclaration>(d).name();
case Declaration::Kind::ChoiceDeclaration:
case DeclarationKind::ChoiceDeclaration:
return cast<ChoiceDeclaration>(d).name();
case Declaration::Kind::VariableDeclaration: {
case DeclarationKind::VariableDeclaration: {
const BindingPattern& binding = cast<VariableDeclaration>(d).binding();
if (!binding.name().has_value()) {
FATAL_COMPILATION_ERROR(binding.source_loc())
@@ -1122,19 +1122,19 @@ void TypeChecker::TypeCheckDeclaration(Nonnull<Declaration*> d,
const TypeEnv& types,
const Env& values) {
switch (d->kind()) {
case Declaration::Kind::FunctionDeclaration:
case DeclarationKind::FunctionDeclaration:
TypeCheckFunctionDeclaration(&cast<FunctionDeclaration>(*d), types,
values, /*check_body=*/true);
return;
case Declaration::Kind::ClassDeclaration:
case DeclarationKind::ClassDeclaration:
// TODO
return;
case Declaration::Kind::ChoiceDeclaration:
case DeclarationKind::ChoiceDeclaration:
// TODO
return;
case Declaration::Kind::VariableDeclaration: {
case DeclarationKind::VariableDeclaration: {
auto& var = cast<VariableDeclaration>(*d);
// Signals a type error if the initializing expression does not have
// the declared type of the variable, otherwise returns this
@@ -1159,7 +1159,7 @@ void TypeChecker::TypeCheckDeclaration(Nonnull<Declaration*> d,
void TypeChecker::TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops) {
switch (d->kind()) {
case Declaration::Kind::FunctionDeclaration: {
case DeclarationKind::FunctionDeclaration: {
auto& func_def = cast<FunctionDeclaration>(*d);
TypeCheckFunctionDeclaration(&func_def, tops->types, tops->values,
/*check_body=*/false);
@@ -1168,7 +1168,7 @@ void TypeChecker::TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops) {
break;
}
case Declaration::Kind::ClassDeclaration: {
case DeclarationKind::ClassDeclaration: {
const auto& class_decl = cast<ClassDeclaration>(*d);
auto st = TypeOfClassDecl(class_decl, tops->types, tops->values);
AllocationId a = interpreter_.AllocateValue(st);
@@ -1177,10 +1177,10 @@ void TypeChecker::TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops) {
break;
}
case Declaration::Kind::ChoiceDeclaration: {
case DeclarationKind::ChoiceDeclaration: {
const auto& choice = cast<ChoiceDeclaration>(*d);
std::vector<NamedValue> alts;
for (Nonnull<const ChoiceDeclaration::Alternative*> alternative :
for (Nonnull<const AlternativeSignature*> alternative :
choice.alternatives()) {
auto t =
interpreter_.InterpExp(tops->values, &alternative->signature());
@@ -1193,7 +1193,7 @@ void TypeChecker::TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops) {
break;
}
case Declaration::Kind::VariableDeclaration: {
case DeclarationKind::VariableDeclaration: {
auto& var = cast<VariableDeclaration>(*d);
// Associate the variable name with it's declared type in the
// compile-time symbol table.