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:
Jon Meow
2021-07-20 13:16:48 -07:00
committed by GitHub
parent 368fc0063c
commit 8fccecadeb
31 changed files with 391 additions and 458 deletions
+14 -3
View File
@@ -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",
],
)
+10 -17
View File
@@ -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;
}
}
+2 -1
View File
@@ -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);
+50 -69
View File
@@ -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;
}
}
+4 -2
View File
@@ -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;
+2 -6
View File
@@ -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;
}
}
+2 -1
View File
@@ -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);
+48 -66
View File
@@ -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
+3 -2
View File
@@ -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_