1
2
3 :(scenario calling_recipe)
4 def main [
5 f
6 ]
7 def f [
8 3:num <- add 2, 2
9 ]
10 +mem: storing 4 in location 3
11
12 :(scenario return_on_fallthrough)
13 def main [
14 f
15 1:num <- copy 0
16 2:num <- copy 0
17 3:num <- copy 0
18 ]
19 def f [
20 4:num <- copy 0
21 5:num <- copy 0
22 ]
23 +run: f
24
25 +run: {4: "number"} <- copy {0: "literal"}
26 +run: {5: "number"} <- copy {0: "literal"}
27
28 +run: {1: "number"} <- copy {0: "literal"}
29 +run: {2: "number"} <- copy {0: "literal"}
30 +run: {3: "number"} <- copy {0: "literal"}
31
32 :(before "struct routine {")
33
34
35
36 struct call {
37 recipe_ordinal running_recipe;
38 int running_step_index;
39
40 call(recipe_ordinal r) {
41 ¦ running_recipe = r;
42 ¦ running_step_index = 0;
43 ¦
44 }
45 ~call() {
46 ¦
47 }
48 };
49 typedef list<call> call_stack;
50
51 :(replace{} "struct routine")
52 struct routine {
53 call_stack calls;
54
55 routine(recipe_ordinal r);
56 bool completed() const;
57 const vector<instruction>& steps() const;
58 };
59 :(code)
60 routine::routine(recipe_ordinal r) {
61 if (Trace_stream) {
62 ¦ ++Trace_stream->callstack_depth;
63 ¦ trace(9999, "trace") << "new routine; incrementing callstack depth to " << Trace_stream->callstack_depth << end();
64 ¦ assert(Trace_stream->callstack_depth < 9000);
65 }
66 calls.push_front(call(r));
67
68 }
69
70
71
72 :(delete{} "int& current_step_index()")
73 :(delete{} "recipe_ordinal currently_running_recipe()")
74 :(delete{} "const string& current_recipe_name()")
75 :(delete{} "const recipe& current_recipe()")
76 :(delete{} "const instruction& current_instruction()")
77
78 :(before "End Includes")
79 #define current_call() Current_routine->calls.front()
80 #define current_step_index() current_call().running_step_index
81 #define currently_running_recipe() current_call().running_recipe
82 #define current_recipe() get(Recipe, currently_running_recipe())
83 #define current_recipe_name() current_recipe().name
84 #define to_instruction(call) get(Recipe, (call).running_recipe).steps.at((call).running_step_index)
85 #define current_instruction() to_instruction(current_call())
86
87 :(after "Defined Recipe Checks")
88
89 if (!contains_key(Recipe, inst.operation)) {
90 raise << maybe(get(Recipe, r).name) << "undefined operation in '" << to_original_string(inst) << "'\n" << end();
91 break;
92 }
93 :(replace{} "default:" following "End Primitive Recipe Implementations")
94 default: {
95 if (contains_key(Recipe, current_instruction().operation)) {
96 ¦
97 ¦ if (Trace_stream) {
98 ¦ ¦ ++Trace_stream->callstack_depth;
99 ¦ ¦ trace(9999, "trace") << "incrementing callstack depth to " << Trace_stream->callstack_depth << end();
100 ¦ ¦ assert(Trace_stream->callstack_depth < 9000);
101 ¦ }
102 ¦ const call& caller_frame = current_call();
103 ¦ Current_routine->calls.push_front(call(to_instruction(caller_frame).operation));
104 ¦ finish_call_housekeeping(to_instruction(caller_frame), ingredients);
105 ¦
106 ¦ write_products = false;
107 ¦ fall_through_to_next_instruction = false;
108 ¦
109 }
110 }
111 :(code)
112 void finish_call_housekeeping(const instruction& call_instruction, const vector<vector<double> >& ingredients) {
113
114 }
115
116 :(scenario calling_undefined_recipe_fails)
117 % Hide_errors = true;
118 def main [
119 foo
120 ]
121 +error: main: undefined operation in 'foo'
122
123 :(scenario calling_undefined_recipe_handles_missing_result)
124 % Hide_errors = true;
125 def main [
126 x:num <- foo
127 ]
128 +error: main: undefined operation in 'x:num <- foo'
129
130
131
132 :(replace{} "bool routine::completed() const")
133 bool routine::completed() const {
134 return calls.empty();
135 }
136
137 :(replace{} "const vector<instruction>& routine::steps() const")
138 const vector<instruction>& routine::steps() const {
139 assert(!calls.empty());
140 return get(Recipe, calls.front().running_recipe).steps;
141 }
142
143 :(after "Running One Instruction")
144
145
146 while (current_step_index() >= SIZE(Current_routine->steps())) {
147
148 if (Trace_stream) {
149 ¦ trace(9999, "trace") << "fall-through: exiting " << current_recipe_name() << "; decrementing callstack depth from " << Trace_stream->callstack_depth << end();
150 ¦ --Trace_stream->callstack_depth;
151 ¦ assert(Trace_stream->callstack_depth >= 0);
152 }
153 Current_routine->calls.pop_front();
154 if (Current_routine->calls.empty()) goto stop_running_current_routine;
155
156
157 ++current_step_index();
158 }