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
+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;
}
}