diff --git a/explorer/interpreter/BUILD b/explorer/interpreter/BUILD index b2ec4791c7a2..169b46857433 100644 --- a/explorer/interpreter/BUILD +++ b/explorer/interpreter/BUILD @@ -43,6 +43,7 @@ cc_library( "//common:error", "//common:ostream", "//explorer/ast", + "//explorer/common:trace_stream", "@llvm-project//llvm:Support", ], ) @@ -87,6 +88,7 @@ cc_library( "//explorer/common:error_builders", "//explorer/common:nonnull", "//explorer/common:source_location", + "//explorer/common:trace_stream", "@llvm-project//llvm:Support", ], ) diff --git a/explorer/interpreter/action_stack.cpp b/explorer/interpreter/action_stack.cpp index f58b77cc8b6f..c6ada2f77929 100644 --- a/explorer/interpreter/action_stack.cpp +++ b/explorer/interpreter/action_stack.cpp @@ -22,7 +22,7 @@ void ActionStack::Print(llvm::raw_ostream& out) const { void ActionStack::Start(std::unique_ptr action) { result_ = std::nullopt; CARBON_CHECK(todo_.empty()); - todo_.Push(std::move(action)); + Push(std::move(action)); } void ActionStack::Initialize(ValueNodeView value_node, @@ -129,7 +129,7 @@ static auto FinishActionKindFor(Action::Kind kind) -> FinishActionKind { auto ActionStack::FinishAction() -> ErrorOr { std::stack> scopes_to_destroy; - std::unique_ptr act = todo_.Pop(); + std::unique_ptr act = Pop(); switch (FinishActionKindFor(act->kind())) { case FinishActionKind::Value: CARBON_FATAL() << "This kind of action must produce a result: " << *act; @@ -147,7 +147,7 @@ auto ActionStack::FinishAction() -> ErrorOr { auto ActionStack::FinishAction(Nonnull result) -> ErrorOr { std::stack> scopes_to_destroy; - std::unique_ptr act = todo_.Pop(); + std::unique_ptr act = Pop(); switch (FinishActionKindFor(act->kind())) { case FinishActionKind::NoValue: CARBON_FATAL() << "This kind of action cannot produce results: " << *act; @@ -166,7 +166,7 @@ auto ActionStack::FinishAction(Nonnull result) auto ActionStack::Spawn(std::unique_ptr child) -> ErrorOr { Action& action = *todo_.Top(); action.set_pos(action.pos() + 1); - todo_.Push(std::move(child)); + Push(std::move(child)); return Success(); } @@ -174,18 +174,18 @@ auto ActionStack::Spawn(std::unique_ptr child, RuntimeScope scope) -> ErrorOr { Action& action = *todo_.Top(); action.set_pos(action.pos() + 1); - todo_.Push(std::make_unique(std::move(scope))); - todo_.Push(std::move(child)); + Push(std::make_unique(std::move(scope))); + Push(std::move(child)); return Success(); } auto ActionStack::ReplaceWith(std::unique_ptr replacement) -> ErrorOr { - std::unique_ptr old = todo_.Pop(); + std::unique_ptr old = Pop(); CARBON_CHECK(FinishActionKindFor(old->kind()) == FinishActionKindFor(replacement->kind())) << "Can't replace action " << *old << " with " << *replacement; - todo_.Push(std::move(replacement)); + Push(std::move(replacement)); return Success(); } @@ -205,7 +205,7 @@ auto ActionStack::UnwindToWithCaptureScopesToDestroy( &statement_action->statement() == ast_node) { break; } - auto item = todo_.Pop(); + auto item = Pop(); auto& scope = item->scope(); if (scope && item->kind() != Action::Kind::CleanUpAction) { std::unique_ptr cleanup_action = std::make_unique( @@ -237,7 +237,7 @@ auto ActionStack::UnwindPastWithCaptureScopesToDestroy( Nonnull ast_node) -> std::stack> { std::stack> scopes_to_destroy = UnwindToWithCaptureScopesToDestroy(ast_node); - auto item = todo_.Pop(); + auto item = Pop(); scopes_to_destroy.push(std::move(item)); PopScopes(scopes_to_destroy); return scopes_to_destroy; @@ -255,7 +255,7 @@ auto ActionStack::UnwindPast(Nonnull ast_node, void ActionStack::PopScopes( std::stack>& cleanup_stack) { while (!todo_.empty() && llvm::isa(*todo_.Top())) { - auto act = todo_.Pop(); + auto act = Pop(); if (act->scope()) { cleanup_stack.push(std::move(act)); } @@ -279,7 +279,7 @@ void ActionStack::PushCleanUpActions( std::unique_ptr cleanup_action = std::make_unique( std::move(*act->scope()), SourceLocation("stack cleanup", 1, FileKind::Unknown)); - todo_.Push(std::move(cleanup_action)); + Push(std::move(cleanup_action)); } actions.pop(); } @@ -292,7 +292,7 @@ void ActionStack::PushCleanUpAction(std::unique_ptr act) { std::unique_ptr cleanup_action = std::make_unique( std::move(*scope), SourceLocation("stack cleanup", 1, FileKind::Unknown)); - todo_.Push(std::move(cleanup_action)); + Push(std::move(cleanup_action)); } } diff --git a/explorer/interpreter/action_stack.h b/explorer/interpreter/action_stack.h index bb6d7aea8871..7a2c4787f205 100644 --- a/explorer/interpreter/action_stack.h +++ b/explorer/interpreter/action_stack.h @@ -12,6 +12,7 @@ #include "common/ostream.h" #include "explorer/ast/statement.h" #include "explorer/ast/value.h" +#include "explorer/common/trace_stream.h" #include "explorer/interpreter/action.h" namespace Carbon { @@ -23,12 +24,16 @@ enum class Phase { CompileTime, RunTime }; class ActionStack { public: // Constructs an empty compile-time ActionStack. - ActionStack() : phase_(Phase::CompileTime) {} + explicit ActionStack(Nonnull trace_stream) + : phase_(Phase::CompileTime), trace_stream_(trace_stream) {} // Constructs an empty run-time ActionStack that allocates global variables // on `heap`. - explicit ActionStack(Nonnull heap) - : globals_(RuntimeScope(heap)), phase_(Phase::RunTime) {} + explicit ActionStack(Nonnull trace_stream, + Nonnull heap) + : globals_(RuntimeScope(heap)), + phase_(Phase::RunTime), + trace_stream_(trace_stream) {} void Print(llvm::raw_ostream& out) const; LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); } @@ -104,7 +109,20 @@ class ActionStack { auto UnwindPast(Nonnull ast_node, Nonnull result) -> ErrorOr; - void Pop() { todo_.Pop(); } + auto Pop() -> std::unique_ptr { + auto popped_action = todo_.Pop(); + if (trace_stream_->is_enabled()) { + *trace_stream_ << "(-) stack-pop: " << *popped_action << "\n"; + } + return popped_action; + } + + void Push(std::unique_ptr action) { + if (trace_stream_->is_enabled()) { + *trace_stream_ << "(+) stack-push: " << *action << "\n"; + } + todo_.Push(std::move(action)); + } auto size() const -> int { return todo_.size(); } @@ -136,6 +154,7 @@ class ActionStack { std::optional> result_; std::optional globals_; Phase phase_; + Nonnull trace_stream_; }; } // namespace Carbon diff --git a/explorer/interpreter/heap.cpp b/explorer/interpreter/heap.cpp index 4abcdf191104..c9279e534d03 100644 --- a/explorer/interpreter/heap.cpp +++ b/explorer/interpreter/heap.cpp @@ -21,12 +21,21 @@ auto Heap::AllocateValue(Nonnull v) -> AllocationId { // to leave it up to the caller. AllocationId a(values_.size()); values_.push_back(v); + bool is_uninitialized = false; + if (v->kind() == Carbon::Value::Kind::UninitializedValue) { states_.push_back(ValueState::Uninitialized); + is_uninitialized = true; } else { states_.push_back(ValueState::Alive); } bound_values_.push_back(llvm::DenseMap{}); + + if (trace_stream_->is_enabled()) { + *trace_stream_ << "(+) memory-alloc: #" << a.index_ << " `" << *v << "`" + << (is_uninitialized ? " uninitialized" : "") << "\n"; + } + return a; } @@ -35,7 +44,15 @@ auto Heap::Read(const Address& a, SourceLocation source_loc) const CARBON_RETURN_IF_ERROR(this->CheckInit(a.allocation_, source_loc)); CARBON_RETURN_IF_ERROR(this->CheckAlive(a.allocation_, source_loc)); Nonnull value = values_[a.allocation_.index_]; - return value->GetElement(arena_, a.element_path_, source_loc, value); + ErrorOr> read_value = + value->GetElement(arena_, a.element_path_, source_loc, value); + + if (trace_stream_->is_enabled()) { + *trace_stream_ << "+++ memory-read: #" << a.allocation_.index_ << " `" + << **read_value << "`\n"; + } + + return read_value; } auto Heap::Write(const Address& a, Nonnull v, @@ -64,6 +81,12 @@ auto Heap::Write(const Address& a, Nonnull v, } } } + + if (trace_stream_->is_enabled()) { + *trace_stream_ << "+++ memory-write: #" << a.allocation_.index_ << " `" + << *values_[a.allocation_.index_] << "`\n"; + } + return Success(); } @@ -95,6 +118,12 @@ auto Heap::Deallocate(AllocationId allocation) -> ErrorOr { CARBON_FATAL() << "deallocating an already dead value: " << *values_[allocation.index_]; } + + if (trace_stream_->is_enabled()) { + *trace_stream_ << "(-) memory-dealloc: #" << allocation.index_ << " `" + << *values_[allocation.index_] << "`\n"; + } + return Success(); } diff --git a/explorer/interpreter/heap.h b/explorer/interpreter/heap.h index 20b975db60dd..d701639c1053 100644 --- a/explorer/interpreter/heap.h +++ b/explorer/interpreter/heap.h @@ -13,6 +13,7 @@ #include "explorer/ast/value_node.h" #include "explorer/common/nonnull.h" #include "explorer/common/source_location.h" +#include "explorer/common/trace_stream.h" #include "explorer/interpreter/heap_allocation_interface.h" namespace Carbon { @@ -28,7 +29,8 @@ class Heap : public HeapAllocationInterface { }; // Constructs an empty Heap. - explicit Heap(Nonnull arena) : arena_(arena){}; + explicit Heap(Nonnull trace_stream, Nonnull arena) + : arena_(arena), trace_stream_(trace_stream){}; Heap(const Heap&) = delete; auto operator=(const Heap&) -> Heap& = delete; @@ -96,6 +98,7 @@ class Heap : public HeapAllocationInterface { std::vector> values_; std::vector states_; std::vector> bound_values_; + Nonnull trace_stream_; }; } // namespace Carbon diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index f3c9dd500914..dc8a14271471 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -48,12 +48,13 @@ static constexpr int64_t MaxStepsTaken = 1e6; static constexpr int64_t MaxArenaAllocated = 1e9; // Constructs an ActionStack suitable for the specified phase. -static auto MakeTodo(Phase phase, Nonnull heap) -> ActionStack { +static auto MakeTodo(Phase phase, Nonnull heap, + Nonnull trace_stream) -> ActionStack { switch (phase) { case Phase::CompileTime: - return ActionStack(); + return ActionStack(trace_stream); case Phase::RunTime: - return ActionStack(heap); + return ActionStack(trace_stream, heap); } } @@ -69,8 +70,8 @@ class Interpreter { Nonnull trace_stream, Nonnull print_stream) : arena_(arena), - heap_(arena), - todo_(MakeTodo(phase, &heap_)), + heap_(trace_stream, arena), + todo_(MakeTodo(phase, &heap_, trace_stream)), trace_stream_(trace_stream), print_stream_(print_stream), phase_(phase) {} @@ -181,8 +182,6 @@ class Interpreter { auto CallDestructor(Nonnull fun, Nonnull receiver) -> ErrorOr; - void TraceState(); - auto phase() const -> Phase { return phase_; } Nonnull arena_; @@ -206,10 +205,6 @@ class Interpreter { // State Operations // -void Interpreter::TraceState() { - *trace_stream_ << "{\nstack: " << todo_ << "\nmemory: " << heap_ << "\n}\n"; -} - auto Interpreter::EvalPrim(Operator op, Nonnull /*static_type*/, const std::vector>& args, SourceLocation source_loc) @@ -651,10 +646,6 @@ auto Interpreter::StepLocation() -> ErrorOr { auto Interpreter::EvalRecursively(std::unique_ptr action) -> ErrorOr> { - if (trace_stream_->is_enabled()) { - TraceState(); - } - todo_.BeginRecursiveAction(); CARBON_RETURN_IF_ERROR(todo_.Spawn(std::move(action))); // Note that the only `RecursiveAction` we can encounter here is our own -- @@ -662,9 +653,6 @@ auto Interpreter::EvalRecursively(std::unique_ptr action) // action is finished and popped off the queue before returning to us. while (!isa(todo_.CurrentAction())) { CARBON_RETURN_IF_ERROR(Step()); - if (trace_stream_->is_enabled()) { - TraceState(); - } } if (trace_stream_->is_enabled()) { *trace_stream_ << "--- recursive eval done\n"; @@ -2766,15 +2754,9 @@ auto Interpreter::Step() -> ErrorOr { auto Interpreter::RunAllSteps(std::unique_ptr action) -> ErrorOr { - if (trace_stream_->is_enabled()) { - TraceState(); - } todo_.Start(std::move(action)); while (!todo_.empty()) { CARBON_RETURN_IF_ERROR(Step()); - if (trace_stream_->is_enabled()) { - TraceState(); - } } return Success(); } diff --git a/explorer/trace_testdata/full_trace.carbon b/explorer/trace_testdata/full_trace.carbon index 7ac1f24a0a79..33abc8133453 100644 --- a/explorer/trace_testdata/full_trace.carbon +++ b/explorer/trace_testdata/full_trace.carbon @@ -14,13 +14,13 @@ // CHECK:STDOUT: } // CHECK:STDOUT: fn Main ()-> i32 { // CHECK:STDOUT: { -// CHECK:STDOUT: return N.Foo(0); +// CHECK:STDOUT: var x: i32 = N.Foo(0); +// CHECK:STDOUT: return x; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: ********** resolving names ********** - package ExplorerTest api; // CHECK:STDOUT: --- declared `TestInterface` as `interface TestInterface` in `package` (full_trace.carbon:[[@LINE+1]]) @@ -36,37 +36,42 @@ fn N.Foo(n: i32) -> i32 { } fn Main() -> i32 { - return N.Foo(0); -// CHECK:STDOUT: --- declared `Main` as `fn Main` in `package` (full_trace.carbon:[[@LINE+440]]) -// CHECK:STDOUT: ** resolving decl `interface TestInterface` (full_trace.carbon:[[@LINE-14]]) + var x: i32 = N.Foo(0); + return x; +// CHECK:STDOUT: --- declared `Main` as `fn Main` in `package` (full_trace.carbon:[[@LINE+310]]) +// CHECK:STDOUT: ** resolving decl `interface TestInterface` (full_trace.carbon:[[@LINE-15]]) // CHECK:STDOUT: --- marked `TestInterface` declared but not usable in `package` // CHECK:STDOUT: --- marked `TestInterface` usable in `package` -// CHECK:STDOUT: --- declared `Self` as `Self` in `interface TestInterface` (full_trace.carbon:[[@LINE-17]]) -// CHECK:STDOUT: ** finished resolving decl `interface TestInterface` (full_trace.carbon:[[@LINE-18]]) -// CHECK:STDOUT: ** resolving decl `namespace N` (full_trace.carbon:[[@LINE-16]]) +// CHECK:STDOUT: --- declared `Self` as `Self` in `interface TestInterface` (full_trace.carbon:[[@LINE-18]]) +// CHECK:STDOUT: ** finished resolving decl `interface TestInterface` (full_trace.carbon:[[@LINE-19]]) +// CHECK:STDOUT: ** resolving decl `namespace N` (full_trace.carbon:[[@LINE-17]]) // CHECK:STDOUT: --- marked `N` usable in `package` -// CHECK:STDOUT: ** finished resolving decl `namespace N` (full_trace.carbon:[[@LINE-18]]) -// CHECK:STDOUT: ** resolving decl `fn N.Foo` (full_trace.carbon:[[@LINE-13]]) -// CHECK:STDOUT: --- resolved `N` as `namespace N` in `package` (full_trace.carbon:[[@LINE-17]]) +// CHECK:STDOUT: ** finished resolving decl `namespace N` (full_trace.carbon:[[@LINE-19]]) +// CHECK:STDOUT: ** resolving decl `fn N.Foo` (full_trace.carbon:[[@LINE-14]]) +// CHECK:STDOUT: --- resolved `N` as `namespace N` in `package` (full_trace.carbon:[[@LINE-18]]) // CHECK:STDOUT: --- marked `Foo` declared but not usable in `namespace N` -// CHECK:STDOUT: --- declared `n` as `n` in `fn N.Foo` (full_trace.carbon:[[@LINE-19]]) +// CHECK:STDOUT: --- declared `n` as `n` in `fn N.Foo` (full_trace.carbon:[[@LINE-20]]) // CHECK:STDOUT: --- marked `Foo` usable in `namespace N` -// CHECK:STDOUT: ** resolving stmt `{return (n + 1);}` (full_trace.carbon:[[@LINE-18]]) -// CHECK:STDOUT: ** resolving stmt `return (n + 1);` (full_trace.carbon:[[@LINE-21]]) -// CHECK:STDOUT: --- resolved `n` as `n` in `fn N.Foo` (full_trace.carbon:[[@LINE-22]]) -// CHECK:STDOUT: ** finished resolving stmt `return (n + 1);` (full_trace.carbon:[[@LINE-23]]) -// CHECK:STDOUT: ** finished resolving stmt `{return (n + 1);}` (full_trace.carbon:[[@LINE-22]]) -// CHECK:STDOUT: ** finished resolving decl `fn N.Foo` (full_trace.carbon:[[@LINE-23]]) -// CHECK:STDOUT: ** resolving decl `fn Main` (full_trace.carbon:[[@LINE+420]]) +// CHECK:STDOUT: ** resolving stmt `{return (n + 1);}` (full_trace.carbon:[[@LINE-19]]) +// CHECK:STDOUT: ** resolving stmt `return (n + 1);` (full_trace.carbon:[[@LINE-22]]) +// CHECK:STDOUT: --- resolved `n` as `n` in `fn N.Foo` (full_trace.carbon:[[@LINE-23]]) +// CHECK:STDOUT: ** finished resolving stmt `return (n + 1);` (full_trace.carbon:[[@LINE-24]]) +// CHECK:STDOUT: ** finished resolving stmt `{return (n + 1);}` (full_trace.carbon:[[@LINE-23]]) +// CHECK:STDOUT: ** finished resolving decl `fn N.Foo` (full_trace.carbon:[[@LINE-24]]) +// CHECK:STDOUT: ** resolving decl `fn Main` (full_trace.carbon:[[@LINE+290]]) // CHECK:STDOUT: --- marked `Main` declared but not usable in `package` // CHECK:STDOUT: --- marked `Main` usable in `package` -// CHECK:STDOUT: ** resolving stmt `{return N.Foo(0);}` (full_trace.carbon:[[@LINE+417]]) -// CHECK:STDOUT: ** resolving stmt `return N.Foo(0);` (full_trace.carbon:[[@LINE-25]]) -// CHECK:STDOUT: --- resolved `N` as `namespace N` in `package` (full_trace.carbon:[[@LINE-26]]) -// CHECK:STDOUT: --- resolved `Foo` as `fn N.Foo` in `namespace N` (full_trace.carbon:[[@LINE-27]]) -// CHECK:STDOUT: ** finished resolving stmt `return N.Foo(0);` (full_trace.carbon:[[@LINE-28]]) -// CHECK:STDOUT: ** finished resolving stmt `{return N.Foo(0);}` (full_trace.carbon:[[@LINE+412]]) -// CHECK:STDOUT: ** finished resolving decl `fn Main` (full_trace.carbon:[[@LINE+411]]) +// CHECK:STDOUT: ** resolving stmt `{var x: i32 = N.Foo(0);return x;}` (full_trace.carbon:[[@LINE+287]]) +// CHECK:STDOUT: ** resolving stmt `var x: i32 = N.Foo(0);` (full_trace.carbon:[[@LINE-26]]) +// CHECK:STDOUT: --- resolved `N` as `namespace N` in `package` (full_trace.carbon:[[@LINE-27]]) +// CHECK:STDOUT: --- resolved `Foo` as `fn N.Foo` in `namespace N` (full_trace.carbon:[[@LINE-28]]) +// CHECK:STDOUT: --- declared `x` as `x` in `{var x: i32 = N.Foo(0);return x;}` (full_trace.carbon:[[@LINE-29]]) +// CHECK:STDOUT: ** finished resolving stmt `var x: i32 = N.Foo(0);` (full_trace.carbon:[[@LINE-30]]) +// CHECK:STDOUT: ** resolving stmt `return x;` (full_trace.carbon:[[@LINE-30]]) +// CHECK:STDOUT: --- resolved `x` as `x` in `{var x: i32 = N.Foo(0);return x;}` (full_trace.carbon:[[@LINE-31]]) +// CHECK:STDOUT: ** finished resolving stmt `return x;` (full_trace.carbon:[[@LINE-32]]) +// CHECK:STDOUT: ** finished resolving stmt `{var x: i32 = N.Foo(0);return x;}` (full_trace.carbon:[[@LINE+278]]) +// CHECK:STDOUT: ** finished resolving decl `fn Main` (full_trace.carbon:[[@LINE+277]]) // CHECK:STDOUT: --- resolved `Main` as `fn Main` in `package` (:0) // CHECK:STDOUT: ********** resolving control flow ********** // CHECK:STDOUT: ********** type checking ********** @@ -83,42 +88,18 @@ fn Main() -> i32 { // CHECK:STDOUT: checking BindingPattern n: i32 // CHECK:STDOUT: checking ExpressionPattern i32 // CHECK:STDOUT: checking IntTypeLiteral i32 -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: i32 .0. ## i32 .1. -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-61]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: i32 .1. {{[[][[]}}i32]] -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } +// CHECK:STDOUT: (+) stack-push: i32 .0. +// CHECK:STDOUT: (+) stack-push: i32 .0. +// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-60]]) ---> +// CHECK:STDOUT: (-) stack-pop: i32 .0. +// CHECK:STDOUT: (-) stack-pop: i32 .1. {{[[][[]}}i32]] // CHECK:STDOUT: finished checking tuple pattern field n: i32 // CHECK:STDOUT: checking IntTypeLiteral i32 -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: i32 .0. ## i32 .1. -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-80]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: i32 .1. {{[[][[]}}i32]] -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } +// CHECK:STDOUT: (+) stack-push: i32 .0. +// CHECK:STDOUT: (+) stack-push: i32 .0. +// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-67]]) ---> +// CHECK:STDOUT: (-) stack-pop: i32 .0. +// CHECK:STDOUT: (-) stack-pop: i32 .1. {{[[][[]}}i32]] // CHECK:STDOUT: ** finished declaring function Foo of type fn (i32,) -> i32 // CHECK:STDOUT: checking FunctionDeclaration // CHECK:STDOUT: ** checking function Foo @@ -136,33 +117,22 @@ fn Main() -> i32 { // CHECK:STDOUT: ** declaring function Main // CHECK:STDOUT: checking TuplePattern () // CHECK:STDOUT: checking IntTypeLiteral i32 -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: i32 .0. ## i32 .1. -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-109]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: i32 .1. {{[[][[]}}i32]] -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory:{{ }} -// CHECK:STDOUT: } +// CHECK:STDOUT: (+) stack-push: i32 .0. +// CHECK:STDOUT: (+) stack-push: i32 .0. +// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-84]]) ---> +// CHECK:STDOUT: (-) stack-pop: i32 .0. +// CHECK:STDOUT: (-) stack-pop: i32 .1. {{[[][[]}}i32]] // CHECK:STDOUT: ** finished declaring function Main of type fn () -> i32 // CHECK:STDOUT: checking FunctionDeclaration // CHECK:STDOUT: ** checking function Main // CHECK:STDOUT: impl declarations:{{ }} // CHECK:STDOUT: impl declarations: bool as interface EqWith(U = bool), i32 as interface EqWith(U = i32), String as interface EqWith(U = String), i32 as interface CompareWith(U = i32), String as interface CompareWith(U = String), i32 as interface LessWith(U = i32), String as interface LessWith(U = String), i32 as interface LessEqWith(U = i32), String as interface LessEqWith(U = String), i32 as interface GreaterWith(U = i32), String as interface GreaterWith(U = String), i32 as interface GreaterEqWith(U = i32), String as interface GreaterEqWith(U = String), i32 as interface Negate, i32 as interface AddWith(U = i32), i32 as interface SubWith(U = i32), i32 as interface MulWith(U = i32), i32 as interface DivWith(U = i32), i32 as interface ModWith(U = i32), i32 as interface BitComplement, i32 as interface BitAndWith(U = i32), i32 as interface BitOrWith(U = i32), i32 as interface BitXorWith(U = i32), i32 as interface LeftShiftWith(U = i32), i32 as interface RightShiftWith(U = i32), i32 as interface Inc, i32 as interface Dec, U as interface __EqualConverter [0], (T1,) as interface As(T = (U1,)) [0, 0, 0; 1, 1, 0, 0, 0], (T1, T2) as interface As(T = (U1, U2)) [0, 0, 0; 0, 0, 1; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1], (T1, U1) as interface EqWith(U = (T2, U2)) [0, 0, 0; 0, 0, 1; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1], (T1, T2, T3) as interface As(T = (U1, U2, U3)) [0, 0, 0; 0, 0, 1; 0, 0, 2; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1; 1, 1, 0, 0, 2], T as interface ImplicitAs(T = U) [0; 1, 1, 0], T as interface As(T = U) [0; 1, 1, 0], T as interface ImplicitAs(T = U) [0; 1, 1, 0], T as interface As(T = U) [0; 1, 1, 0], T as interface AssignWith(U = U) [0; 1, 1, 0], T as interface AddAssignWith(U = U) [0; 1, 1, 0], T as interface SubAssignWith(U = U) [0; 1, 1, 0], T as interface MulAssignWith(U = U) [0; 1, 1, 0], T as interface DivAssignWith(U = U) [0; 1, 1, 0], T as interface ModAssignWith(U = U) [0; 1, 1, 0], T as interface BitAndAssignWith(U = U) [0; 1, 1, 0], T as interface BitOrAssignWith(U = U) [0; 1, 1, 0], T as interface BitXorAssignWith(U = U) [0; 1, 1, 0], T as interface LeftShiftAssignWith(U = U) [0; 1, 1, 0], T as interface RightShiftAssignWith(U = U) [0; 1, 1, 0] // CHECK:STDOUT: checking Block { -// CHECK:STDOUT: return N.Foo(0); +// CHECK:STDOUT: var x: i32 = N.Foo(0); +// CHECK:STDOUT: return x; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: checking ReturnExpression return N.Foo(0); +// CHECK:STDOUT: checking VariableDefinition var x: i32 = N.Foo(0); // CHECK:STDOUT: checking CallExpression N.Foo(0) // CHECK:STDOUT: checking SimpleMemberAccessExpression N.Foo // CHECK:STDOUT: checking IdentifierExpression Foo @@ -173,6 +143,16 @@ fn Main() -> i32 { // CHECK:STDOUT: performing argument deduction for bindings:{{ }} // CHECK:STDOUT: deducing i32 from i32 // CHECK:STDOUT: deduction succeeded with results: {} +// CHECK:STDOUT: checking BindingPattern x: i32, expecting i32 +// CHECK:STDOUT: checking ExpressionPattern i32, expecting i32 +// CHECK:STDOUT: checking IntTypeLiteral i32 +// CHECK:STDOUT: (+) stack-push: i32 .0. +// CHECK:STDOUT: (+) stack-push: i32 .0. +// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-112]]) ---> +// CHECK:STDOUT: (-) stack-pop: i32 .0. +// CHECK:STDOUT: (-) stack-pop: i32 .1. {{[[][[]}}i32]] +// CHECK:STDOUT: checking ReturnExpression return x; +// CHECK:STDOUT: checking IdentifierExpression x // CHECK:STDOUT: ** finished checking function Main // CHECK:STDOUT: checking CallExpression Main() // CHECK:STDOUT: checking IdentifierExpression Main @@ -193,283 +173,174 @@ fn Main() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: fn Main ()-> i32 { // CHECK:STDOUT: { -// CHECK:STDOUT: return N.Foo(0); +// CHECK:STDOUT: var x: i32 = N.Foo(0); +// CHECK:STDOUT: return x; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: ********** starting execution ********** // CHECK:STDOUT: ********** initializing globals ********** -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: (+) stack-push: interface TestInterface { // CHECK:STDOUT: } -// CHECK:STDOUT: --- step decl interface TestInterface .0. (full_trace.carbon:[[@LINE-179]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: .0. +// CHECK:STDOUT: --- step decl interface TestInterface .0. (full_trace.carbon:[[@LINE-159]]) ---> +// CHECK:STDOUT: (-) stack-pop: interface TestInterface { // CHECK:STDOUT: } +// CHECK:STDOUT: .0. +// CHECK:STDOUT: (+) stack-push: namespace N; .0. +// CHECK:STDOUT: --- step decl namespace N .0. (full_trace.carbon:[[@LINE-161]]) ---> +// CHECK:STDOUT: (-) stack-pop: namespace N; .0. +// CHECK:STDOUT: (+) stack-push: fn Foo (n: i32)-> i32 { // CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: return (n + 1); // CHECK:STDOUT: } -// CHECK:STDOUT: --- step decl namespace N .0. (full_trace.carbon:[[@LINE-185]]) ---> +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: .0. +// CHECK:STDOUT: --- step decl fn N.Foo .0. (full_trace.carbon:[[@LINE-164]]) ---> +// CHECK:STDOUT: (-) stack-pop: fn Foo (n: i32)-> i32 { // CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: return (n + 1); // CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: .0. +// CHECK:STDOUT: (+) stack-push: fn Main ()-> i32 { // CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: var x: i32 = N.Foo(0); +// CHECK:STDOUT: return x; // CHECK:STDOUT: } -// CHECK:STDOUT: --- step decl fn N.Foo .0. (full_trace.carbon:[[@LINE-188]]) ---> +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: .0. +// CHECK:STDOUT: --- step decl fn Main .0. (full_trace.carbon:[[@LINE+135]]) ---> +// CHECK:STDOUT: (-) stack-pop: fn Main ()-> i32 { // CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: var x: i32 = N.Foo(0); +// CHECK:STDOUT: return x; // CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step decl fn Main .0. (full_trace.carbon:[[@LINE+247]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: // CHECK:STDOUT: } +// CHECK:STDOUT: .0. // CHECK:STDOUT: ********** calling main function ********** -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main() .0. ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } +// CHECK:STDOUT: (+) stack-push: Main() .0. +// CHECK:STDOUT: (+) stack-push: Main() .0. // CHECK:STDOUT: --- step exp Main() .0. (:0) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main .0. ## Main() .1. ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main .0. ## Main .1. ## Main() .1. ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } +// CHECK:STDOUT: (+) stack-push: Main .0. +// CHECK:STDOUT: (+) stack-push: Main .0. // CHECK:STDOUT: --- step exp Main .0. (:0) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main .1. {{[[][[]}}fun
]] ## Main() .1. ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main() .1. {{[[][[]}}fun
]] ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } +// CHECK:STDOUT: (-) stack-pop: Main .0. +// CHECK:STDOUT: (-) stack-pop: Main .1. {{[[][[]}}fun
]] // CHECK:STDOUT: --- step exp Main() .1. (:0) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: () .0. ## Main() .2. {{[[][[]}}fun
]] ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } +// CHECK:STDOUT: (+) stack-push: () .0. // CHECK:STDOUT: --- step exp () .0. (:0) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main() .2. {{[[][[]}}fun
, ()]] ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } +// CHECK:STDOUT: (-) stack-pop: () .0. // CHECK:STDOUT: --- step exp Main() .2. (:0) ---> // CHECK:STDOUT: calling function: fun
// CHECK:STDOUT: match pattern () // CHECK:STDOUT: from value expression with value () -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: {return N.Foo(0);} .0. ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step stmt {return N.Foo(0);} .0. (full_trace.carbon:[[@LINE+197]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: return N.Foo(0); .0. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step stmt return N.Foo(0); .0. (full_trace.carbon:[[@LINE-249]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: N.Foo(0) .0. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: N.Foo(0) .0. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp N.Foo(0) .0. (full_trace.carbon:[[@LINE-258]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: N.Foo .0. ## N.Foo(0) .1. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: N.Foo .0. ## N.Foo .1. ## N.Foo(0) .1. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp N.Foo .0. (full_trace.carbon:[[@LINE-267]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: Foo .0. ## N.Foo .1. ## N.Foo(0) .1. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp Foo .0. (full_trace.carbon:[[@LINE-272]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: N.Foo .1. {{[[][[]}}fun]] ## N.Foo(0) .1. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: N.Foo(0) .1. {{[[][[]}}fun]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp N.Foo(0) .1. (full_trace.carbon:[[@LINE-281]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: (0) .0. ## N.Foo(0) .2. {{[[][[]}}fun]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp (0) .0. (full_trace.carbon:[[@LINE-286]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: 0 .0. ## (0) .1. ## N.Foo(0) .2. {{[[][[]}}fun]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp 0 .0. (full_trace.carbon:[[@LINE-291]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: (0) .1. {{[[][[]}}0]] ## N.Foo(0) .2. {{[[][[]}}fun]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp (0) .1. (full_trace.carbon:[[@LINE-296]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: N.Foo(0) .2. {{[[][[]}}fun, (0,)]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{} -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp N.Foo(0) .2. (full_trace.carbon:[[@LINE-301]]) ---> +// CHECK:STDOUT: (+) stack-push: .0. {} +// CHECK:STDOUT: (+) stack-push: {var x: i32 = N.Foo(0);return x;} .0. +// CHECK:STDOUT: --- step stmt {var x: i32 = N.Foo(0);return x;} .0. (full_trace.carbon:[[@LINE+107]]) ---> +// CHECK:STDOUT: (+) stack-push: var x: i32 = N.Foo(0); .0. +// CHECK:STDOUT: --- step stmt var x: i32 = N.Foo(0); .0. (full_trace.carbon:[[@LINE-207]]) ---> +// CHECK:STDOUT: (+) memory-alloc: #1 `Uninit` uninitialized +// CHECK:STDOUT: (+) stack-push: N.Foo(0) .0. +// CHECK:STDOUT: --- step exp N.Foo(0) .0. (full_trace.carbon:[[@LINE-210]]) ---> +// CHECK:STDOUT: (+) stack-push: N.Foo .0. +// CHECK:STDOUT: (+) stack-push: N.Foo .0. +// CHECK:STDOUT: --- step exp N.Foo .0. (full_trace.carbon:[[@LINE-213]]) ---> +// CHECK:STDOUT: (-) stack-pop: N.Foo .0. +// CHECK:STDOUT: (+) stack-push: Foo .0. +// CHECK:STDOUT: --- step exp Foo .0. (full_trace.carbon:[[@LINE-216]]) ---> +// CHECK:STDOUT: (-) stack-pop: Foo .0. +// CHECK:STDOUT: (-) stack-pop: N.Foo .1. {{[[][[]}}fun]] +// CHECK:STDOUT: --- step exp N.Foo(0) .1. (full_trace.carbon:[[@LINE-219]]) ---> +// CHECK:STDOUT: (+) stack-push: (0) .0. +// CHECK:STDOUT: --- step exp (0) .0. (full_trace.carbon:[[@LINE-221]]) ---> +// CHECK:STDOUT: (+) stack-push: 0 .0. +// CHECK:STDOUT: --- step exp 0 .0. (full_trace.carbon:[[@LINE-223]]) ---> +// CHECK:STDOUT: (-) stack-pop: 0 .0. +// CHECK:STDOUT: --- step exp (0) .1. (full_trace.carbon:[[@LINE-225]]) ---> +// CHECK:STDOUT: (-) stack-pop: (0) .1. {{[[][[]}}0]] +// CHECK:STDOUT: --- step exp N.Foo(0) .2. (full_trace.carbon:[[@LINE-227]]) ---> // CHECK:STDOUT: calling function: fun // CHECK:STDOUT: match pattern (Placeholder,) // CHECK:STDOUT: from value expression with value (0,) // CHECK:STDOUT: match pattern Placeholder // CHECK:STDOUT: from value expression with value 0 -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: {return (n + 1);} .0. ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step stmt {return (n + 1);} .0. (full_trace.carbon:[[@LINE-314]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: return (n + 1); .0. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step stmt return (n + 1); .0. (full_trace.carbon:[[@LINE-321]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: (n + 1) .0. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: (n + 1) .0. ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp (n + 1) .0. (full_trace.carbon:[[@LINE-330]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: n .0. ## (n + 1) .1. ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: n .0. ## n .1. ## (n + 1) .1. ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp n .0. (full_trace.carbon:[[@LINE-339]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: n .1. {{[[][[]}}0]] ## (n + 1) .1. ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: (n + 1) .1. {{[[][[]}}0]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp (n + 1) .1. (full_trace.carbon:[[@LINE-348]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: 1 .0. ## (n + 1) .2. {{[[][[]}}0]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: 1 .0. ## 1 .1. ## (n + 1) .2. {{[[][[]}}0]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp 1 .0. (full_trace.carbon:[[@LINE-357]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: 1 .1. {{[[][[]}}1]] ## (n + 1) .2. {{[[][[]}}0]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: (n + 1) .2. {{[[][[]}}0, 1]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp (n + 1) .2. (full_trace.carbon:[[@LINE-366]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: (n + 1) .1. {{[[][[]}}1]] ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: return (n + 1); .1. {{[[][[]}}1]] ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step stmt return (n + 1); .1. (full_trace.carbon:[[@LINE-375]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.0. {} ## clean up.0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: destroy.0. ## clean up.1. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.1. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.2. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp N.Foo(0) .3. (full_trace.carbon:[[@LINE-395]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.0. {} ## N.Foo(0) .1. {{[[][[]}}1]] ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: N.Foo(0) .1. {{[[][[]}}1]] ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: return N.Foo(0); .1. {{[[][[]}}1]] ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } -// CHECK:STDOUT: --- step stmt return N.Foo(0); .1. (full_trace.carbon:[[@LINE-408]]) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.0. {} ## clean up.0. {} ## Main() .3. {{[[][[]}}fun
, (), 1]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.0. {} ## Main() .3. {{[[][[]}}fun
, (), 1]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main() .3. {{[[][[]}}fun
, (), 1]] {} ## Main() .1. -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } +// CHECK:STDOUT: (+) memory-alloc: #2 `0` +// CHECK:STDOUT: (+) stack-push: .0. {n: i32: lval} +// CHECK:STDOUT: (+) stack-push: {return (n + 1);} .0. +// CHECK:STDOUT: --- step stmt {return (n + 1);} .0. (full_trace.carbon:[[@LINE-239]]) ---> +// CHECK:STDOUT: (+) stack-push: return (n + 1); .0. +// CHECK:STDOUT: --- step stmt return (n + 1); .0. (full_trace.carbon:[[@LINE-243]]) ---> +// CHECK:STDOUT: (+) stack-push: (n + 1) .0. +// CHECK:STDOUT: (+) stack-push: (n + 1) .0. +// CHECK:STDOUT: --- step exp (n + 1) .0. (full_trace.carbon:[[@LINE-246]]) ---> +// CHECK:STDOUT: (+) stack-push: n .0. +// CHECK:STDOUT: (+) stack-push: n .0. +// CHECK:STDOUT: --- step exp n .0. (full_trace.carbon:[[@LINE-249]]) ---> +// CHECK:STDOUT: +++ memory-read: #2 `0` +// CHECK:STDOUT: (-) stack-pop: n .0. +// CHECK:STDOUT: (-) stack-pop: n .1. {{[[][[]}}0]] +// CHECK:STDOUT: --- step exp (n + 1) .1. (full_trace.carbon:[[@LINE-253]]) ---> +// CHECK:STDOUT: (+) stack-push: 1 .0. +// CHECK:STDOUT: (+) stack-push: 1 .0. +// CHECK:STDOUT: --- step exp 1 .0. (full_trace.carbon:[[@LINE-256]]) ---> +// CHECK:STDOUT: (-) stack-pop: 1 .0. +// CHECK:STDOUT: (-) stack-pop: 1 .1. {{[[][[]}}1]] +// CHECK:STDOUT: --- step exp (n + 1) .2. (full_trace.carbon:[[@LINE-259]]) ---> +// CHECK:STDOUT: (-) stack-pop: (n + 1) .2. {{[[][[]}}0, 1]] +// CHECK:STDOUT: (-) stack-pop: (n + 1) .1. {{[[][[]}}1]] +// CHECK:STDOUT: --- step stmt return (n + 1); .1. (full_trace.carbon:[[@LINE-262]]) ---> +// CHECK:STDOUT: +++ memory-write: #1 `1` +// CHECK:STDOUT: (-) stack-pop: return (n + 1); .1. {{[[][[]}}1]] +// CHECK:STDOUT: (-) stack-pop: {return (n + 1);} .1. {} +// CHECK:STDOUT: (-) stack-pop: .0. {n: i32: lval} +// CHECK:STDOUT: (+) stack-push: clean up.0. {n: i32: lval} +// CHECK:STDOUT: (+) stack-push: clean up.0. {} +// CHECK:STDOUT: (-) stack-pop: clean up.0. {} +// CHECK:STDOUT: +++ memory-read: #2 `0` +// CHECK:STDOUT: (+) stack-push: destroy.0. +// CHECK:STDOUT: (-) stack-pop: destroy.0. +// CHECK:STDOUT: (-) memory-dealloc: #2 `0` +// CHECK:STDOUT: (-) stack-pop: clean up.2. {n: i32: lval} +// CHECK:STDOUT: --- step exp N.Foo(0) .3. (full_trace.carbon:[[@LINE-270]]) ---> +// CHECK:STDOUT: (-) stack-pop: N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} +// CHECK:STDOUT: (+) stack-push: clean up.0. {} +// CHECK:STDOUT: (-) stack-pop: clean up.0. {} +// CHECK:STDOUT: --- step stmt var x: i32 = N.Foo(0); .1. (full_trace.carbon:[[@LINE-274]]) ---> +// CHECK:STDOUT: +++ memory-read: #1 `1` +// CHECK:STDOUT: match pattern Placeholder +// CHECK:STDOUT: from initializing expression with value 1 +// CHECK:STDOUT: (-) stack-pop: var x: i32 = N.Foo(0); .1. {{[[][[]}}1]] +// CHECK:STDOUT: --- step stmt {var x: i32 = N.Foo(0);return x;} .1. (full_trace.carbon:[[@LINE+33]]) ---> +// CHECK:STDOUT: (+) stack-push: return x; .0. +// CHECK:STDOUT: --- step stmt return x; .0. (full_trace.carbon:[[@LINE-280]]) ---> +// CHECK:STDOUT: (+) stack-push: x .0. +// CHECK:STDOUT: (+) stack-push: x .0. +// CHECK:STDOUT: --- step exp x .0. (full_trace.carbon:[[@LINE-283]]) ---> +// CHECK:STDOUT: +++ memory-read: #1 `1` +// CHECK:STDOUT: (-) stack-pop: x .0. +// CHECK:STDOUT: (-) stack-pop: x .1. {{[[][[]}}ref_expr]] +// CHECK:STDOUT: --- step stmt return x; .1. (full_trace.carbon:[[@LINE-287]]) ---> +// CHECK:STDOUT: (-) stack-pop: return x; .1. {{[[][[]}}1]] +// CHECK:STDOUT: (-) stack-pop: {var x: i32 = N.Foo(0);return x;} .2. {x: i32: lval} +// CHECK:STDOUT: (-) stack-pop: .0. {} +// CHECK:STDOUT: (+) stack-push: clean up.0. {} +// CHECK:STDOUT: (+) stack-push: clean up.0. {x: i32: lval} +// CHECK:STDOUT: +++ memory-read: #1 `1` +// CHECK:STDOUT: (+) stack-push: destroy.0. +// CHECK:STDOUT: (-) stack-pop: destroy.0. +// CHECK:STDOUT: (-) memory-dealloc: #1 `1` +// CHECK:STDOUT: (-) stack-pop: clean up.2. {x: i32: lval} +// CHECK:STDOUT: (-) stack-pop: clean up.0. {} // CHECK:STDOUT: --- step exp Main() .3. (:0) ---> -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.0. {} ## Main() .1. {{[[][[]}}1]] -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main() .1. {{[[][[]}}1]] -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } -// CHECK:STDOUT: { -// CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 -// CHECK:STDOUT: } +// CHECK:STDOUT: (-) stack-pop: Main() .3. {{[[][[]}}fun
, (), 1]] {} +// CHECK:STDOUT: (+) stack-push: clean up.0. {} +// CHECK:STDOUT: (-) stack-pop: clean up.0. {} +// CHECK:STDOUT: (-) stack-pop: Main() .1. {{[[][[]}}1]] // CHECK:STDOUT: interpreter result: 1 // CHECK:STDOUT: ********** printing timing ********** // CHECK:STDOUT: Time elapsed in ExecProgram: {{[0-9]+}}ms