mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-03 22:02:51 +01:00
Refactor output to be more streaming-focused. (#666)
- Switch code to llvm::raw_ostream as part of standardizing output forms.
- Preferring llvm::raw_ostream over std::ostream because other tooling code should be expected to rely on llvm more closely, and an overall preference towards library consistency.
- There are a couple spots in syntax/ that still use std streams, but I'd prefer to take a separate PR to see how best to address those.
- std::boolalpha doesn't work with llvm, so I've implemented equivalent in a couple places (not enough that it felt like worth making a helper function).
- Implement Print(ostream) as consistently as we can, as an instance member.
- This facilitates the use of the common/ostream.h template to provide operators.
- Preferring this approach so that Print is easily accessible via gdb, per suggestion on #executable-semantics.
- Switch code currently calling `type->Print(ostream)` to instead do `ostream << *type`.
- Remove the unused `PrintTypeEnv`, nothing used it and the declaration didn't match the definition.
This commit is contained in:
@@ -17,6 +17,7 @@ cc_library(
|
||||
":function_definition",
|
||||
":member",
|
||||
":struct_definition",
|
||||
"//common:ostream",
|
||||
"//executable_semantics/interpreter:address",
|
||||
"//executable_semantics/interpreter:containers",
|
||||
],
|
||||
@@ -26,7 +27,10 @@ cc_library(
|
||||
name = "expression",
|
||||
srcs = ["expression.cpp"],
|
||||
hdrs = ["expression.h"],
|
||||
deps = ["//common:indirect_value"],
|
||||
deps = [
|
||||
"//common:indirect_value",
|
||||
"//common:ostream",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -43,7 +47,10 @@ cc_library(
|
||||
name = "member",
|
||||
srcs = ["member.cpp"],
|
||||
hdrs = ["member.h"],
|
||||
deps = [":expression"],
|
||||
deps = [
|
||||
":expression",
|
||||
"//common:ostream",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -53,11 +60,15 @@ cc_library(
|
||||
deps = [
|
||||
":expression",
|
||||
"//common:check",
|
||||
"//common:ostream",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "struct_definition",
|
||||
hdrs = ["struct_definition.h"],
|
||||
deps = [":member"],
|
||||
deps = [
|
||||
":member",
|
||||
"//common:ostream",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#include "executable_semantics/ast/declaration.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto Declaration::MakeFunctionDeclaration(FunctionDefinition definition)
|
||||
@@ -65,41 +63,36 @@ auto Declaration::GetVariableDeclaration() const -> const VariableDeclaration& {
|
||||
return std::get<VariableDeclaration>(value);
|
||||
}
|
||||
|
||||
void Declaration::Print() const {
|
||||
void Declaration::Print(llvm::raw_ostream& out) const {
|
||||
switch (tag()) {
|
||||
case DeclarationKind::FunctionDeclaration:
|
||||
GetFunctionDeclaration().definition.Print();
|
||||
out << GetFunctionDeclaration().definition;
|
||||
break;
|
||||
|
||||
case DeclarationKind::StructDeclaration: {
|
||||
const StructDefinition& struct_def = GetStructDeclaration().definition;
|
||||
std::cout << "struct " << struct_def.name << " {" << std::endl;
|
||||
out << "struct " << struct_def.name << " {\n";
|
||||
for (Member* m : struct_def.members) {
|
||||
m->Print();
|
||||
out << *m;
|
||||
}
|
||||
std::cout << "}" << std::endl;
|
||||
out << "}\n";
|
||||
break;
|
||||
}
|
||||
|
||||
case DeclarationKind::ChoiceDeclaration: {
|
||||
const auto& choice = GetChoiceDeclaration();
|
||||
std::cout << "choice " << choice.name << " {" << std::endl;
|
||||
out << "choice " << choice.name << " {\n";
|
||||
for (const auto& [name, signature] : choice.alternatives) {
|
||||
std::cout << "alt " << name << " ";
|
||||
PrintExp(signature);
|
||||
std::cout << ";" << std::endl;
|
||||
out << "alt " << name << " " << *signature << ";\n";
|
||||
}
|
||||
std::cout << "}" << std::endl;
|
||||
out << "}\n";
|
||||
break;
|
||||
}
|
||||
|
||||
case DeclarationKind::VariableDeclaration: {
|
||||
const auto& var = GetVariableDeclaration();
|
||||
std::cout << "var ";
|
||||
PrintExp(var.type);
|
||||
std::cout << " : " << var.name << " = ";
|
||||
PrintExp(var.initializer);
|
||||
std::cout << std::endl;
|
||||
out << "var " << *var.type << " : " << var.name << " = "
|
||||
<< *var.initializer << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "common/ostream.h"
|
||||
#include "executable_semantics/ast/function_definition.h"
|
||||
#include "executable_semantics/ast/member.h"
|
||||
#include "executable_semantics/ast/struct_definition.h"
|
||||
@@ -82,7 +83,7 @@ class Declaration {
|
||||
auto GetChoiceDeclaration() const -> const ChoiceDeclaration&;
|
||||
auto GetVariableDeclaration() const -> const VariableDeclaration&;
|
||||
|
||||
void Print() const;
|
||||
void Print(llvm::raw_ostream& out) const;
|
||||
|
||||
inline auto tag() const -> DeclarationKind {
|
||||
return std::visit([](const auto& t) { return t.Kind; }, value);
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto Expression::GetIdentifierExpression() const
|
||||
@@ -168,9 +166,8 @@ auto Expression::MakeTupleLiteral(int line_num,
|
||||
for (auto& arg : args) {
|
||||
if (arg.name == "") {
|
||||
if (seen_named_member) {
|
||||
std::cerr << line_num
|
||||
<< ": positional members must come before named members"
|
||||
<< std::endl;
|
||||
llvm::errs() << line_num
|
||||
<< ": positional members must come before named members\n";
|
||||
exit(-1);
|
||||
}
|
||||
arg.name = std::to_string(i);
|
||||
@@ -191,138 +188,122 @@ auto Expression::MakeIndexExpression(int line_num, const Expression* exp,
|
||||
return e;
|
||||
}
|
||||
|
||||
static void PrintOp(Operator op) {
|
||||
static void PrintOp(llvm::raw_ostream& out, Operator op) {
|
||||
switch (op) {
|
||||
case Operator::Add:
|
||||
std::cout << "+";
|
||||
out << "+";
|
||||
break;
|
||||
case Operator::Neg:
|
||||
case Operator::Sub:
|
||||
std::cout << "-";
|
||||
out << "-";
|
||||
break;
|
||||
case Operator::Mul:
|
||||
case Operator::Deref:
|
||||
case Operator::Ptr:
|
||||
std::cout << "*";
|
||||
out << "*";
|
||||
break;
|
||||
case Operator::Not:
|
||||
std::cout << "not";
|
||||
out << "not";
|
||||
break;
|
||||
case Operator::And:
|
||||
std::cout << "and";
|
||||
out << "and";
|
||||
break;
|
||||
case Operator::Or:
|
||||
std::cout << "or";
|
||||
out << "or";
|
||||
break;
|
||||
case Operator::Eq:
|
||||
std::cout << "==";
|
||||
out << "==";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintFields(const std::vector<FieldInitializer>& fields) {
|
||||
static void PrintFields(llvm::raw_ostream& out,
|
||||
const std::vector<FieldInitializer>& fields) {
|
||||
int i = 0;
|
||||
for (auto iter = fields.begin(); iter != fields.end(); ++iter, ++i) {
|
||||
if (i != 0) {
|
||||
std::cout << ", ";
|
||||
out << ", ";
|
||||
}
|
||||
std::cout << iter->name << " = ";
|
||||
PrintExp(iter->expression);
|
||||
out << iter->name << " = " << *iter->expression;
|
||||
}
|
||||
}
|
||||
|
||||
void PrintExp(const Expression* e) {
|
||||
switch (e->tag()) {
|
||||
void Expression::Print(llvm::raw_ostream& out) const {
|
||||
switch (tag()) {
|
||||
case ExpressionKind::IndexExpression:
|
||||
PrintExp(e->GetIndexExpression().aggregate);
|
||||
std::cout << "[";
|
||||
PrintExp(e->GetIndexExpression().offset);
|
||||
std::cout << "]";
|
||||
out << *GetIndexExpression().aggregate << "["
|
||||
<< *GetIndexExpression().offset << "]";
|
||||
break;
|
||||
case ExpressionKind::FieldAccessExpression:
|
||||
PrintExp(e->GetFieldAccessExpression().aggregate);
|
||||
std::cout << ".";
|
||||
std::cout << e->GetFieldAccessExpression().field;
|
||||
out << *GetFieldAccessExpression().aggregate << "."
|
||||
<< GetFieldAccessExpression().field;
|
||||
break;
|
||||
case ExpressionKind::TupleLiteral:
|
||||
std::cout << "(";
|
||||
PrintFields(e->GetTupleLiteral().fields);
|
||||
std::cout << ")";
|
||||
out << "(";
|
||||
PrintFields(out, GetTupleLiteral().fields);
|
||||
out << ")";
|
||||
break;
|
||||
case ExpressionKind::IntLiteral:
|
||||
std::cout << e->GetIntLiteral();
|
||||
out << GetIntLiteral();
|
||||
break;
|
||||
case ExpressionKind::BoolLiteral:
|
||||
std::cout << std::boolalpha;
|
||||
std::cout << e->GetBoolLiteral();
|
||||
out << (GetBoolLiteral() ? "true" : "false");
|
||||
break;
|
||||
case ExpressionKind::PrimitiveOperatorExpression: {
|
||||
std::cout << "(";
|
||||
PrimitiveOperatorExpression op = e->GetPrimitiveOperatorExpression();
|
||||
out << "(";
|
||||
PrimitiveOperatorExpression op = GetPrimitiveOperatorExpression();
|
||||
if (op.arguments.size() == 0) {
|
||||
PrintOp(op.op);
|
||||
PrintOp(out, op.op);
|
||||
} else if (op.arguments.size() == 1) {
|
||||
PrintOp(op.op);
|
||||
std::cout << " ";
|
||||
auto iter = op.arguments.begin();
|
||||
PrintExp(*iter);
|
||||
PrintOp(out, op.op);
|
||||
out << " " << *op.arguments[0];
|
||||
} else if (op.arguments.size() == 2) {
|
||||
auto iter = op.arguments.begin();
|
||||
PrintExp(*iter);
|
||||
std::cout << " ";
|
||||
PrintOp(op.op);
|
||||
std::cout << " ";
|
||||
++iter;
|
||||
PrintExp(*iter);
|
||||
out << *op.arguments[0] << " ";
|
||||
PrintOp(out, op.op);
|
||||
out << " " << *op.arguments[1];
|
||||
}
|
||||
std::cout << ")";
|
||||
out << ")";
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::IdentifierExpression:
|
||||
std::cout << e->GetIdentifierExpression().name;
|
||||
out << GetIdentifierExpression().name;
|
||||
break;
|
||||
case ExpressionKind::BindingExpression: {
|
||||
const BindingExpression& binding = e->GetBindingExpression();
|
||||
const BindingExpression& binding = GetBindingExpression();
|
||||
if (binding.name.has_value()) {
|
||||
std::cout << *binding.name;
|
||||
out << *binding.name;
|
||||
} else {
|
||||
std::cout << "_";
|
||||
out << "_";
|
||||
}
|
||||
std::cout << ": ";
|
||||
PrintExp(e->GetBindingExpression().type);
|
||||
out << ": " << *binding.type;
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::CallExpression:
|
||||
PrintExp(e->GetCallExpression().function);
|
||||
if (e->GetCallExpression().argument->tag() ==
|
||||
ExpressionKind::TupleLiteral) {
|
||||
PrintExp(e->GetCallExpression().argument);
|
||||
out << *GetCallExpression().function;
|
||||
if (GetCallExpression().argument->tag() == ExpressionKind::TupleLiteral) {
|
||||
out << *GetCallExpression().argument;
|
||||
} else {
|
||||
std::cout << "(";
|
||||
PrintExp(e->GetCallExpression().argument);
|
||||
std::cout << ")";
|
||||
out << "(" << *GetCallExpression().argument << ")";
|
||||
}
|
||||
break;
|
||||
case ExpressionKind::BoolTypeLiteral:
|
||||
std::cout << "Bool";
|
||||
out << "Bool";
|
||||
break;
|
||||
case ExpressionKind::IntTypeLiteral:
|
||||
std::cout << "Int";
|
||||
out << "Int";
|
||||
break;
|
||||
case ExpressionKind::TypeTypeLiteral:
|
||||
std::cout << "Type";
|
||||
out << "Type";
|
||||
break;
|
||||
case ExpressionKind::AutoTypeLiteral:
|
||||
std::cout << "auto";
|
||||
out << "auto";
|
||||
break;
|
||||
case ExpressionKind::ContinuationTypeLiteral:
|
||||
std::cout << "Continuation";
|
||||
out << "Continuation";
|
||||
break;
|
||||
case ExpressionKind::FunctionTypeLiteral:
|
||||
std::cout << "fn ";
|
||||
PrintExp(e->GetFunctionTypeLiteral().parameter);
|
||||
std::cout << " -> ";
|
||||
PrintExp(e->GetFunctionTypeLiteral().return_type);
|
||||
out << "fn " << *GetFunctionTypeLiteral().parameter << " -> "
|
||||
<< *GetFunctionTypeLiteral().return_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "common/ostream.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
struct Expression;
|
||||
@@ -176,6 +178,8 @@ struct Expression {
|
||||
auto GetCallExpression() const -> const CallExpression&;
|
||||
auto GetFunctionTypeLiteral() const -> const FunctionTypeLiteral&;
|
||||
|
||||
void Print(llvm::raw_ostream& out) const;
|
||||
|
||||
inline auto tag() const -> ExpressionKind {
|
||||
return std::visit([](const auto& t) { return t.Kind; }, value);
|
||||
}
|
||||
@@ -191,8 +195,6 @@ struct Expression {
|
||||
value;
|
||||
};
|
||||
|
||||
void PrintExp(const Expression* exp);
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
#endif // EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_
|
||||
|
||||
@@ -4,21 +4,16 @@
|
||||
|
||||
#include "executable_semantics/ast/function_definition.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
void FunctionDefinition::PrintDepth(int depth) const {
|
||||
std::cout << "fn " << name << " ";
|
||||
PrintExp(param_pattern);
|
||||
std::cout << " -> ";
|
||||
PrintExp(return_type);
|
||||
void FunctionDefinition::PrintDepth(int depth, llvm::raw_ostream& out) const {
|
||||
out << "fn " << name << " " << *param_pattern << " -> " << *return_type;
|
||||
if (body) {
|
||||
std::cout << " {" << std::endl;
|
||||
PrintStatement(body, depth);
|
||||
std::cout << std::endl << "}" << std::endl;
|
||||
out << " {\n";
|
||||
body->PrintDepth(depth, out);
|
||||
out << "\n}\n";
|
||||
} else {
|
||||
std::cout << ";" << std::endl;
|
||||
out << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef EXECUTABLE_SEMANTICS_AST_FUNCTION_DEFINITION_H_
|
||||
#define EXECUTABLE_SEMANTICS_AST_FUNCTION_DEFINITION_H_
|
||||
|
||||
#include "common/ostream.h"
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
#include "executable_semantics/ast/statement.h"
|
||||
|
||||
@@ -21,8 +22,8 @@ struct FunctionDefinition {
|
||||
return_type(return_type),
|
||||
body(body) {}
|
||||
|
||||
void Print() const { PrintDepth(-1); }
|
||||
void PrintDepth(int depth) const;
|
||||
void Print(llvm::raw_ostream& out) const { PrintDepth(-1, out); }
|
||||
void PrintDepth(int depth, llvm::raw_ostream& out) const;
|
||||
|
||||
int line_num;
|
||||
std::string name;
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#include "executable_semantics/ast/member.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto Member::MakeFieldMember(int line_num, std::string name,
|
||||
@@ -20,13 +18,11 @@ auto Member::GetFieldMember() const -> const FieldMember& {
|
||||
return std::get<FieldMember>(value);
|
||||
}
|
||||
|
||||
void Member::Print() {
|
||||
void Member::Print(llvm::raw_ostream& out) const {
|
||||
switch (tag()) {
|
||||
case MemberKind::FieldMember:
|
||||
const auto& field = GetFieldMember();
|
||||
std::cout << "var " << field.name << " : ";
|
||||
PrintExp(field.type);
|
||||
std::cout << ";" << std::endl;
|
||||
out << "var " << field.name << " : " << *field.type << ";\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common/ostream.h"
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
|
||||
namespace Carbon {
|
||||
@@ -25,7 +26,7 @@ struct Member {
|
||||
|
||||
auto GetFieldMember() const -> const FieldMember&;
|
||||
|
||||
void Print();
|
||||
void Print(llvm::raw_ostream& out) const;
|
||||
|
||||
inline auto tag() const -> MemberKind {
|
||||
return std::visit([](const auto& t) { return t.Kind; }, value);
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#include "executable_semantics/ast/statement.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "common/check.h"
|
||||
|
||||
namespace Carbon {
|
||||
@@ -182,117 +180,101 @@ auto Statement::MakeAwait(int line_num) -> const Statement* {
|
||||
return s;
|
||||
}
|
||||
|
||||
void PrintStatement(const Statement* s, int depth) {
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const {
|
||||
if (depth == 0) {
|
||||
std::cout << " ... ";
|
||||
out << " ... ";
|
||||
return;
|
||||
}
|
||||
switch (s->tag()) {
|
||||
switch (tag()) {
|
||||
case StatementKind::Match:
|
||||
std::cout << "match (";
|
||||
PrintExp(s->GetMatch().exp);
|
||||
std::cout << ") {";
|
||||
out << "match (" << *GetMatch().exp << ") {";
|
||||
if (depth < 0 || depth > 1) {
|
||||
std::cout << std::endl;
|
||||
for (auto& clause : *s->GetMatch().clauses) {
|
||||
std::cout << "case ";
|
||||
PrintExp(clause.first);
|
||||
std::cout << " =>" << std::endl;
|
||||
PrintStatement(clause.second, depth - 1);
|
||||
std::cout << std::endl;
|
||||
out << "\n";
|
||||
for (auto& clause : *GetMatch().clauses) {
|
||||
out << "case " << *clause.first << " =>\n";
|
||||
clause.second->PrintDepth(depth - 1, out);
|
||||
out << "\n";
|
||||
}
|
||||
} else {
|
||||
std::cout << "...";
|
||||
out << "...";
|
||||
}
|
||||
std::cout << "}";
|
||||
out << "}";
|
||||
break;
|
||||
case StatementKind::While:
|
||||
std::cout << "while (";
|
||||
PrintExp(s->GetWhile().cond);
|
||||
std::cout << ")" << std::endl;
|
||||
PrintStatement(s->GetWhile().body, depth - 1);
|
||||
out << "while (" << *GetWhile().cond << ")\n";
|
||||
GetWhile().body->PrintDepth(depth - 1, out);
|
||||
break;
|
||||
case StatementKind::Break:
|
||||
std::cout << "break;";
|
||||
out << "break;";
|
||||
break;
|
||||
case StatementKind::Continue:
|
||||
std::cout << "continue;";
|
||||
out << "continue;";
|
||||
break;
|
||||
case StatementKind::VariableDefinition:
|
||||
std::cout << "var ";
|
||||
PrintExp(s->GetVariableDefinition().pat);
|
||||
std::cout << " = ";
|
||||
PrintExp(s->GetVariableDefinition().init);
|
||||
std::cout << ";";
|
||||
out << "var " << *GetVariableDefinition().pat << " = "
|
||||
<< *GetVariableDefinition().init << ";";
|
||||
break;
|
||||
case StatementKind::ExpressionStatement:
|
||||
PrintExp(s->GetExpressionStatement().exp);
|
||||
std::cout << ";";
|
||||
out << *GetExpressionStatement().exp << ";";
|
||||
break;
|
||||
case StatementKind::Assign:
|
||||
PrintExp(s->GetAssign().lhs);
|
||||
std::cout << " = ";
|
||||
PrintExp(s->GetAssign().rhs);
|
||||
std::cout << ";";
|
||||
out << *GetAssign().lhs << " = " << *GetAssign().rhs << ";";
|
||||
break;
|
||||
case StatementKind::If:
|
||||
std::cout << "if (";
|
||||
PrintExp(s->GetIf().cond);
|
||||
std::cout << ")" << std::endl;
|
||||
PrintStatement(s->GetIf().then_stmt, depth - 1);
|
||||
std::cout << std::endl << "else" << std::endl;
|
||||
PrintStatement(s->GetIf().else_stmt, depth - 1);
|
||||
out << "if (" << *GetIf().cond << ")\n";
|
||||
GetIf().then_stmt->PrintDepth(depth - 1, out);
|
||||
if (GetIf().else_stmt) {
|
||||
out << "\nelse\n";
|
||||
GetIf().else_stmt->PrintDepth(depth - 1, out);
|
||||
}
|
||||
break;
|
||||
case StatementKind::Return:
|
||||
std::cout << "return ";
|
||||
PrintExp(s->GetReturn().exp);
|
||||
std::cout << ";";
|
||||
out << "return " << *GetReturn().exp << ";";
|
||||
break;
|
||||
case StatementKind::Sequence:
|
||||
PrintStatement(s->GetSequence().stmt, depth);
|
||||
GetSequence().stmt->PrintDepth(depth, out);
|
||||
if (depth < 0 || depth > 1) {
|
||||
std::cout << std::endl;
|
||||
out << "\n";
|
||||
} else {
|
||||
std::cout << " ";
|
||||
out << " ";
|
||||
}
|
||||
if (GetSequence().next) {
|
||||
GetSequence().next->PrintDepth(depth - 1, out);
|
||||
}
|
||||
PrintStatement(s->GetSequence().next, depth - 1);
|
||||
break;
|
||||
case StatementKind::Block:
|
||||
std::cout << "{";
|
||||
out << "{";
|
||||
if (depth < 0 || depth > 1) {
|
||||
std::cout << std::endl;
|
||||
out << "\n";
|
||||
}
|
||||
PrintStatement(s->GetBlock().stmt, depth);
|
||||
if (depth < 0 || depth > 1) {
|
||||
std::cout << std::endl;
|
||||
if (GetBlock().stmt) {
|
||||
GetBlock().stmt->PrintDepth(depth, out);
|
||||
if (depth < 0 || depth > 1) {
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
std::cout << "}";
|
||||
out << "}";
|
||||
if (depth < 0 || depth > 1) {
|
||||
std::cout << std::endl;
|
||||
out << "\n";
|
||||
}
|
||||
break;
|
||||
case StatementKind::Continuation:
|
||||
std::cout << "continuation " << s->GetContinuation().continuation_variable
|
||||
<< " ";
|
||||
out << "continuation " << GetContinuation().continuation_variable << " ";
|
||||
if (depth < 0 || depth > 1) {
|
||||
std::cout << std::endl;
|
||||
out << "\n";
|
||||
}
|
||||
PrintStatement(s->GetContinuation().body, depth - 1);
|
||||
GetContinuation().body->PrintDepth(depth - 1, out);
|
||||
if (depth < 0 || depth > 1) {
|
||||
std::cout << std::endl;
|
||||
out << "\n";
|
||||
}
|
||||
break;
|
||||
case StatementKind::Run:
|
||||
std::cout << "run ";
|
||||
PrintExp(s->GetRun().argument);
|
||||
std::cout << ";";
|
||||
out << "run " << *GetRun().argument << ";";
|
||||
break;
|
||||
case StatementKind::Await:
|
||||
std::cout << "await;";
|
||||
out << "await;";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "common/ostream.h"
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
|
||||
namespace Carbon {
|
||||
@@ -162,6 +163,8 @@ struct Statement {
|
||||
auto GetRun() const -> const Run&;
|
||||
auto GetAwait() const -> const Await&;
|
||||
|
||||
void PrintDepth(int depth, llvm::raw_ostream& out) const;
|
||||
|
||||
inline auto tag() const -> StatementKind {
|
||||
return std::visit([](const auto& t) { return t.Kind; }, value);
|
||||
}
|
||||
@@ -175,8 +178,6 @@ struct Statement {
|
||||
value;
|
||||
};
|
||||
|
||||
void PrintStatement(const Statement*, int);
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
#endif // EXECUTABLE_SEMANTICS_AST_STATEMENT_H_
|
||||
|
||||
Reference in New Issue
Block a user