:(scenario copy_literal)
def main [
1:num <- copy 23
]
+run: {1: "number"} <- copy {23: "literal"}
+mem: storing 23 in location 1
:(scenario copy)
def main [
1:num <- copy 23
2:num <- copy 1:num
]
+run: {2: "number"} <- copy {1: "number"}
+mem: location 1 is 23
+mem: storing 23 in location 2
:(scenario copy_multiple)
def main [
1:num, 2:num <- copy 23, 24
]
+mem: storing 23 in location 1
+mem: storing 24 in location 2
:(before "End Types")
struct routine {
recipe_ordinal running_recipe;
int running_step_index;
routine(recipe_ordinal r) :running_recipe(r), running_step_index(0) {}
bool completed() const;
const vector<instruction>& steps() const;
};
:(before "End Globals")
routine* Current_routine = NULL;
map<string, int> Instructions_running;
map<string, int> Locations_read;
map<string, int> Locations_read_by_instruction;
:(before "End Setup")
Current_routine = NULL;
:(code)
void run(const recipe_ordinal r) {
routine rr(r);
Current_routine = &rr;
run_current_routine();
Current_routine = NULL;
}
void run_current_routine() {
while (should_continue_running(Current_routine)) {
if (current_instruction().is_label) { ++current_step_index(); continue; }
trace(Initial_callstack_depth + Trace_stream->callstack_depth, "run") << to_string(current_instruction()) << end();
if (get_or_insert(Memory, 0) != 0) {
raise << "something wrote to location 0; this should never happen\n" << end();
put(Memory, 0, 0);
}
vector<vector<double> > ingredients;
if (should_copy_ingredients()) {
for (int i = 0; i < SIZE(current_instruction().ingredients); ++i)
ingredients.push_back(read_memory(current_instruction().ingredients.at(i)));
}
vector<vector<double> > products;
switch (current_instruction().operation) {
case COPY: {
copy(ingredients.begin(), ingredients.end(), inserter(products, products.begin()));
break;
}
default: {
cout << "not a primitive op: " << current_instruction().operation << '\n';
}
}
if (SIZE(products) < SIZE(current_instruction().products)) {
raise << SIZE(products) << " vs " << SIZE(current_instruction().products) << ": failed to write to all products! " << to_original_string(current_instruction()) << '\n' << end();
}
else {
for (int i = 0; i < SIZE(current_instruction().Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */void test_trace_check_compares() {
trace("test layer") << "foo" << end();
CHECK_TRACE_CONTENTS("test layer: foo");
}
void test_trace_check_ignores_other_layers() {
trace("test layer 1") << "foo" << end();
trace("test layer 2") << "bar" << end();
CHECK_TRACE_CONTENTS("test layer 1: foo");
CHECK_TRACE_DOESNT_CONTAIN("test layer 2: foo");
}
void test_trace_check_ignores_leading_whitespace() {
trace("test layer 1") << " foo" << end();
CHECK(trace_count("test layer 1", /*too little whitespace*/"foo") == 1);
CHECK(trace_count("test layer 1", /*too much whitespace*/" foo") == 1);
}
void test_trace_check_ignores_other_lines() {
trace("test layer 1") << "foo" << end();
trace("test layer 1") << "bar" << end();
CHECK_TRACE_CONTENTS("test layer 1: foo");
}
void test_trace_check_ignores_other_lines2() {
trace("test layer 1") << "foo" << end();
trace("test layer 1") << "bar" << end();
CHECK_TRACE_CONTENTS("test layer 1: bar");
}
void test_trace_ignores_trailing_whitespace() {
trace("test layer 1") << "foo\n" << end();
CHECK_TRACE_CONTENTS("test layer 1: foo");
}
void test_trace_ignores_trailing_whitespace2() {
trace("test layer 1") << "foo " << end();
CHECK_TRACE_CONTENTS("test layer 1: foo");
}
void test_trace_orders_across_layers() {
trace("test layer 1") << "foo" << end();
trace("test layer 2") << "bar" << end();
trace("test layer 1") << "qux" << end();
CHECK_TRACE_CONTENTS("test layer 1: footest layer 2: bartest layer 1: qux");
}
void test_trace_supports_count() {
trace("test layer 1") << "foo" << end();
trace("test layer 1") << "foo" << end();
CHECK_EQ(trace_count("test layer 1", "foo"), 2);
}
void test_trace_supports_count2() {
trace("test layer 1") << "foo" << end();
trace("test layer 1") << "bar" << end();
CHECK_EQ(trace_count("test layer 1"), 2);
}
void test_trace_count_ignores_trailing_whitespace() {
trace("test layer 1") << "foo\n" << end();
CHECK(trace_count("test layer 1", "foo") == 1);
}
// pending: DUMP tests
// pending: readable_contents() adds newline if necessary.
// pending: raise also prints to stderr.
// pending: raise doesn't print to stderr if Hide_errors is set.
// pending: raise doesn't have to be saved if Hide_errors is set, just printed.
// pending: raise prints to stderr if Trace_stream is NULL.
// pending: raise prints to stderr if Trace_stream is NULL even if Hide_errors is set.
// pending: raise << ... die() doesn't die if Hide_errors is set.
// can't check trace because trace methods call 'split'
void test_split_returns_at_least_one_elem() {
vector<string> result = split("", ",");
CHECK_EQ(result.size(), 1);
CHECK_EQ(result.at(0), "");
}
void test_split_returns_entire_input_when_no_delim() {
vector<string> result = split("abc", ",");
CHECK_EQ(result.size(), 1);
CHECK_EQ(result.at(0), "abc");
}
void test_split_works() {
vector<string> result = split("abc,def", ",");
CHECK_EQ(result.size(), 2);
CHECK_EQ(result.at(0), "abc");
CHECK_EQ(result.at(1), "def");
}
void test_split_works2() {
vector<string> result = split("abc,def,ghi", ",");
CHECK_EQ(result.size(), 3);
CHECK_EQ(result.at(0), "abc");
CHECK_EQ(result.at(1), "def");
CHECK_EQ(result.at(2), "ghi");
}
void test_split_handles_multichar_delim() {
vector<string> result = split("abc,,def,,ghi", ",,");
CHECK_EQ(result.size(), 3);
CHECK_EQ(result.at(0), "abc");
CHECK_EQ(result.at(1), "def");
CHECK_EQ(result.at(2), "ghi");
}
void test_trim() {
CHECK_EQ(trim(""), "");
CHECK_EQ(trim(" "), "");
CHECK_EQ(trim(" "), "");
CHECK_EQ(trim("a"), "a");
CHECK_EQ(trim(" a"), "a");
CHECK_EQ(trim(" a"), "a");
CHECK_EQ(trim(" ab"), "ab");
CHECK_EQ(trim("a "), "a");
CHECK_EQ(trim("a "), "a");
CHECK_EQ(trim("ab "), "ab");
CHECK_EQ(trim(" a "), "a");
CHECK_EQ(trim(" a "), "a");
CHECK_EQ(trim(" ab "), "ab");
}