@@ -27,6 +27,91 @@ using llvm::isa;
27
27
28
28
namespace Carbon {
29
29
30
+ // Selects between compile-time and run-time behavior.
31
+ enum class Phase { CompileTime, RunTime };
32
+
33
+ // Constructs an ActionStack suitable for the specified phase.
34
+ static auto MakeTodo (Phase phase, Nonnull<Heap*> heap) -> ActionStack {
35
+ switch (phase) {
36
+ case Phase::CompileTime:
37
+ return ActionStack ();
38
+ case Phase::RunTime:
39
+ return ActionStack (heap);
40
+ }
41
+ }
42
+
43
+ // An Interpreter represents an instance of the Carbon abstract machine. It
44
+ // manages the state of the abstract machine, and executes the steps of Actions
45
+ // passed to it.
46
+ class Interpreter {
47
+ public:
48
+ // Constructs an Interpreter which allocates values on `arena`, and prints
49
+ // traces if `trace` is true. `phase` indicates whether it executes at
50
+ // compile time or run time.
51
+ Interpreter (Phase phase, Nonnull<Arena*> arena, bool trace)
52
+ : arena_(arena),
53
+ heap_ (arena),
54
+ todo_(MakeTodo(phase, &heap_)),
55
+ trace_(trace) {}
56
+
57
+ ~Interpreter ();
58
+
59
+ // Runs all the steps of `action`.
60
+ void RunAllSteps (std::unique_ptr<Action> action);
61
+
62
+ // The result produced by the `action` argument of the most recent
63
+ // RunAllSteps call. Cannot be called if `action` was an action that doesn't
64
+ // produce results.
65
+ auto result () const -> Nonnull<const Value*> { return todo_.result (); }
66
+
67
+ private:
68
+ void Step ();
69
+
70
+ // State transitions for expressions.
71
+ void StepExp ();
72
+ // State transitions for lvalues.
73
+ void StepLvalue ();
74
+ // State transitions for patterns.
75
+ void StepPattern ();
76
+ // State transition for statements.
77
+ void StepStmt ();
78
+ // State transition for declarations.
79
+ void StepDeclaration ();
80
+
81
+ auto CreateStruct (const std::vector<FieldInitializer>& fields,
82
+ const std::vector<Nonnull<const Value*>>& values)
83
+ -> Nonnull<const Value*>;
84
+
85
+ auto EvalPrim (Operator op, const std::vector<Nonnull<const Value*>>& args,
86
+ SourceLocation source_loc) -> Nonnull<const Value*>;
87
+
88
+ // Returns the result of converting `value` to type `destination_type`.
89
+ auto Convert (Nonnull<const Value*> value,
90
+ Nonnull<const Value*> destination_type) const
91
+ -> Nonnull<const Value*>;
92
+
93
+ void PrintState (llvm::raw_ostream& out);
94
+
95
+ Nonnull<Arena*> arena_;
96
+
97
+ Heap heap_;
98
+ ActionStack todo_;
99
+
100
+ // The underlying states of continuation values. All StackFragments created
101
+ // during execution are tracked here, in order to safely deallocate the
102
+ // contents of any non-completed continuations at the end of execution.
103
+ std::vector<Nonnull<ContinuationValue::StackFragment*>> stack_fragments_;
104
+
105
+ bool trace_;
106
+ };
107
+
108
+ Interpreter::~Interpreter () {
109
+ // Clean up any remaining suspended continuations.
110
+ for (Nonnull<ContinuationValue::StackFragment*> fragment : stack_fragments_) {
111
+ fragment->Clear ();
112
+ }
113
+ }
114
+
30
115
//
31
116
// State Operations
32
117
//
@@ -85,10 +170,9 @@ auto Interpreter::CreateStruct(const std::vector<FieldInitializer>& fields,
85
170
return arena_->New <StructValue>(std::move (elements));
86
171
}
87
172
88
- auto Interpreter::PatternMatch (Nonnull<const Value*> p, Nonnull<const Value*> v,
89
- SourceLocation source_loc,
90
- std::optional<Nonnull<RuntimeScope*>> bindings)
91
- -> bool {
173
+ auto PatternMatch (Nonnull<const Value*> p, Nonnull<const Value*> v,
174
+ SourceLocation source_loc,
175
+ std::optional<Nonnull<RuntimeScope*>> bindings) -> bool {
92
176
switch (p->kind ()) {
93
177
case Value::Kind::BindingPlaceholderValue: {
94
178
if (!bindings.has_value ()) {
@@ -864,59 +948,50 @@ void Interpreter::Step() {
864
948
} // switch
865
949
}
866
950
867
- void Interpreter::RunAllSteps (bool trace_steps) {
951
+ void Interpreter::RunAllSteps (std::unique_ptr<Action> action) {
952
+ if (trace_) {
953
+ PrintState (llvm::outs ());
954
+ }
955
+ todo_.Start (std::move (action));
868
956
while (!todo_.IsEmpty ()) {
869
957
Step ();
870
- if (trace_steps ) {
958
+ if (trace_ ) {
871
959
PrintState (llvm::outs ());
872
960
}
873
961
}
874
962
}
875
963
876
- auto Interpreter::InterpProgram (const AST& ast) -> int {
877
- todo_.SetHeap (&heap_);
878
-
879
- if (trace_) {
964
+ auto InterpProgram (const AST& ast, Nonnull<Arena*> arena, bool trace) -> int {
965
+ Interpreter interpreter (Phase::RunTime, arena, trace);
966
+ if (trace) {
880
967
llvm::outs () << " ********** initializing globals **********\n " ;
881
968
}
882
969
883
970
for (Nonnull<Declaration*> declaration : ast.declarations ) {
884
- todo_.Start (std::make_unique<DeclarationAction>(declaration));
885
- RunAllSteps (trace_);
971
+ interpreter.RunAllSteps (std::make_unique<DeclarationAction>(declaration));
886
972
}
887
973
888
- if (trace_ ) {
974
+ if (trace ) {
889
975
llvm::outs () << " ********** calling main function **********\n " ;
890
- PrintState (llvm::outs ());
891
976
}
892
977
893
- todo_.Start (std::make_unique<ExpressionAction>(*ast.main_call ));
894
- RunAllSteps (trace_);
978
+ interpreter.RunAllSteps (std::make_unique<ExpressionAction>(*ast.main_call ));
895
979
896
- // Clean up any remaining suspended continuations.
897
- for (Nonnull<ContinuationValue::StackFragment*> fragment : stack_fragments_) {
898
- fragment->Clear ();
899
- }
900
-
901
- return cast<IntValue>(*todo_.result ()).value ();
902
- }
903
-
904
- auto Interpreter::RunCompileTimeAction (std::unique_ptr<Action> action)
905
- -> Nonnull<const Value*> {
906
- todo_.Start (std::move (action));
907
- RunAllSteps (/* trace_steps=*/ false );
908
- CHECK (stack_fragments_.empty ());
909
- return todo_.result ();
980
+ return cast<IntValue>(*interpreter.result ()).value ();
910
981
}
911
982
912
- auto Interpreter:: InterpExp (Nonnull<const Expression*> e)
983
+ auto InterpExp (Nonnull<const Expression*> e, Nonnull<Arena*> arena, bool trace )
913
984
-> Nonnull<const Value*> {
914
- return RunCompileTimeAction (std::make_unique<ExpressionAction>(e));
985
+ Interpreter interpreter (Phase::CompileTime, arena, trace);
986
+ interpreter.RunAllSteps (std::make_unique<ExpressionAction>(e));
987
+ return interpreter.result ();
915
988
}
916
989
917
- auto Interpreter:: InterpPattern (Nonnull<const Pattern*> p)
990
+ auto InterpPattern (Nonnull<const Pattern*> p, Nonnull<Arena*> arena, bool trace )
918
991
-> Nonnull<const Value*> {
919
- return RunCompileTimeAction (std::make_unique<PatternAction>(p));
992
+ Interpreter interpreter (Phase::CompileTime, arena, trace);
993
+ interpreter.RunAllSteps (std::make_unique<PatternAction>(p));
994
+ return interpreter.result ();
920
995
}
921
996
922
997
} // namespace Carbon
0 commit comments