mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 06:44:46 +01:00
Define a base class for all AST nodes. (#947)
Also implement code-generation to manage the resulting boilerplate.
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user