mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Suppress Print intrinsic output in the fuzzer. (#2784)
Related to #2780, but mostly an issue when running over the committed corpus since we use Print a lot.
This commit is contained in:
@@ -86,8 +86,11 @@ auto ParseAndExecute(const Fuzzing::CompilationUnit& compilation_unit)
|
||||
AddPrelude(*prelude_path, &arena, &ast.declarations,
|
||||
&ast.num_prelude_declarations);
|
||||
TraceStream trace_stream;
|
||||
CARBON_ASSIGN_OR_RETURN(ast, AnalyzeProgram(&arena, ast, &trace_stream));
|
||||
return ExecProgram(&arena, ast, &trace_stream);
|
||||
|
||||
// Use llvm::nulls() to suppress output from the Print intrinsic.
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
ast, AnalyzeProgram(&arena, ast, &trace_stream, &llvm::nulls()));
|
||||
return ExecProgram(&arena, ast, &trace_stream, &llvm::nulls());
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
namespace Carbon {
|
||||
|
||||
auto AnalyzeProgram(Nonnull<Arena*> arena, AST ast,
|
||||
Nonnull<TraceStream*> trace_stream) -> ErrorOr<AST> {
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream) -> ErrorOr<AST> {
|
||||
if (trace_stream->is_enabled()) {
|
||||
*trace_stream << "********** source program **********\n";
|
||||
for (int i = ast.num_prelude_declarations;
|
||||
@@ -46,7 +47,8 @@ auto AnalyzeProgram(Nonnull<Arena*> arena, AST ast,
|
||||
if (trace_stream->is_enabled()) {
|
||||
*trace_stream << "********** type checking **********\n";
|
||||
}
|
||||
CARBON_RETURN_IF_ERROR(TypeChecker(arena, trace_stream).TypeCheck(ast));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
TypeChecker(arena, trace_stream, print_stream).TypeCheck(ast));
|
||||
|
||||
if (trace_stream->is_enabled()) {
|
||||
*trace_stream << "********** resolving unformed variables **********\n";
|
||||
@@ -64,11 +66,12 @@ auto AnalyzeProgram(Nonnull<Arena*> arena, AST ast,
|
||||
}
|
||||
|
||||
auto ExecProgram(Nonnull<Arena*> arena, AST ast,
|
||||
Nonnull<TraceStream*> trace_stream) -> ErrorOr<int> {
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream) -> ErrorOr<int> {
|
||||
if (trace_stream->is_enabled()) {
|
||||
*trace_stream << "********** starting execution **********\n";
|
||||
}
|
||||
return InterpProgram(ast, arena, trace_stream);
|
||||
return InterpProgram(ast, arena, trace_stream, print_stream);
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
@@ -17,11 +17,13 @@ namespace Carbon {
|
||||
|
||||
// Perform semantic analysis on the AST.
|
||||
auto AnalyzeProgram(Nonnull<Arena*> arena, AST ast,
|
||||
Nonnull<TraceStream*> trace_stream) -> ErrorOr<AST>;
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream) -> ErrorOr<AST>;
|
||||
|
||||
// Run the program's `Main` function.
|
||||
auto ExecProgram(Nonnull<Arena*> arena, AST ast,
|
||||
Nonnull<TraceStream*> trace_stream) -> ErrorOr<int>;
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream) -> ErrorOr<int>;
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
|
||||
@@ -59,11 +59,13 @@ class Interpreter {
|
||||
// traces if `trace` is true. `phase` indicates whether it executes at
|
||||
// compile time or run time.
|
||||
Interpreter(Phase phase, Nonnull<Arena*> arena,
|
||||
Nonnull<TraceStream*> trace_stream)
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream)
|
||||
: arena_(arena),
|
||||
heap_(arena),
|
||||
todo_(MakeTodo(phase, &heap_)),
|
||||
trace_stream_(trace_stream),
|
||||
print_stream_(print_stream),
|
||||
phase_(phase) {}
|
||||
|
||||
// Runs all the steps of `action`.
|
||||
@@ -178,6 +180,10 @@ class Interpreter {
|
||||
ActionStack todo_;
|
||||
|
||||
Nonnull<TraceStream*> trace_stream_;
|
||||
|
||||
// The stream for the Print intrinsic.
|
||||
Nonnull<llvm::raw_ostream*> print_stream_;
|
||||
|
||||
Phase phase_;
|
||||
};
|
||||
|
||||
@@ -1561,17 +1567,17 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
|
||||
intrinsic.source_loc(), format_string, num_format_args));
|
||||
switch (num_format_args) {
|
||||
case 0:
|
||||
llvm::outs() << llvm::formatv(format_string);
|
||||
*print_stream_ << llvm::formatv(format_string);
|
||||
break;
|
||||
case 1:
|
||||
llvm::outs() << llvm::formatv(format_string,
|
||||
cast<IntValue>(*args[1]).value());
|
||||
*print_stream_ << llvm::formatv(format_string,
|
||||
cast<IntValue>(*args[1]).value());
|
||||
break;
|
||||
default:
|
||||
CARBON_FATAL() << "Too many format args: " << num_format_args;
|
||||
}
|
||||
// Implicit newline; currently no way to disable it.
|
||||
llvm::outs() << "\n";
|
||||
*print_stream_ << "\n";
|
||||
return todo_.FinishAction(TupleValue::Empty());
|
||||
}
|
||||
case IntrinsicExpression::Intrinsic::Assert: {
|
||||
@@ -2438,8 +2444,9 @@ auto Interpreter::RunAllSteps(std::unique_ptr<Action> action)
|
||||
}
|
||||
|
||||
auto InterpProgram(const AST& ast, Nonnull<Arena*> arena,
|
||||
Nonnull<TraceStream*> trace_stream) -> ErrorOr<int> {
|
||||
Interpreter interpreter(Phase::RunTime, arena, trace_stream);
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream) -> ErrorOr<int> {
|
||||
Interpreter interpreter(Phase::RunTime, arena, trace_stream, print_stream);
|
||||
if (trace_stream->is_enabled()) {
|
||||
*trace_stream << "********** initializing globals **********\n";
|
||||
}
|
||||
@@ -2460,9 +2467,11 @@ auto InterpProgram(const AST& ast, Nonnull<Arena*> arena,
|
||||
}
|
||||
|
||||
auto InterpExp(Nonnull<const Expression*> e, Nonnull<Arena*> arena,
|
||||
Nonnull<TraceStream*> trace_stream)
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream)
|
||||
-> ErrorOr<Nonnull<const Value*>> {
|
||||
Interpreter interpreter(Phase::CompileTime, arena, trace_stream);
|
||||
Interpreter interpreter(Phase::CompileTime, arena, trace_stream,
|
||||
print_stream);
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
interpreter.RunAllSteps(std::make_unique<ExpressionAction>(e)));
|
||||
return interpreter.result();
|
||||
|
||||
@@ -25,13 +25,15 @@ namespace Carbon {
|
||||
// Interprets the program defined by `ast`, allocating values on `arena` and
|
||||
// printing traces if `trace` is true.
|
||||
auto InterpProgram(const AST& ast, Nonnull<Arena*> arena,
|
||||
Nonnull<TraceStream*> trace_stream) -> ErrorOr<int>;
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream) -> ErrorOr<int>;
|
||||
|
||||
// Interprets `e` at compile-time, allocating values on `arena` and
|
||||
// printing traces if `trace` is true. The caller must ensure that all the
|
||||
// code this evaluates has been typechecked.
|
||||
auto InterpExp(Nonnull<const Expression*> e, Nonnull<Arena*> arena,
|
||||
Nonnull<TraceStream*> trace_stream)
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream)
|
||||
-> ErrorOr<Nonnull<const Value*>>;
|
||||
|
||||
// Attempts to match `v` against the pattern `p`, returning whether matching
|
||||
|
||||
@@ -756,7 +756,7 @@ auto TypeChecker::ImplicitlyConvert(std::string_view context,
|
||||
ImplicitlyConvert(context, impl_scope, source,
|
||||
arena_->New<TypeType>()));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> converted_value,
|
||||
InterpExp(source_as_type, arena_, trace_stream_));
|
||||
InterpExp(source_as_type));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const ConstraintType*> destination_constraint,
|
||||
ConvertToConstraintType(source->source_loc(), "implicit conversion",
|
||||
@@ -1363,7 +1363,7 @@ auto TypeChecker::ArgumentDeduction::Finish(
|
||||
|
||||
// Evaluate the argument to get the value.
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> value,
|
||||
InterpExp(arg, type_checker.arena_, trace_stream_));
|
||||
type_checker.InterpExp(arg));
|
||||
if (trace_stream_->is_enabled()) {
|
||||
*trace_stream_ << "evaluated generic parameter " << *binding << " as "
|
||||
<< *value << "\n";
|
||||
@@ -2717,9 +2717,8 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
ExpectExactType(index.offset().source_loc(), "tuple index",
|
||||
arena_->New<IntType>(),
|
||||
&index.offset().static_type(), impl_scope));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
auto offset_value,
|
||||
InterpExp(&index.offset(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(auto offset_value,
|
||||
InterpExp(&index.offset()));
|
||||
int i = cast<IntValue>(*offset_value).value();
|
||||
if (i < 0 || i >= static_cast<int>(tuple_type.elements().size())) {
|
||||
return ProgramError(e->source_loc())
|
||||
@@ -2936,9 +2935,8 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
// TODO: Per the language rules, we are supposed to also perform
|
||||
// lookup into `type` and report an ambiguity if the name is found in
|
||||
// both places.
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> type,
|
||||
InterpExp(&access.object(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> type,
|
||||
InterpExp(&access.object()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
ConstraintLookupResult result,
|
||||
LookupInConstraint(e->source_loc(), "member access", &object_type,
|
||||
@@ -2987,9 +2985,8 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
case Value::Kind::TypeType: {
|
||||
// This is member access into an unconstrained type. Evaluate it and
|
||||
// perform lookup in the result.
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> type,
|
||||
InterpExp(&access.object(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> type,
|
||||
InterpExp(&access.object()));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ExpectCompleteType(access.source_loc(), "member access", type));
|
||||
switch (type->kind()) {
|
||||
@@ -3119,7 +3116,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
// Evaluate the member name expression to determine which member we're
|
||||
// accessing.
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> member_name_value,
|
||||
InterpExp(&access.path(), arena_, trace_stream_));
|
||||
InterpExp(&access.path()));
|
||||
const auto& member_name = cast<MemberName>(*member_name_value);
|
||||
access.set_member(&member_name);
|
||||
bool is_instance_member = IsInstanceMember(&member_name.member());
|
||||
@@ -3130,8 +3127,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
if (IsTypeOfType(&access.object().static_type())) {
|
||||
// This is `Type.(member_name)`, where `member_name` doesn't specify
|
||||
// a type. This access doesn't perform instance binding.
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
base_type, InterpExp(&access.object(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(base_type, InterpExp(&access.object()));
|
||||
has_instance = false;
|
||||
} else {
|
||||
// This is `value.(member_name)`, where `member_name` doesn't specify
|
||||
@@ -3382,12 +3378,10 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
// `&` between type-of-types performs constraint combination.
|
||||
// TODO: Should this be done via an intrinsic?
|
||||
if (IsTypeOfType(ts[0]) && IsTypeOfType(ts[1])) {
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> lhs,
|
||||
InterpExp(op.arguments()[0], arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> rhs,
|
||||
InterpExp(op.arguments()[1], arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> lhs,
|
||||
InterpExp(op.arguments()[0]));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> rhs,
|
||||
InterpExp(op.arguments()[1]));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const ConstraintType*> lhs_constraint,
|
||||
ConvertToConstraintType(op.arguments()[0]->source_loc(),
|
||||
@@ -3568,9 +3562,8 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
dyn_cast<SimpleMemberAccessExpression>(&call.function());
|
||||
if (member_access &&
|
||||
isa<TypeType>(member_access->object().static_type())) {
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> type,
|
||||
InterpExp(&member_access->object(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> type,
|
||||
InterpExp(&member_access->object()));
|
||||
if (isa<ChoiceType>(type)) {
|
||||
return ProgramError(e->source_loc())
|
||||
<< "alternative `" << *type << "."
|
||||
@@ -3885,9 +3878,8 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> type,
|
||||
TypeCheckTypeExp(&impls_clause.type(), inner_impl_scope));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> constraint,
|
||||
InterpExp(&impls_clause.constraint(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> constraint,
|
||||
InterpExp(&impls_clause.constraint()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const ConstraintType*> constraint_type,
|
||||
ConvertToConstraintType(impls_clause.source_loc(),
|
||||
@@ -3904,12 +3896,10 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
}
|
||||
case WhereClauseKind::EqualsWhereClause: {
|
||||
const auto& equals_clause = cast<EqualsWhereClause>(*clause);
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> lhs,
|
||||
InterpExp(&equals_clause.lhs(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> rhs,
|
||||
InterpExp(&equals_clause.rhs(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> lhs,
|
||||
InterpExp(&equals_clause.lhs()));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> rhs,
|
||||
InterpExp(&equals_clause.rhs()));
|
||||
if (!ValueEqual(lhs, rhs, std::nullopt)) {
|
||||
builder.AddEqualityConstraint({.values = {lhs, rhs}});
|
||||
}
|
||||
@@ -3945,8 +3935,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
// type. This is the value we'll rewrite to when type-checking a
|
||||
// member access.
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> replacement_value,
|
||||
InterpExp(&rewrite_clause.replacement(),
|
||||
arena_, trace_stream_));
|
||||
InterpExp(&rewrite_clause.replacement()));
|
||||
Nonnull<const Value*> replacement_type =
|
||||
&rewrite_clause.replacement().static_type();
|
||||
|
||||
@@ -3964,9 +3953,8 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
Nonnull<Expression*> converted_expression,
|
||||
ImplicitlyConvert("rewrite constraint", inner_impl_scope,
|
||||
replacement_literal, constraint_type));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> converted_value,
|
||||
InterpExp(converted_expression, arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> converted_value,
|
||||
InterpExp(converted_expression));
|
||||
|
||||
// Add the rewrite constraint.
|
||||
builder.AddRewriteConstraint(
|
||||
@@ -3998,9 +3986,8 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
||||
array_literal.size_expression().source_loc(), "array size",
|
||||
arena_->New<IntType>(),
|
||||
&array_literal.size_expression().static_type(), impl_scope));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> size_value,
|
||||
InterpExp(&array_literal.size_expression(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> size_value,
|
||||
InterpExp(&array_literal.size_expression()));
|
||||
if (cast<IntValue>(size_value)->value() < 0) {
|
||||
return ProgramError(array_literal.size_expression().source_loc())
|
||||
<< "Array size cannot be negative";
|
||||
@@ -4072,7 +4059,7 @@ auto TypeChecker::TypeCheckTypeExp(Nonnull<Expression*> type_expression,
|
||||
ImplicitlyConvert("type expression", impl_scope, type_expression,
|
||||
arena_->New<TypeType>()));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> type,
|
||||
InterpExp(type_expression, arena_, trace_stream_));
|
||||
InterpExp(type_expression));
|
||||
CARBON_CHECK(IsType(type))
|
||||
<< "type expression did not produce a type, got " << *type;
|
||||
if (concrete) {
|
||||
@@ -4180,8 +4167,7 @@ auto TypeChecker::TypeCheckPattern(
|
||||
auto* converted,
|
||||
ImplicitlyConvert("type of name binding", impl_scope, literal,
|
||||
arena_->New<TypeType>()));
|
||||
CARBON_ASSIGN_OR_RETURN(type,
|
||||
InterpExp(converted, arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(type, InterpExp(converted));
|
||||
}
|
||||
CARBON_CHECK(IsType(type))
|
||||
<< "conversion to type succeeded but didn't produce a type, got "
|
||||
@@ -4306,7 +4292,7 @@ auto TypeChecker::TypeCheckPattern(
|
||||
p->set_static_type(&expression.static_type());
|
||||
// TODO: Per proposal #2188, we should form an `==` comparison here.
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> expr_value,
|
||||
InterpExp(&expression, arena_, trace_stream_));
|
||||
InterpExp(&expression));
|
||||
p->set_value(expr_value);
|
||||
return Success();
|
||||
}
|
||||
@@ -5910,7 +5896,7 @@ auto TypeChecker::DeclareAliasDeclaration(Nonnull<AliasDeclaration*> alias,
|
||||
if (alias->target().static_type().kind() !=
|
||||
Value::Kind::TypeOfNamespaceName) {
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> target,
|
||||
InterpExp(&alias->target(), arena_, trace_stream_));
|
||||
InterpExp(&alias->target()));
|
||||
alias->set_constant_value(target);
|
||||
}
|
||||
return Success();
|
||||
@@ -6091,9 +6077,8 @@ auto TypeChecker::DeclareDeclaration(Nonnull<Declaration*> d,
|
||||
auto& mix_decl = cast<MixDeclaration>(*d);
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
TypeCheckExp(&mix_decl.mixin(), *scope_info.innermost_scope));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> mixin,
|
||||
InterpExp(&mix_decl.mixin(), arena_, trace_stream_));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> mixin,
|
||||
InterpExp(&mix_decl.mixin()));
|
||||
if (const auto* mixin_value = dyn_cast<MixinPseudoType>(mixin)) {
|
||||
mix_decl.set_mixin_value(mixin_value);
|
||||
} else {
|
||||
@@ -6333,4 +6318,9 @@ auto TypeChecker::InstantiateImplDeclaration(
|
||||
return std::pair{impl, arena_->New<Bindings>(std::move(new_bindings))};
|
||||
}
|
||||
|
||||
auto TypeChecker::InterpExp(Nonnull<const Expression*> e)
|
||||
-> ErrorOr<Nonnull<const Value*>> {
|
||||
return Carbon::InterpExp(e, arena_, trace_stream_, print_stream_);
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
@@ -38,8 +38,11 @@ using GlobalMembersMap =
|
||||
class TypeChecker {
|
||||
public:
|
||||
explicit TypeChecker(Nonnull<Arena*> arena,
|
||||
Nonnull<TraceStream*> trace_stream)
|
||||
: arena_(arena), trace_stream_(trace_stream) {}
|
||||
Nonnull<TraceStream*> trace_stream,
|
||||
Nonnull<llvm::raw_ostream*> print_stream)
|
||||
: arena_(arena),
|
||||
trace_stream_(trace_stream),
|
||||
print_stream_(print_stream) {}
|
||||
|
||||
// Type-checks `ast` and sets properties such as `static_type`, as documented
|
||||
// on the individual nodes.
|
||||
@@ -523,9 +526,14 @@ class TypeChecker {
|
||||
|
||||
// Instantiate an impl with the given set of bindings, including one or more
|
||||
// template bindings.
|
||||
ErrorOr<std::pair<Nonnull<ImplDeclaration*>, Nonnull<Bindings*>>>
|
||||
InstantiateImplDeclaration(Nonnull<const ImplDeclaration*> pattern,
|
||||
Nonnull<const Bindings*> bindings) const;
|
||||
auto InstantiateImplDeclaration(Nonnull<const ImplDeclaration*> pattern,
|
||||
Nonnull<const Bindings*> bindings) const
|
||||
-> ErrorOr<std::pair<Nonnull<ImplDeclaration*>, Nonnull<Bindings*>>>;
|
||||
|
||||
// Wraps the interpreter's InterpExp, forwarding TypeChecker members as
|
||||
// arguments.
|
||||
auto InterpExp(Nonnull<const Expression*> e)
|
||||
-> ErrorOr<Nonnull<const Value*>>;
|
||||
|
||||
Nonnull<Arena*> arena_;
|
||||
Builtins builtins_;
|
||||
@@ -535,6 +543,9 @@ class TypeChecker {
|
||||
|
||||
Nonnull<TraceStream*> trace_stream_;
|
||||
|
||||
// The stream for the Print intrinsic.
|
||||
Nonnull<llvm::raw_ostream*> print_stream_;
|
||||
|
||||
// The top-level ImplScope, containing `impl` declarations that should be
|
||||
// usable from any context. This is used when we want to try to refine a
|
||||
// symbolic witness into an impl witness during substitution.
|
||||
|
||||
+4
-2
@@ -105,7 +105,8 @@ auto ExplorerMain(int argc, char** argv, void* static_for_main_addr,
|
||||
auto time_after_prelude = std::chrono::system_clock::now();
|
||||
|
||||
// Semantically analyze the parsed program.
|
||||
if (ErrorOr<AST> analyze_result = AnalyzeProgram(&arena, ast, &trace_stream);
|
||||
if (ErrorOr<AST> analyze_result =
|
||||
AnalyzeProgram(&arena, ast, &trace_stream, &llvm::outs());
|
||||
analyze_result.ok()) {
|
||||
ast = *std::move(analyze_result);
|
||||
} else {
|
||||
@@ -117,7 +118,8 @@ auto ExplorerMain(int argc, char** argv, void* static_for_main_addr,
|
||||
|
||||
// Run the program.
|
||||
auto ret = EXIT_SUCCESS;
|
||||
if (ErrorOr<int> exec_result = ExecProgram(&arena, ast, &trace_stream);
|
||||
if (ErrorOr<int> exec_result =
|
||||
ExecProgram(&arena, ast, &trace_stream, &llvm::outs());
|
||||
exec_result.ok()) {
|
||||
// Print the return code to stdout.
|
||||
llvm::outs() << "result: " << *exec_result << "\n";
|
||||
|
||||
Reference in New Issue
Block a user