mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 14:51:06 +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();
|
||||
|
||||
Reference in New Issue
Block a user