diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-07-25 00:02:20 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-07-25 00:02:20 -0700 |
commit | 35064671ef90ec6e35eafd9b15363058bf4f23f4 (patch) | |
tree | 3a0b4b02cbdd1b304deb52d1673083091a1ed12d | |
parent | a17fd65ca0124f544bd4de844f1bfe2d91b46ae6 (diff) | |
download | mu-35064671ef90ec6e35eafd9b15363058bf4f23f4.tar.gz |
1844 - explicitly end each trace line
More verbose, but it saves trouble when debugging; there's never something you thought should be traced but just never came out the other end. Also got rid of fatal errors entirely. Everything's a warning now, and code after a warning isn't guaranteed to run.
-rw-r--r-- | 003trace.cc | 21 | ||||
-rw-r--r-- | 003trace.test.cc | 34 | ||||
-rw-r--r-- | 011load.cc | 25 | ||||
-rw-r--r-- | 013literal_string.cc | 4 | ||||
-rw-r--r-- | 020run.cc | 19 | ||||
-rw-r--r-- | 023jump.cc | 10 | ||||
-rw-r--r-- | 027trace.cc | 2 | ||||
-rw-r--r-- | 028assert.cc | 2 | ||||
-rw-r--r-- | 029debug.cc | 4 | ||||
-rw-r--r-- | 030container.cc | 36 | ||||
-rw-r--r-- | 031address.cc | 2 | ||||
-rw-r--r-- | 032array.cc | 24 | ||||
-rw-r--r-- | 033exclusive_container.cc | 4 | ||||
-rw-r--r-- | 034call.cc | 2 | ||||
-rw-r--r-- | 036call_reply.cc | 8 | ||||
-rw-r--r-- | 038scheduler.cc | 22 | ||||
-rw-r--r-- | 039wait.cc | 14 | ||||
-rw-r--r-- | 040brace.cc | 22 | ||||
-rw-r--r-- | 041jump_label.cc | 2 | ||||
-rw-r--r-- | 042name.cc | 20 | ||||
-rw-r--r-- | 043new.cc | 33 | ||||
-rw-r--r-- | 044space.cc | 16 | ||||
-rw-r--r-- | 046closure_name.cc | 26 | ||||
-rw-r--r-- | 047global.cc | 4 | ||||
-rw-r--r-- | 049continuation.cc | 2 | ||||
-rw-r--r-- | 050scenario.cc | 26 | ||||
-rw-r--r-- | 072scenario_screen.cc | 10 | ||||
-rw-r--r-- | 075scenario_console.cc | 6 | ||||
-rw-r--r-- | 082persist.cc | 8 |
29 files changed, 205 insertions, 203 deletions
diff --git a/003trace.cc b/003trace.cc index 11bad7a2..3695703a 100644 --- a/003trace.cc +++ b/003trace.cc @@ -114,7 +114,6 @@ struct trace_stream { ostream& stream(int depth, string layer) { if (!collect_layer.empty() && layer != collect_layer) return null_stream; - newline(); curr_stream = new ostringstream; curr_layer = layer; curr_depth = depth; @@ -125,6 +124,7 @@ struct trace_stream { void newline() { if (!curr_stream) return; string curr_contents = curr_stream->str(); + if (curr_contents.empty()) return; past_lines.push_back(trace_line(curr_depth, trim(curr_layer), curr_contents)); // preserve indent in contents if (curr_layer == dump_layer || curr_layer == "dump" || dump_layer == "all" || (!Hide_warnings && curr_layer == "warn")) @@ -138,7 +138,6 @@ struct trace_stream { // Useful for debugging. string readable_contents(string layer) { // missing layer = everything - newline(); ostringstream output; layer = trim(layer); for (vector<trace_line>::iterator p = past_lines.begin(); p != past_lines.end(); ++p) @@ -161,22 +160,12 @@ trace_stream* Trace_stream = NULL; // some unfriendly constraints (they delay printing, they can't nest) #define raise ((!Trace_stream || !Hide_warnings) ? (tb_shutdown(),cerr) /*do print*/ : Trace_stream->stream("warn")) -// A separate helper for debugging. We should only trace domain-specific -// facts. For everything else use log. -#define xlog if (false) log -// To turn on logging replace 'xlog' with 'log'. -#define log cerr - :(before "End Types") -// raise << die exits after printing -- unless Hide_warnings is set. -struct die {}; +struct end {}; :(before "End Tracing") -ostream& operator<<(ostream& os, unused die) { - if (Hide_warnings) return os; - tb_shutdown(); - os << "dying"; +ostream& operator<<(ostream& os, unused end) { if (Trace_stream) Trace_stream->newline(); - exit(1); + return os; } #define CLEAR_TRACE delete Trace_stream, Trace_stream = new trace_stream; @@ -217,7 +206,6 @@ bool check_trace_contents(string FUNCTION, string FILE, int LINE, string expecte while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty()) ++curr_expected_line; if (curr_expected_line == SIZE(expected_lines)) return true; - Trace_stream->newline(); string layer, contents; split_layer_contents(expected_lines.at(curr_expected_line), &layer, &contents); for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { @@ -265,7 +253,6 @@ int trace_count(string layer) { } int trace_count(string layer, string line) { - Trace_stream->newline(); long result = 0; for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { if (layer == p->label) { diff --git a/003trace.test.cc b/003trace.test.cc index 146f9dc2..a16457a1 100644 --- a/003trace.test.cc +++ b/003trace.test.cc @@ -1,58 +1,58 @@ void test_trace_check_compares() { - trace("test layer") << "foo"; + trace("test layer") << "foo" << end(); CHECK_TRACE_CONTENTS("test layer: foo"); } void test_trace_check_ignores_other_layers() { - trace("test layer 1") << "foo"; - trace("test layer 2") << "bar"; + 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_other_lines() { - trace("test layer 1") << "foo"; - trace("test layer 1") << "bar"; + 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"; - trace("test layer 1") << "bar"; + 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"; + 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 "; + trace("test layer 1") << "foo " << end(); CHECK_TRACE_CONTENTS("test layer 1: foo"); } void test_trace_orders_across_layers() { - trace("test layer 1") << "foo"; - trace("test layer 2") << "bar"; - trace("test layer 1") << "qux"; + 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"; - trace("test layer 1") << "foo"; + 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"; - trace("test layer 1") << "bar"; + 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"; + trace("test layer 1") << "foo\n" << end(); CHECK(trace_count("test layer 1", "foo") == 1); } diff --git a/011load.cc b/011load.cc index 7ce8e25f..9142429c 100644 --- a/011load.cc +++ b/011load.cc @@ -29,7 +29,7 @@ vector<recipe_ordinal> load(istream& in) { string recipe_name = next_word(in); //? cerr << "recipe: " << recipe_name << '\n'; //? 1 if (recipe_name.empty()) - raise << "empty recipe name\n"; + raise << "empty recipe name\n" << end(); if (Recipe_ordinal.find(recipe_name) == Recipe_ordinal.end()) { Recipe_ordinal[recipe_name] = Next_recipe_ordinal++; } @@ -44,7 +44,7 @@ vector<recipe_ordinal> load(istream& in) { } // End Command Handlers else { - raise << "unknown top-level command: " << command << '\n'; + raise << "unknown top-level command: " << command << '\n' << end(); } } // End Load Sanity Checks @@ -55,7 +55,7 @@ recipe slurp_recipe(istream& in) { recipe result; skip_whitespace(in); if (in.get() != '[') - raise << "recipe body must begin with '['\n"; + raise << "recipe body must begin with '['\n" << end(); skip_whitespace_and_comments(in); instruction curr; while (next_instruction(in, &curr)) { @@ -96,7 +96,7 @@ bool next_instruction(istream& in, instruction* curr) { if (SIZE(words) == 1 && !isalnum(words.at(0).at(0)) && words.at(0).at(0) != '$') { curr->is_label = true; curr->label = words.at(0); - trace("parse") << "label: " << curr->label; + trace("parse") << "label: " << curr->label << end(); return !in.eof(); } @@ -110,15 +110,18 @@ bool next_instruction(istream& in, instruction* curr) { ++p; // skip <- } - if (p == words.end()) - raise << "instruction prematurely ended with '<-'\n" << die(); + if (p == words.end()) { + raise << "instruction prematurely ended with '<-'\n" << end() << end(); + return false; + } curr->name = *p; if (Recipe_ordinal.find(*p) == Recipe_ordinal.end()) { Recipe_ordinal[*p] = Next_recipe_ordinal++; //? cout << "AAA: " << *p << " is now " << Recipe_ordinal[*p] << '\n'; //? 1 } if (Recipe_ordinal[*p] == 0) { - raise << "Recipe " << *p << " has number 0, which is reserved for IDLE.\n" << die(); + raise << "Recipe " << *p << " has number 0, which is reserved for IDLE.\n" << end() << end(); + return false; } curr->operation = Recipe_ordinal[*p]; ++p; @@ -128,12 +131,12 @@ bool next_instruction(istream& in, instruction* curr) { //? cerr << "ingredient: " << curr->ingredients.back().to_string() << '\n'; //? 1 } - trace("parse") << "instruction: " << curr->name; + trace("parse") << "instruction: " << curr->name << end(); for (vector<reagent>::iterator p = curr->ingredients.begin(); p != curr->ingredients.end(); ++p) { - trace("parse") << " ingredient: " << p->to_string(); + trace("parse") << " ingredient: " << p->to_string() << end(); } for (vector<reagent>::iterator p = curr->products.begin(); p != curr->products.end(); ++p) { - trace("parse") << " product: " << p->to_string(); + trace("parse") << " product: " << p->to_string() << end(); } return !in.eof(); } @@ -204,7 +207,7 @@ Hide_redefine_warnings = false; :(after "Warn On Redefinition") if (!Hide_redefine_warnings && Recipe.find(Recipe_ordinal[recipe_name]) != Recipe.end()) { - raise << "redefining recipe " << Recipe[Recipe_ordinal[recipe_name]].name << "\n"; + raise << "redefining recipe " << Recipe[Recipe_ordinal[recipe_name]].name << "\n" << end(); } // for debugging diff --git a/013literal_string.cc b/013literal_string.cc index 0d4e3573..29a185b2 100644 --- a/013literal_string.cc +++ b/013literal_string.cc @@ -80,7 +80,7 @@ void slurp_quoted_comment_oblivious(istream& in, ostringstream& out) { if (brace_depth == 0) break; } if (in.eof() && brace_depth > 0) { - raise << "unbalanced '['\n"; + raise << "unbalanced '['\n" << end(); out.clear(); } } @@ -109,7 +109,7 @@ void slurp_quoted_comment_aware(istream& in, ostringstream& out) { out << c; if (c == ']') return; } - raise << "unbalanced '['\n"; + raise << "unbalanced '['\n" << end(); out.clear(); } diff --git a/020run.cc b/020run.cc index 12ae6091..08aa2b74 100644 --- a/020run.cc +++ b/020run.cc @@ -60,9 +60,11 @@ void run_current_routine() //? cerr << "AAA 7: " << current_step_index() << '\n'; //? 1 // Running One Instruction if (current_instruction().is_label) { ++current_step_index(); continue; } - trace(Initial_callstack_depth+Callstack_depth, "run") << current_instruction().to_string(); - if (Memory[0] != 0) - raise << "something wrote to location 0; this should never happen\n" << die(); + trace(Initial_callstack_depth+Callstack_depth, "run") << current_instruction().to_string() << end(); + if (Memory[0] != 0) { + raise << "something wrote to location 0; this should never happen\n" << end(); + break; + } // Read all ingredients from memory. // Each ingredient loads a vector of values rather than a single value; mu // permits operating on reagents spanning multiple locations. @@ -87,7 +89,7 @@ void run_current_routine() } } if (SIZE(products) < SIZE(current_instruction().products)) - raise << SIZE(products) << " vs " << SIZE(current_instruction().products) << ": failed to write to all products! " << current_instruction().to_string(); + raise << SIZE(products) << " vs " << SIZE(current_instruction().products) << ": failed to write to all products! " << current_instruction().to_string() << end(); for (long long int i = 0; i < SIZE(current_instruction().products); ++i) { write_memory(current_instruction().products.at(i), products.at(i)); } @@ -147,7 +149,7 @@ void load_permanently(string filename) { //? cerr << "AAA: " << filename << ' ' << static_cast<bool>(fin) << ' ' << fin.fail() << '\n'; //? 1 //? return; //? 1 if (!fin) { - raise << "no such file " << filename << '\n'; + raise << "no such file " << filename << '\n' << end(); return; } fin >> std::noskipws; @@ -189,7 +191,7 @@ vector<double> read_memory(reagent x) { long long int size = size_of(x); for (long long int offset = 0; offset < size; ++offset) { double val = Memory[base+offset]; - trace(Primitive_recipe_depth, "mem") << "location " << base+offset << " is " << val; + trace(Primitive_recipe_depth, "mem") << "location " << base+offset << " is " << val << end(); result.push_back(val); } return result; @@ -200,10 +202,11 @@ void write_memory(reagent x, vector<double> data) { if (is_literal(x)) return; long long int base = x.value; if (size_mismatch(x, data)) { - raise << current_recipe_name() << ": size mismatch in storing to " << x.to_string() << " at " << current_instruction().to_string() << '\n' << die(); + raise << current_recipe_name() << ": size mismatch in storing to " << x.to_string() << " at " << current_instruction().to_string() << '\n' << end(); + return; } for (long long int offset = 0; offset < SIZE(data); ++offset) { - trace(Primitive_recipe_depth, "mem") << "storing " << data.at(offset) << " in location " << base+offset; + trace(Primitive_recipe_depth, "mem") << "storing " << data.at(offset) << " in location " << base+offset << end(); Memory[base+offset] = data.at(offset); } } diff --git a/023jump.cc b/023jump.cc index f53f3079..edccf207 100644 --- a/023jump.cc +++ b/023jump.cc @@ -20,7 +20,7 @@ case JUMP: { assert(SIZE(ingredients) == 1); assert(scalar(ingredients.at(0))); current_step_index() += ingredients.at(0).at(0)+1; - trace(Primitive_recipe_depth, "run") << "jumping to instruction " << current_step_index(); + trace(Primitive_recipe_depth, "run") << "jumping to instruction " << current_step_index() << end(); continue; // skip rest of this instruction } @@ -49,12 +49,12 @@ case JUMP_IF: { assert(SIZE(ingredients) == 2); assert(scalar(ingredients.at(0))); if (!ingredients.at(0).at(0)) { - trace(Primitive_recipe_depth, "run") << "jump-if fell through"; + trace(Primitive_recipe_depth, "run") << "jump-if fell through" << end(); break; } assert(scalar(ingredients.at(1))); current_step_index() += ingredients.at(1).at(0)+1; - trace(Primitive_recipe_depth, "run") << "jumping to instruction " << current_step_index(); + trace(Primitive_recipe_depth, "run") << "jumping to instruction " << current_step_index() << end(); continue; // skip rest of this instruction } @@ -88,12 +88,12 @@ case JUMP_UNLESS: { assert(SIZE(ingredients) == 2); assert(scalar(ingredients.at(0))); if (ingredients.at(0).at(0)) { - trace(Primitive_recipe_depth, "run") << "jump-unless fell through"; + trace(Primitive_recipe_depth, "run") << "jump-unless fell through" << end(); break; } assert(scalar(ingredients.at(1))); current_step_index() += ingredients.at(1).at(0)+1; - trace(Primitive_recipe_depth, "run") << "jumping to instruction " << current_step_index(); + trace(Primitive_recipe_depth, "run") << "jumping to instruction " << current_step_index() << end(); continue; // skip rest of this instruction } diff --git a/027trace.cc b/027trace.cc index 89d6f2e2..12cc7ca3 100644 --- a/027trace.cc +++ b/027trace.cc @@ -16,7 +16,7 @@ case TRACE: { string label = current_instruction().ingredients.at(0).name; assert(is_literal(current_instruction().ingredients.at(1))); string message = current_instruction().ingredients.at(1).name; - trace(1, label) << message; + trace(1, label) << message << end(); break; } diff --git a/028assert.cc b/028assert.cc index f864d43e..07f68cc8 100644 --- a/028assert.cc +++ b/028assert.cc @@ -15,7 +15,7 @@ case ASSERT: { assert(scalar(ingredients.at(0))); if (!ingredients.at(0).at(0)) { assert(is_literal(current_instruction().ingredients.at(1))); - raise << current_instruction().ingredients.at(1).name << '\n' << die(); + raise << current_instruction().ingredients.at(1).name << '\n' << end(); } break; } diff --git a/029debug.cc b/029debug.cc index f6d77355..b9f653e7 100644 --- a/029debug.cc +++ b/029debug.cc @@ -6,7 +6,7 @@ Recipe_ordinal["$print"] = _PRINT; case _PRINT: { for (long long int i = 0; i < SIZE(ingredients); ++i) { if (is_literal(current_instruction().ingredients.at(i))) { - trace(Primitive_recipe_depth, "run") << "$print: " << current_instruction().ingredients.at(i).name; + trace(Primitive_recipe_depth, "run") << "$print: " << current_instruction().ingredients.at(i).name << end(); if (has_property(current_instruction().ingredients.at(i), "newline")) cout << '\n'; else @@ -14,7 +14,7 @@ case _PRINT: { } else { for (long long int j = 0; j < SIZE(ingredients.at(i)); ++j) { - trace(Primitive_recipe_depth, "run") << "$print: " << ingredients.at(i).at(j); + trace(Primitive_recipe_depth, "run") << "$print: " << ingredients.at(i).at(j) << end(); if (j > 0) cout << " "; cout << ingredients.at(i).at(j); } diff --git a/030container.cc b/030container.cc index c9042398..79ab71e1 100644 --- a/030container.cc +++ b/030container.cc @@ -84,7 +84,7 @@ if (t.kind == container) { for (long long int i = 0; i < SIZE(t.elements); ++i) { // todo: strengthen assertion to disallow mutual type recursion if (types.at(0) == t.elements.at(i).at(0)) { - raise << "container " << t.name << " can't include itself as a member\n"; + raise << "container " << t.name << " can't include itself as a member\n" << end(); return 0; } result += size_of(t.elements.at(i)); @@ -108,18 +108,18 @@ Recipe_ordinal["get"] = GET; :(before "End Primitive Recipe Implementations") case GET: { if (ingredients.size() != 2) { - raise << current_recipe_name() << ": 'get' expects exactly 2 ingredients in '" << current_instruction().to_string() << "'\n"; + raise << current_recipe_name() << ": 'get' expects exactly 2 ingredients in '" << current_instruction().to_string() << "'\n" << end(); break; } reagent base = current_instruction().ingredients.at(0); long long int base_address = base.value; type_ordinal base_type = base.types.at(0); if (Type[base_type].kind != container) { - raise << current_recipe_name () << ": 'get' on a non-container " << base.original_string << '\n'; + raise << current_recipe_name () << ": 'get' on a non-container " << base.original_string << '\n' << end(); break; } if (!is_literal(current_instruction().ingredients.at(1))) { - raise << current_recipe_name() << ": expected ingredient 1 of 'get' to have type 'offset', got '" << current_instruction().ingredients.at(1).original_string << "'\n"; + raise << current_recipe_name() << ": expected ingredient 1 of 'get' to have type 'offset', got '" << current_instruction().ingredients.at(1).original_string << "'\n" << end(); break; } assert(scalar(ingredients.at(1))); @@ -128,14 +128,14 @@ case GET: { for (long long int i = 0; i < offset; ++i) { src += size_of(Type[base_type].elements.at(i)); } - trace(Primitive_recipe_depth, "run") << "address to copy is " << src; + trace(Primitive_recipe_depth, "run") << "address to copy is " << src << end(); if (offset < 0 || offset >= SIZE(Type[base_type].elements)) { - raise << current_recipe_name() << ": invalid offset " << offset << " for " << Type[base_type].name << '\n'; + raise << current_recipe_name() << ": invalid offset " << offset << " for " << Type[base_type].name << '\n' << end(); products.resize(1); break; } type_ordinal src_type = Type[base_type].elements.at(offset).at(0); - trace(Primitive_recipe_depth, "run") << "its type is " << Type[src_type].name; + trace(Primitive_recipe_depth, "run") << "its type is " << Type[src_type].name << end(); reagent tmp; tmp.set_value(src); tmp.types.push_back(src_type); @@ -192,17 +192,17 @@ case GET_ADDRESS: { long long int base_address = base.value; type_ordinal base_type = base.types.at(0); if (Type[base_type].kind != container) { - raise << current_recipe_name () << ": 'get-address' on a non-container " << base.original_string << '\n'; + raise << current_recipe_name () << ": 'get-address' on a non-container " << base.original_string << '\n' << end(); break; } if (!is_literal(current_instruction().ingredients.at(1))) { - raise << current_recipe_name() << ": expected ingredient 1 of 'get-address' to have type 'offset', got '" << current_instruction().ingredients.at(1).original_string << "'\n"; + raise << current_recipe_name() << ": expected ingredient 1 of 'get-address' to have type 'offset', got '" << current_instruction().ingredients.at(1).original_string << "'\n" << end(); break; } assert(scalar(ingredients.at(1))); long long int offset = ingredients.at(1).at(0); if (offset < 0 || offset >= SIZE(Type[base_type].elements)) { - raise << "invalid offset " << offset << " for " << Type[base_type].name << '\n'; + raise << "invalid offset " << offset << " for " << Type[base_type].name << '\n' << end(); products.resize(1); break; } @@ -210,7 +210,7 @@ case GET_ADDRESS: { for (long long int i = 0; i < offset; ++i) { result += size_of(Type[base_type].elements.at(i)); } - trace(Primitive_recipe_depth, "run") << "address to copy is " << result; + trace(Primitive_recipe_depth, "run") << "address to copy is " << result << end(); products.resize(1); products.at(0).push_back(result); break; @@ -278,7 +278,7 @@ else if (command == "container") { void insert_container(const string& command, kind_of_type kind, istream& in) { skip_whitespace(in); string name = next_word(in); - trace("parse") << "reading " << command << ' ' << name; + trace("parse") << "reading " << command << ' ' << name << end(); //? cout << name << '\n'; //? 2 //? if (Type_ordinal.find(name) != Type_ordinal.end()) //? 1 //? cerr << Type_ordinal[name] << '\n'; //? 1 @@ -286,7 +286,7 @@ void insert_container(const string& command, kind_of_type kind, istream& in) { || Type_ordinal[name] == 0) { Type_ordinal[name] = Next_type_ordinal++; } - trace("parse") << "type number: " << Type_ordinal[name]; + trace("parse") << "type number: " << Type_ordinal[name] << end(); skip_bracket(in, "'container' must begin with '['"); type_info& t = Type[Type_ordinal[name]]; recently_added_types.push_back(Type_ordinal[name]); @@ -298,7 +298,7 @@ void insert_container(const string& command, kind_of_type kind, istream& in) { if (element == "]") break; istringstream inner(element); t.element_names.push_back(slurp_until(inner, ':')); - trace("parse") << " element name: " << t.element_names.back(); + trace("parse") << " element name: " << t.element_names.back() << end(); vector<type_ordinal> types; while (!inner.eof()) { string type_name = slurp_until(inner, ':'); @@ -307,7 +307,7 @@ void insert_container(const string& command, kind_of_type kind, istream& in) { Type_ordinal[type_name] = Next_type_ordinal++; } types.push_back(Type_ordinal[type_name]); - trace("parse") << " type: " << types.back(); + trace("parse") << " type: " << types.back() << end(); } t.elements.push_back(types); } @@ -395,7 +395,7 @@ void check_invalid_types(const reagent& r) { for (long long int i = 0; i < SIZE(r.types); ++i) { if (r.types.at(i) == 0) continue; if (Type.find(r.types.at(i)) == Type.end()) - raise << "unknown type: " << r.properties.at(0).second.at(i) << '\n'; + raise << "unknown type: " << r.properties.at(0).second.at(i) << '\n' << end(); } } @@ -431,7 +431,7 @@ void check_container_field_types() { for (long long int j = 0; j < SIZE(info.elements.at(i)); ++j) { if (info.elements.at(i).at(j) == 0) continue; if (Type.find(info.elements.at(i).at(j)) == Type.end()) - raise << "unknown type for field " << info.element_names.at(i) << " in " << info.name << '\n'; + raise << "unknown type for field " << info.element_names.at(i) << " in " << info.name << '\n' << end(); } } } @@ -470,5 +470,5 @@ recipe main [ void skip_bracket(istream& in, string message) { skip_whitespace_and_comments(in); if (in.get() != '[') - raise << message << '\n'; + raise << message << '\n' << end(); } diff --git a/031address.cc b/031address.cc index 4df2518c..0e2a4f0f 100644 --- a/031address.cc +++ b/031address.cc @@ -44,7 +44,7 @@ reagent deref(reagent x) { // compute value result.set_value(Memory[x.value]); - trace(Primitive_recipe_depth, "mem") << "location " << x.value << " is " << result.value; + trace(Primitive_recipe_depth, "mem") << "location " << x.value << " is " << result.value << end(); // populate types copy(++x.types.begin(), x.types.end(), inserter(result.types, result.types.begin())); diff --git a/032array.cc b/032array.cc index 9dad84ac..f9134e87 100644 --- a/032array.cc +++ b/032array.cc @@ -43,7 +43,7 @@ if (x.types.at(0) == Type_ordinal["array"]) return false; :(before "End size_of(reagent) Cases") if (r.types.at(0) == Type_ordinal["array"]) { if (SIZE(r.types) == 1) { - raise << current_recipe_name() << ": '" << r.original_string << "' is an array of what?\n"; + raise << current_recipe_name() << ": '" << r.original_string << "' is an array of what?\n" << end(); return 1; } // skip the 'array' type to get at the element type @@ -81,26 +81,26 @@ Recipe_ordinal["index"] = INDEX; case INDEX: { //? if (Trace_stream) Trace_stream->dump_layer = "run"; //? 1 reagent base = canonize(current_instruction().ingredients.at(0)); -//? trace(Primitive_recipe_depth, "run") << "ingredient 0 after canonize: " << base.to_string(); //? 1 +//? trace(Primitive_recipe_depth, "run") << "ingredient 0 after canonize: " << base.to_string() << end(); //? 1 long long int base_address = base.value; if (base.types.at(0) != Type_ordinal["array"]) { - raise << current_recipe_name () << ": 'index' on a non-array " << base.original_string << '\n'; + raise << current_recipe_name () << ": 'index' on a non-array " << base.original_string << '\n' << end(); break; } reagent offset = canonize(current_instruction().ingredients.at(1)); -//? trace(Primitive_recipe_depth, "run") << "ingredient 1 after canonize: " << offset.to_string(); //? 1 +//? trace(Primitive_recipe_depth, "run") << "ingredient 1 after canonize: " << offset.to_string() << end(); //? 1 vector<double> offset_val(read_memory(offset)); vector<type_ordinal> element_type = array_element(base.types); -//? trace(Primitive_recipe_depth, "run") << "offset: " << offset_val.at(0); //? 1 -//? trace(Primitive_recipe_depth, "run") << "size of elements: " << size_of(element_type); //? 1 +//? trace(Primitive_recipe_depth, "run") << "offset: " << offset_val.at(0) << end(); //? 1 +//? trace(Primitive_recipe_depth, "run") << "size of elements: " << size_of(element_type) << end(); //? 1 if (offset_val.at(0) < 0 || offset_val.at(0) >= Memory[base_address]) { - raise << current_recipe_name() << ": invalid index " << offset_val.at(0) << '\n'; + raise << current_recipe_name() << ": invalid index " << offset_val.at(0) << '\n' << end(); products.resize(1); break; } long long int src = base_address + 1 + offset_val.at(0)*size_of(element_type); - trace(Primitive_recipe_depth, "run") << "address to copy is " << src; - trace(Primitive_recipe_depth, "run") << "its type is " << Type[element_type.at(0)].name; + trace(Primitive_recipe_depth, "run") << "address to copy is " << src << end(); + trace(Primitive_recipe_depth, "run") << "its type is " << Type[element_type.at(0)].name << end(); reagent tmp; tmp.set_value(src); copy(element_type.begin(), element_type.end(), inserter(tmp.types, tmp.types.begin())); @@ -175,14 +175,14 @@ case INDEX_ADDRESS: { reagent base = canonize(current_instruction().ingredients.at(0)); long long int base_address = base.value; if (base.types.at(0) != Type_ordinal["array"]) { - raise << current_recipe_name () << ": 'index-address' on a non-array " << base.original_string << '\n'; + raise << current_recipe_name () << ": 'index-address' on a non-array " << base.original_string << '\n' << end(); break; } reagent offset = canonize(current_instruction().ingredients.at(1)); vector<double> offset_val(read_memory(offset)); vector<type_ordinal> element_type = array_element(base.types); if (offset_val.at(0) < 0 || offset_val.at(0) >= Memory[base_address]) { - raise << current_recipe_name() << ": invalid index " << offset_val.at(0) << '\n'; + raise << current_recipe_name() << ": invalid index " << offset_val.at(0) << '\n' << end(); products.resize(1); break; } @@ -242,7 +242,7 @@ Recipe_ordinal["length"] = LENGTH; case LENGTH: { reagent x = canonize(current_instruction().ingredients.at(0)); if (x.types.at(0) != Type_ordinal["array"]) { - raise << "tried to calculate length of non-array " << x.to_string() << '\n'; + raise << "tried to calculate length of non-array " << x.to_string() << '\n' << end(); break; } products.resize(1); diff --git a/033exclusive_container.cc b/033exclusive_container.cc index dfdcdd61..c212be79 100644 --- a/033exclusive_container.cc +++ b/033exclusive_container.cc @@ -95,11 +95,11 @@ case MAYBE_CONVERT: { long long int base_address = base.value; type_ordinal base_type = base.types.at(0); if (Type[base_type].kind != exclusive_container) { - raise << current_recipe_name () << ": 'maybe-convert' on a non-exclusive-container " << base.original_string << '\n'; + raise << current_recipe_name () << ": 'maybe-convert' on a non-exclusive-container " << base.original_string << '\n' << end(); break; } if (!is_literal(current_instruction().ingredients.at(1))) { - raise << current_recipe_name() << ": expected ingredient 1 of 'get' to have type 'variant', got '" << current_instruction().ingredients.at(1).original_string << "'\n"; + raise << current_recipe_name() << ": expected ingredient 1 of 'get' to have type 'variant', got '" << current_instruction().ingredients.at(1).original_string << "'\n" << end(); break; } long long int tag = current_instruction().ingredients.at(1).value; diff --git a/034call.cc b/034call.cc index 4b841fe0..cafabd53 100644 --- a/034call.cc +++ b/034call.cc @@ -81,7 +81,7 @@ inline const instruction& current_instruction() { default: { // not a primitive; try to look up the book of recipes if (Recipe.find(current_instruction().operation) == Recipe.end()) { - raise << "undefined operation " << current_instruction().operation << ": " << current_instruction().to_string() << '\n'; + raise << "undefined operation " << current_instruction().operation << ": " << current_instruction().to_string() << '\n' << end(); break; } Current_routine->calls.push_front(call(current_instruction().operation)); diff --git a/036call_reply.cc b/036call_reply.cc index 618ad651..75587351 100644 --- a/036call_reply.cc +++ b/036call_reply.cc @@ -35,20 +35,20 @@ case REPLY: { // check that any reply ingredients with /same-as-ingredient connect up // the corresponding ingredient and product in the caller. if (SIZE(caller_instruction.products) > SIZE(ingredients)) - raise << "too few values replied from " << callee << '\n'; + raise << "too few values replied from " << callee << '\n' << end(); for (long long int i = 0; i < SIZE(caller_instruction.products); ++i) { //? cerr << Recipe[Current_routine->calls.front().running_recipe].name << '\n'; //? 1 - trace(Primitive_recipe_depth, "run") << "result " << i << " is " << to_string(ingredients.at(i)); + trace(Primitive_recipe_depth, "run") << "result " << i << " is " << to_string(ingredients.at(i)) << end(); if (has_property(reply_inst.ingredients.at(i), "same-as-ingredient")) { vector<string> tmp = property(reply_inst.ingredients.at(i), "same-as-ingredient"); assert(SIZE(tmp) == 1); long long int ingredient_index = to_integer(tmp.at(0)); if (ingredient_index >= SIZE(caller_instruction.ingredients)) - raise << current_recipe_name() << ": 'same-as-ingredient' metadata overflows ingredients in: " << caller_instruction.to_string() << '\n'; + raise << current_recipe_name() << ": 'same-as-ingredient' metadata overflows ingredients in: " << caller_instruction.to_string() << '\n' << end(); //? cerr << caller_instruction.products.size() << ' ' << i << ' ' << caller_instruction.ingredients.size() << ' ' << ingredient_index << '\n'; //? 1 //? cerr << caller_instruction.to_string() << '\n'; //? 1 if (!is_dummy(caller_instruction.products.at(i)) && caller_instruction.products.at(i).value != caller_instruction.ingredients.at(ingredient_index).value) - raise << current_recipe_name() << ": 'same-as-ingredient' result " << caller_instruction.products.at(i).value << " from call to " << callee << " must be location " << caller_instruction.ingredients.at(ingredient_index).value << '\n'; + raise << current_recipe_name() << ": 'same-as-ingredient' result " << caller_instruction.products.at(i).value << " from call to " << callee << " must be location " << caller_instruction.ingredients.at(ingredient_index).value << '\n' << end(); } } // End Reply diff --git a/038scheduler.cc b/038scheduler.cc index 2f53e884..5334009c 100644 --- a/038scheduler.cc +++ b/038scheduler.cc @@ -56,9 +56,9 @@ void run(recipe_ordinal r) { //? cout << "scheduler: " << Current_routine_index << '\n'; //? 1 assert(Current_routine); assert(Current_routine->state == RUNNING); - trace("schedule") << current_routine_label(); -//? trace("schedule") << Current_routine_index << ": " << current_recipe_name(); //? 1 -//? trace("schedule") << Current_routine->id << " " << current_recipe_name(); //? 1 + trace("schedule") << current_routine_label() << end(); +//? trace("schedule") << Current_routine_index << ": " << current_recipe_name() << end(); //? 1 +//? trace("schedule") << Current_routine->id << " " << current_recipe_name() << end(); //? 1 run_current_routine(Scheduling_interval); // Scheduler State Transitions //? cerr << "AAA completed? " << Current_routine->completed() << '\n'; //? 1 @@ -252,29 +252,29 @@ recipe f1 [ -schedule: f1 :(before "End Scheduler Cleanup") -//? trace("schedule") << "Before cleanup"; //? 1 +//? trace("schedule") << "Before cleanup" << end(); //? 1 //? for (long long int i = 0; i < SIZE(Routines); ++i) { //? 1 -//? trace("schedule") << i << ": " << Routines.at(i)->id << ' ' << Routines.at(i)->state << ' ' << Routines.at(i)->parent_index << ' ' << Routines.at(i)->state; //? 1 +//? trace("schedule") << i << ": " << Routines.at(i)->id << ' ' << Routines.at(i)->state << ' ' << Routines.at(i)->parent_index << ' ' << Routines.at(i)->state << end(); //? 1 //? } //? 1 for (long long int i = 0; i < SIZE(Routines); ++i) { if (Routines.at(i)->state == COMPLETED) continue; if (Routines.at(i)->parent_index < 0) continue; // root thread -//? trace("schedule") << "AAA " << i; //? 1 +//? trace("schedule") << "AAA " << i << end(); //? 1 if (has_completed_parent(i)) { -//? trace("schedule") << "BBB " << i; //? 1 +//? trace("schedule") << "BBB " << i << end(); //? 1 Routines.at(i)->state = COMPLETED; } } -//? trace("schedule") << "After cleanup"; //? 1 +//? trace("schedule") << "After cleanup" << end(); //? 1 //? for (long long int i = 0; i < SIZE(Routines); ++i) { //? 1 -//? trace("schedule") << i << ": " << Routines.at(i)->id << ' ' << Routines.at(i)->state << ' ' << Routines.at(i)->parent_index << ' ' << Routines.at(i)->state; //? 1 +//? trace("schedule") << i << ": " << Routines.at(i)->id << ' ' << Routines.at(i)->state << ' ' << Routines.at(i)->parent_index << ' ' << Routines.at(i)->state << end(); //? 1 //? } //? 1 :(code) bool has_completed_parent(long long int routine_index) { -//? trace("schedule") << "CCC " << routine_index << '\n'; //? 2 +//? trace("schedule") << "CCC " << routine_index << '\n' << end(); //? 2 for (long long int j = routine_index; j >= 0; j = Routines.at(j)->parent_index) { -//? trace("schedule") << "DDD " << j << '\n'; //? 2 +//? trace("schedule") << "DDD " << j << '\n' << end(); //? 2 if (Routines.at(j)->state == COMPLETED) return true; } diff --git a/039wait.cc b/039wait.cc index cbfb4664..8a40dc8a 100644 --- a/039wait.cc +++ b/039wait.cc @@ -40,8 +40,8 @@ case WAIT_FOR_LOCATION: { Current_routine->state = WAITING; Current_routine->waiting_on_location = loc.value; Current_routine->old_value_of_waiting_location = Memory[loc.value]; - trace(Primitive_recipe_depth, "run") << "waiting for location " << loc.value << " to change from " << Memory[loc.value]; -//? trace("schedule") << Current_routine->id << ": waiting for location " << loc.value << " to change from " << Memory[loc.value]; //? 2 + trace(Primitive_recipe_depth, "run") << "waiting for location " << loc.value << " to change from " << Memory[loc.value] << end(); +//? trace("schedule") << Current_routine->id << ": waiting for location " << loc.value << " to change from " << Memory[loc.value] << end(); //? 2 break; } @@ -49,15 +49,15 @@ case WAIT_FOR_LOCATION: { :(before "End Scheduler State Transitions") for (long long int i = 0; i < SIZE(Routines); ++i) { -//? trace("schedule") << "wake up loop 1: routine " << Routines.at(i)->id << " has state " << Routines.at(i)->state; //? 1 +//? trace("schedule") << "wake up loop 1: routine " << Routines.at(i)->id << " has state " << Routines.at(i)->state << end(); //? 1 if (Routines.at(i)->state != WAITING) continue; -//? trace("schedule") << "waiting on location: " << Routines.at(i)->waiting_on_location; //? 1 +//? trace("schedule") << "waiting on location: " << Routines.at(i)->waiting_on_location << end(); //? 1 //? if (Routines.at(i)->waiting_on_location) //? 2 //? trace("schedule") << "checking routine " << Routines.at(i)->id << " waiting on location " //? 2 //? << Routines.at(i)->waiting_on_location << ": " << Memory[Routines.at(i)->waiting_on_location] << " vs " << Routines.at(i)->old_value_of_waiting_location; //? 2 if (Routines.at(i)->waiting_on_location && Memory[Routines.at(i)->waiting_on_location] != Routines.at(i)->old_value_of_waiting_location) { - trace("schedule") << "waking up routine\n"; + trace("schedule") << "waking up routine\n" << end(); Routines.at(i)->state = RUNNING; Routines.at(i)->waiting_on_location = Routines.at(i)->old_value_of_waiting_location = 0; } @@ -99,7 +99,7 @@ case WAIT_FOR_ROUTINE: { Current_routine->state = WAITING; assert(scalar(ingredients.at(0))); Current_routine->waiting_on_routine = ingredients.at(0).at(0); - trace(Primitive_recipe_depth, "run") << "waiting for routine " << ingredients.at(0).at(0); + trace(Primitive_recipe_depth, "run") << "waiting for routine " << ingredients.at(0).at(0) << end(); break; } @@ -114,7 +114,7 @@ for (long long int i = 0; i < SIZE(Routines); ++i) { assert(id != Routines.at(i)->id); for (long long int j = 0; j < SIZE(Routines); ++j) { if (Routines.at(j)->id == id && Routines.at(j)->state != RUNNING) { - trace("schedule") << "waking up routine " << Routines.at(i)->id; + trace("schedule") << "waking up routine " << Routines.at(i)->id << end(); Routines.at(i)->state = RUNNING; Routines.at(i)->waiting_on_routine = 0; } diff --git a/040brace.cc b/040brace.cc index 0ed25262..29d3e024 100644 --- a/040brace.cc +++ b/040brace.cc @@ -45,16 +45,16 @@ void transform_braces(const recipe_ordinal r) { for (long long int index = 0; index < SIZE(Recipe[r].steps); ++index) { const instruction& inst = Recipe[r].steps.at(index); if (inst.label == "{") { - trace("brace") << r << ": push (open, " << index << ")"; + trace("brace") << r << ": push (open, " << index << ")" << end(); braces.push_back(pair<int,long long int>(OPEN, index)); } if (inst.label == "}") { - trace("brace") << "push (close, " << index << ")"; + trace("brace") << "push (close, " << index << ")" << end(); braces.push_back(pair<int,long long int>(CLOSE, index)); } } stack</*step*/long long int> open_braces; - trace("after-brace") << "recipe " << Recipe[r].name; + trace("after-brace") << "recipe " << Recipe[r].name << end(); for (long long int index = 0; index < SIZE(Recipe[r].steps); ++index) { instruction& inst = Recipe[r].steps.at(index); if (inst.label == "{") { @@ -72,7 +72,7 @@ void transform_braces(const recipe_ordinal r) { && inst.operation != Recipe_ordinal["break"] && inst.operation != Recipe_ordinal["break-if"] && inst.operation != Recipe_ordinal["break-unless"]) { - trace("after-brace") << inst.name << " ..."; + trace("after-brace") << inst.name << " ..." << end(); continue; } // update instruction operation @@ -86,14 +86,14 @@ void transform_braces(const recipe_ordinal r) { if (inst.name.find("-if") != string::npos || inst.name.find("-unless") != string::npos) { // conditional branches check arg 1 if (SIZE(inst.ingredients) > 1 && is_literal(inst.ingredients.at(1))) { - trace("after-brace") << "jump " << inst.ingredients.at(1).name << ":offset"; + trace("after-brace") << "jump " << inst.ingredients.at(1).name << ":offset" << end(); continue; } } else { // unconditional branches check arg 0 if (!inst.ingredients.empty() && is_literal(inst.ingredients.at(0))) { - trace("after-brace") << "jump " << inst.ingredients.at(0).name << ":offset"; + trace("after-brace") << "jump " << inst.ingredients.at(0).name << ":offset" << end(); continue; } } @@ -102,7 +102,7 @@ void transform_braces(const recipe_ordinal r) { target.types.push_back(Type_ordinal["offset"]); target.set_value(0); if (open_braces.empty()) - raise << inst.name << " wasn't inside {}\n"; + raise << inst.name << " wasn't inside {}\n" << end(); else if (inst.name.find("loop") != string::npos) target.set_value(open_braces.top()-index); else // break instruction @@ -110,11 +110,11 @@ void transform_braces(const recipe_ordinal r) { inst.ingredients.push_back(target); // log computed target if (inst.name.find("-if") != string::npos) - trace("after-brace") << "jump-if " << inst.ingredients.at(0).name << ", " << target.value << ":offset"; + trace("after-brace") << "jump-if " << inst.ingredients.at(0).name << ", " << target.value << ":offset" << end(); else if (inst.name.find("-unless") != string::npos) - trace("after-brace") << "jump-unless " << inst.ingredients.at(0).name << ", " << target.value << ":offset"; + trace("after-brace") << "jump-unless " << inst.ingredients.at(0).name << ", " << target.value << ":offset" << end(); else - trace("after-brace") << "jump " << target.value << ":offset"; + trace("after-brace") << "jump " << target.value << ":offset" << end(); } } @@ -127,7 +127,7 @@ long long int matching_brace(long long int index, const list<pair<int, long long stacksize += (p->first ? 1 : -1); if (stacksize == 0) return p->second; } - raise << Recipe[r].name << ": unbalanced '{'\n"; + raise << Recipe[r].name << ": unbalanced '{'\n" << end(); return SIZE(Recipe[r].steps); // exit current routine } diff --git a/041jump_label.cc b/041jump_label.cc index dca2e37a..2527e813 100644 --- a/041jump_label.cc +++ b/041jump_label.cc @@ -54,7 +54,7 @@ void replace_offset(reagent& x, /*const*/ map<string, long long int>& offset, co if (is_integer(x.name)) return; // non-labels will be handled like other number operands //? cerr << "DDD " << x.to_string() << '\n'; //? 1 if (offset.find(x.name) == offset.end()) - raise << "can't find label " << x.name << " in routine " << Recipe[r].name << '\n'; + raise << "can't find label " << x.name << " in routine " << Recipe[r].name << '\n' << end(); x.set_value(offset[x.name]-current_offset); } diff --git a/042name.cc b/042name.cc index ed322d54..283bcbd7 100644 --- a/042name.cc +++ b/042name.cc @@ -45,7 +45,7 @@ void transform_names(const recipe_ordinal r) { if (is_named_location(inst.ingredients.at(in))) names_used = true; if (disqualified(inst.ingredients.at(in), inst)) continue; if (!already_transformed(inst.ingredients.at(in), names)) { - raise << "use before set: " << inst.ingredients.at(in).name << " in " << Recipe[r].name << '\n'; + raise << "use before set: " << inst.ingredients.at(in).name << " in " << Recipe[r].name << '\n' << end(); } inst.ingredients.at(in).set_value(lookup_name(inst.ingredients.at(in), r)); } @@ -55,7 +55,7 @@ void transform_names(const recipe_ordinal r) { if (is_named_location(inst.products.at(out))) names_used = true; if (disqualified(inst.products.at(out), inst)) continue; if (names.find(inst.products.at(out).name) == names.end()) { - trace("name") << "assign " << inst.products.at(out).name << " " << curr_idx; + trace("name") << "assign " << inst.products.at(out).name << " " << curr_idx << end(); names[inst.products.at(out).name] = curr_idx; curr_idx += size_of(inst.products.at(out)); } @@ -63,7 +63,7 @@ void transform_names(const recipe_ordinal r) { } } if (names_used && numeric_locations_used && r != Recipe_ordinal["interactive"]) - raise << "mixing variable names and numeric addresses in " << Recipe[r].name << '\n'; + raise << "mixing variable names and numeric addresses in " << Recipe[r].name << '\n' << end(); } void check_metadata(map<string, vector<type_ordinal> >& metadata, const reagent& x, const recipe_ordinal r) { @@ -75,13 +75,13 @@ void check_metadata(map<string, vector<type_ordinal> >& metadata, const reagent& if (metadata.find(x.name) == metadata.end()) metadata[x.name] = x.types; if (metadata[x.name] != x.types) - raise << x.name << " used with multiple types in " << Recipe[r].name << '\n'; + raise << x.name << " used with multiple types in " << Recipe[r].name << '\n' << end(); } bool disqualified(/*mutable*/ reagent& x, const instruction& inst) { //? cerr << x.to_string() << '\n'; //? 1 if (x.types.empty()) { - raise << "missing type in '" << inst.to_string() << "'\n"; + raise << "missing type in '" << inst.to_string() << "'\n" << end(); return true; } if (is_raw(x)) return true; @@ -104,7 +104,7 @@ type_ordinal skip_addresses(const vector<type_ordinal>& types) { for (long long int i = 0; i < SIZE(types); ++i) { if (types.at(i) != Type_ordinal["address"]) return types.at(i); } - raise << "expected a container" << '\n' << die(); + raise << "expected a container" << '\n' << end(); return -1; } @@ -114,7 +114,7 @@ int find_element_name(const type_ordinal t, const string& name) { for (long long int i = 0; i < SIZE(container.element_names); ++i) { if (container.element_names.at(i) == name) return i; } - raise << "unknown element " << name << " in container " << Type[t].name << '\n'; + raise << "unknown element " << name << " in container " << Type[t].name << '\n' << end(); return -1; } @@ -223,12 +223,12 @@ if (inst.operation == Recipe_ordinal["get"] assert(SIZE(inst.ingredients) >= 2); //? cout << inst.ingredients.at(1).to_string() << '\n'; //? 1 if (!is_literal(inst.ingredients.at(1))) - raise << Recipe[r].name << ": expected ingredient 1 of " << (inst.operation == Recipe_ordinal["get"] ? "'get'" : "'get-address'") << " to have type 'offset'; got " << inst.ingredients.at(1).original_string << '\n' << die(); + raise << Recipe[r].name << ": expected ingredient 1 of " << (inst.operation == Recipe_ordinal["get"] ? "'get'" : "'get-address'") << " to have type 'offset'; got " << inst.ingredients.at(1).original_string << '\n' << end(); if (inst.ingredients.at(1).name.find_first_not_of("0123456789") != string::npos) { // since first non-address in base type must be a container, we don't have to canonize type_ordinal base_type = skip_addresses(inst.ingredients.at(0).types); inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name)); - trace("name") << "element " << inst.ingredients.at(1).name << " of type " << Type[base_type].name << " is at offset " << inst.ingredients.at(1).value; + trace("name") << "element " << inst.ingredients.at(1).name << " of type " << Type[base_type].name << " is at offset " << inst.ingredients.at(1).value << end(); } } @@ -265,6 +265,6 @@ if (inst.operation == Recipe_ordinal["maybe-convert"]) { // since first non-address in base type must be an exclusive container, we don't have to canonize type_ordinal base_type = skip_addresses(inst.ingredients.at(0).types); inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name)); - trace("name") << "variant " << inst.ingredients.at(1).name << " of type " << Type[base_type].name << " has tag " << inst.ingredients.at(1).value; + trace("name") << "variant " << inst.ingredients.at(1).name << " of type " << Type[base_type].name << " has tag " << inst.ingredients.at(1).value << end(); } } diff --git a/043new.cc b/043new.cc index 672b4bb1..08c68eec 100644 --- a/043new.cc +++ b/043new.cc @@ -23,7 +23,7 @@ long long int alloc, alloc_max; alloc = Memory_allocated_until; Memory_allocated_until += Initial_memory_per_routine; alloc_max = Memory_allocated_until; -trace(Primitive_recipe_depth, "new") << "routine allocated memory from " << alloc << " to " << alloc_max; +trace(Primitive_recipe_depth, "new") << "routine allocated memory from " << alloc << " to " << alloc_max << end(); //:: First handle 'type' operands. @@ -36,14 +36,14 @@ if (inst.operation == Recipe_ordinal["new"]) { // first arg must be of type 'type' assert(SIZE(inst.ingredients) >= 1); if (!is_literal(inst.ingredients.at(0))) - raise << "expected literal, got " << inst.ingredients.at(0).original_string << '\n' << die(); + raise << "expected literal, got " << inst.ingredients.at(0).original_string << '\n' << end(); if (inst.ingredients.at(0).properties.at(0).second.at(0) != "type") - raise << "tried to allocate non-type " << inst.ingredients.at(0).to_string() << " in recipe " << Recipe[r].name << '\n' << die(); + raise << "tried to allocate non-type " << inst.ingredients.at(0).to_string() << " in recipe " << Recipe[r].name << '\n' << end(); if (Type_ordinal.find(inst.ingredients.at(0).name) == Type_ordinal.end()) - raise << "unknown type " << inst.ingredients.at(0).name << " in recipe " << Recipe[r].name << '\n' << die(); + raise << "unknown type " << inst.ingredients.at(0).name << " in recipe " << Recipe[r].name << '\n' << end(); //? cerr << "type " << inst.ingredients.at(0).name << " => " << Type_ordinal[inst.ingredients.at(0).name] << '\n'; //? 1 inst.ingredients.at(0).set_value(Type_ordinal[inst.ingredients.at(0).name]); - trace(Primitive_recipe_depth, "new") << inst.ingredients.at(0).name << " -> " << inst.ingredients.at(0).name; + trace(Primitive_recipe_depth, "new") << inst.ingredients.at(0).name << " -> " << inst.ingredients.at(0).name << end(); end_new_transform:; } @@ -63,11 +63,11 @@ case NEW: { vector<type_ordinal> type; assert(is_literal(current_instruction().ingredients.at(0))); type.push_back(current_instruction().ingredients.at(0).value); -//? trace(Primitive_recipe_depth, "mem") << "type " << current_instruction().ingredients.at(0).to_string() << ' ' << type.size() << ' ' << type.back() << " has size " << size_of(type); //? 1 +//? trace(Primitive_recipe_depth, "mem") << "type " << current_instruction().ingredients.at(0).to_string() << ' ' << type.size() << ' ' << type.back() << " has size " << size_of(type) << end(); //? 1 if (SIZE(current_instruction().ingredients) > 1) { // array array_length = ingredients.at(1).at(0); - trace(Primitive_recipe_depth, "mem") << "array size is " << array_length; + trace(Primitive_recipe_depth, "mem") << "array size is " << array_length << end(); size = array_length*size_of(type) + /*space for length*/1; } else { @@ -81,8 +81,8 @@ case NEW: { // really crappy at the moment ensure_space(size); const long long int result = Current_routine->alloc; - trace(Primitive_recipe_depth, "mem") << "new alloc: " << result; -//? trace(Primitive_recipe_depth, "mem") << "size: " << size << " locations"; //? 1 + trace(Primitive_recipe_depth, "mem") << "new alloc: " << result << end(); +//? trace(Primitive_recipe_depth, "mem") << "size: " << size << " locations" << end(); //? 1 // save result products.resize(1); products.at(0).push_back(result); @@ -121,7 +121,7 @@ void ensure_space(long long int size) { Current_routine->alloc = Memory_allocated_until; Memory_allocated_until += Initial_memory_per_routine; Current_routine->alloc_max = Memory_allocated_until; - trace(Primitive_recipe_depth, "new") << "routine allocated memory from " << Current_routine->alloc << " to " << Current_routine->alloc_max; + trace(Primitive_recipe_depth, "new") << "routine allocated memory from " << Current_routine->alloc << " to " << Current_routine->alloc_max << end(); } } @@ -209,13 +209,13 @@ Recipe_ordinal["abandon"] = ABANDON; :(before "End Primitive Recipe Implementations") case ABANDON: { if (!scalar(ingredients.at(0))) { - raise << "abandon's ingredient should be scalar\n"; + raise << "abandon's ingredient should be scalar\n" << end(); break; } long long int address = ingredients.at(0).at(0); reagent types = canonize(current_instruction().ingredients.at(0)); if (types.types.at(0) != Type_ordinal["address"]) { - raise << "abandon's ingredient should be an address\n"; + raise << "abandon's ingredient should be an address\n" << end(); break; } reagent target_type = deref(types); @@ -240,9 +240,12 @@ void abandon(long long int address, long long int size) { if (Free_list[size]) { long long int result = Free_list[size]; Free_list[size] = Memory[result]; - for (long long int curr = result+1; curr < result+size; ++curr) - if (Memory[curr] != 0) - raise << current_recipe_name() << ": memory in free list was not zeroed out: " << curr << '/' << result << "; somebody wrote to us after free!!!\n" << die(); + for (long long int curr = result+1; curr < result+size; ++curr) { + if (Memory[curr] != 0) { + raise << current_recipe_name() << ": memory in free list was not zeroed out: " << curr << '/' << result << "; somebody wrote to us after free!!!\n" << end(); + break; // always fatal + } + } if (SIZE(current_instruction().ingredients) > 1) Memory[result] = array_length; else diff --git a/044space.cc b/044space.cc index 557ee04c..17ca4d2a 100644 --- a/044space.cc +++ b/044space.cc @@ -51,8 +51,10 @@ reagent r = absolutize(x); reagent absolutize(reagent x) { //? cout << "absolutize " << x.to_string() << '\n'; //? 4 if (is_raw(x) || is_dummy(x)) return x; - if (!x.initialized) - raise << current_instruction().to_string() << ": reagent not initialized: " << x.original_string << die(); + if (!x.initialized) { + raise << current_instruction().to_string() << ": reagent not initialized: " << x.original_string << end(); + return x; + } reagent r = x; r.set_value(address(r.value, space_base(r))); r.properties.push_back(pair<string, vector<string> >("raw", vector<string>())); @@ -131,13 +133,13 @@ if (curr.name == "new-default-space") { vector<double> result; result.push_back(Name[Recipe_ordinal[current_recipe_name()]][""]); if (result.back() == 0) - raise << "no space allocated for default-space in recipe " << current_recipe_name() << "; are you using names\n"; + raise << "no space allocated for default-space in recipe " << current_recipe_name() << "; are you using names\n" << end(); return result; } :(after "void write_memory(reagent x, vector<double> data)") if (x.name == "number-of-locals") { assert(scalar(data)); - raise << "can't write to special variable number-of-locals\n"; + raise << "can't write to special variable number-of-locals\n" << end(); return; } @@ -186,11 +188,11 @@ void try_reclaim_locals() { void rewrite_default_space_instruction(instruction& curr) { curr.operation = Recipe_ordinal["new"]; if (!curr.ingredients.empty()) - raise << "new-default-space can't take any ingredients\n"; + raise << "new-default-space can't take any ingredients\n" << end(); curr.ingredients.push_back(reagent("location:type")); curr.ingredients.push_back(reagent("number-of-locals:literal")); if (!curr.products.empty()) - raise << "new-default-space can't take any results\n"; + raise << "new-default-space can't take any results\n" << end(); curr.products.push_back(reagent("default-space:address:array:location")); } @@ -206,7 +208,7 @@ long long int address(long long int offset, long long int base) { //? cout << base << '\n'; //? 2 if (offset >= static_cast<long long int>(Memory[base])) { // todo: test - raise << "location " << offset << " is out of bounds " << Memory[base] << " at " << base << '\n'; + raise << "location " << offset << " is out of bounds " << Memory[base] << " at " << base << '\n' << end(); } return base+1 + offset; } diff --git a/046closure_name.cc b/046closure_name.cc index a9a7575c..bc7460f5 100644 --- a/046closure_name.cc +++ b/046closure_name.cc @@ -52,20 +52,22 @@ void collect_surrounding_spaces(const recipe_ordinal r) { || inst.products.at(j).types.at(0) != Type_ordinal["address"] || inst.products.at(j).types.at(1) != Type_ordinal["array"] || inst.products.at(j).types.at(2) != Type_ordinal["location"]) { - raise << "slot 0 should always have type address:array:location, but is " << inst.products.at(j).to_string() << '\n'; + raise << "slot 0 should always have type address:array:location, but is " << inst.products.at(j).to_string() << '\n' << end(); continue; } vector<string> s = property(inst.products.at(j), "names"); - if (s.empty()) - raise << "slot 0 requires a /names property in recipe " << Recipe[r].name << die(); - if (SIZE(s) > 1) raise << "slot 0 should have a single value in /names, got " << inst.products.at(j).to_string() << '\n'; + if (s.empty()) { + raise << "slot 0 requires a /names property in recipe " << Recipe[r].name << end(); + continue; + } + if (SIZE(s) > 1) raise << "slot 0 should have a single value in /names, got " << inst.products.at(j).to_string() << '\n' << end(); string surrounding_recipe_name = s.at(0); if (Surrounding_space.find(r) != Surrounding_space.end() && Surrounding_space[r] != Recipe_ordinal[surrounding_recipe_name]) { - raise << "recipe " << Recipe[r].name << " can have only one 'surrounding' recipe but has " << Recipe[Surrounding_space[r]].name << " and " << surrounding_recipe_name << '\n'; + raise << "recipe " << Recipe[r].name << " can have only one 'surrounding' recipe but has " << Recipe[Surrounding_space[r]].name << " and " << surrounding_recipe_name << '\n' << end(); continue; } - trace("name") << "recipe " << Recipe[r].name << " is surrounded by " << surrounding_recipe_name; + trace("name") << "recipe " << Recipe[r].name << " is surrounded by " << surrounding_recipe_name << end(); Surrounding_space[r] = Recipe_ordinal[surrounding_recipe_name]; } } @@ -79,11 +81,11 @@ long long int lookup_name(const reagent& x, const recipe_ordinal default_recipe) //? cout << "AAA " << default_recipe << " " << Recipe[default_recipe].name << '\n'; //? 2 //? cout << "AAA " << x.to_string() << '\n'; //? 1 if (!has_property(x, "space")) { - if (Name[default_recipe].empty()) raise << "name not found: " << x.name << '\n' << die(); + if (Name[default_recipe].empty()) raise << "name not found: " << x.name << '\n' << end(); return Name[default_recipe][x.name]; } vector<string> p = property(x, "space"); - if (SIZE(p) != 1) raise << "/space property should have exactly one (non-negative integer) value\n"; + if (SIZE(p) != 1) raise << "/space property should have exactly one (non-negative integer) value\n" << end(); long long int n = to_integer(p.at(0)); assert(n >= 0); recipe_ordinal surrounding_recipe = lookup_surrounding_recipe(default_recipe, n); @@ -97,11 +99,11 @@ long long int lookup_name(const reagent& x, const recipe_ordinal default_recipe) long long int lookup_name(const reagent& x, const recipe_ordinal r, set<recipe_ordinal>& done, vector<recipe_ordinal>& path) { if (!Name[r].empty()) return Name[r][x.name]; if (done.find(r) != done.end()) { - raise << "can't compute address of " << x.to_string() << " because "; + raise << "can't compute address of " << x.to_string() << " because " << end(); for (long long int i = 1; i < SIZE(path); ++i) { - raise << path.at(i-1) << " requires computing names of " << path.at(i) << '\n'; + raise << path.at(i-1) << " requires computing names of " << path.at(i) << '\n' << end(); } - raise << path.at(SIZE(path)-1) << " requires computing names of " << r << "..ad infinitum\n" << die(); + raise << path.at(SIZE(path)-1) << " requires computing names of " << r << "..ad infinitum\n" << end(); return 0; } done.insert(r); @@ -114,7 +116,7 @@ long long int lookup_name(const reagent& x, const recipe_ordinal r, set<recipe_o recipe_ordinal lookup_surrounding_recipe(const recipe_ordinal r, long long int n) { if (n == 0) return r; if (Surrounding_space.find(r) == Surrounding_space.end()) { - raise << "don't know surrounding recipe of " << Recipe[r].name << '\n'; + raise << "don't know surrounding recipe of " << Recipe[r].name << '\n' << end(); return 0; } assert(Surrounding_space[r]); diff --git a/047global.cc b/047global.cc index e3dbe356..6ce4b78f 100644 --- a/047global.cc +++ b/047global.cc @@ -33,7 +33,7 @@ global_space = 0; if (x.name == "global-space") { assert(scalar(data)); if (Current_routine->global_space) - raise << "routine already has a global-space; you can't over-write your globals"; + raise << "routine already has a global-space; you can't over-write your globals" << end(); Current_routine->global_space = data.at(0); return; } @@ -42,7 +42,7 @@ global_space = 0; :(after "long long int space_base(const reagent& x)") if (is_global(x)) { if (!Current_routine->global_space) - raise << "routine has no global space\n" << die(); + raise << "routine has no global space\n" << end(); return Current_routine->global_space; } diff --git a/049continuation.cc b/049continuation.cc index c292f44b..e625e7b7 100644 --- a/049continuation.cc +++ b/049continuation.cc @@ -30,7 +30,7 @@ case CURRENT_CONTINUATION: { products.resize(1); products.at(0).push_back(Next_continuation_id); ++Next_continuation_id; - trace("current-continuation") << "new continuation " << Next_continuation_id; + trace("current-continuation") << "new continuation " << Next_continuation_id << end(); break; } diff --git a/050scenario.cc b/050scenario.cc index 8f3ec77e..358c767c 100644 --- a/050scenario.cc +++ b/050scenario.cc @@ -257,16 +257,16 @@ void check_memory(const string& s) { skip_whitespace_and_comments(in); int value = 0; in >> value; if (locations_checked.find(address) != locations_checked.end()) - raise << "duplicate expectation for location " << address << '\n'; - trace(Primitive_recipe_depth, "run") << "checking location " << address; + raise << "duplicate expectation for location " << address << '\n' << end(); + trace(Primitive_recipe_depth, "run") << "checking location " << address << end(); if (Memory[address] != value) { if (Current_scenario && !Scenario_testing_scenario) { // genuine test in a mu file - raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n'; + raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n' << end(); } else { // just testing scenario support - raise << "expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n'; + raise << "expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n' << end(); } if (!Scenario_testing_scenario) { Passed = false; @@ -294,16 +294,16 @@ void check_type(const string& lhs, istream& in) { check_string(address, literal); return; } - raise << "don't know how to check memory for " << lhs << '\n'; + raise << "don't know how to check memory for " << lhs << '\n' << end(); } void check_string(long long int address, const string& literal) { - trace(Primitive_recipe_depth, "run") << "checking string length at " << address; + trace(Primitive_recipe_depth, "run") << "checking string length at " << address << end(); if (Memory[address] != SIZE(literal)) { if (Current_scenario && !Scenario_testing_scenario) - raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << Memory[address] << '\n'; + raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << Memory[address] << '\n' << end(); else - raise << "expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << Memory[address] << '\n'; + raise << "expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << Memory[address] << '\n' << end(); if (!Scenario_testing_scenario) { Passed = false; ++Num_failures; @@ -312,15 +312,15 @@ void check_string(long long int address, const string& literal) { } ++address; // now skip length for (long long int i = 0; i < SIZE(literal); ++i) { - trace(Primitive_recipe_depth, "run") << "checking location " << address+i; + trace(Primitive_recipe_depth, "run") << "checking location " << address+i << end(); if (Memory[address+i] != literal.at(i)) { if (Current_scenario && !Scenario_testing_scenario) { // genuine test in a mu file - raise << "\nF - " << Current_scenario->name << ": expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << Memory[address+i] << '\n'; + raise << "\nF - " << Current_scenario->name << ": expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << Memory[address+i] << '\n' << end(); } else { // just testing scenario support - raise << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << Memory[address+i] << '\n'; + raise << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << Memory[address+i] << '\n' << end(); } if (!Scenario_testing_scenario) { Passed = false; @@ -421,7 +421,7 @@ bool check_trace(const string& expected) { } raise << "missing [" << expected_lines.at(curr_expected_line).contents << "] " - << "in trace layer " << expected_lines.at(curr_expected_line).label << '\n'; + << "in trace layer " << expected_lines.at(curr_expected_line).label << '\n' << end(); Passed = false; return false; } @@ -502,7 +502,7 @@ bool check_trace_missing(const string& in) { vector<trace_line> lines = parse_trace(in); for (long long int i = 0; i < SIZE(lines); ++i) { if (trace_count(lines.at(i).label, lines.at(i).contents) != 0) { - raise << "unexpected [" << lines.at(i).contents << "] in trace layer " << lines.at(i).label << '\n'; + raise << "unexpected [" << lines.at(i).contents << "] in trace layer " << lines.at(i).label << '\n' << end(); Passed = false; return false; } diff --git a/072scenario_screen.cc b/072scenario_screen.cc index 8e3f0d9c..b3642f1a 100644 --- a/072scenario_screen.cc +++ b/072scenario_screen.cc @@ -236,11 +236,11 @@ void check_screen(const string& expected_contents, const int color) { // contents match but color is off if (Current_scenario && !Scenario_testing_scenario) { // genuine test in a mu file - raise << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ", address " << addr << ", value " << Memory[addr] << ") to be in color " << color << " instead of " << Memory[addr+cell_color_offset] << "\n"; + raise << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ", address " << addr << ", value " << Memory[addr] << ") to be in color " << color << " instead of " << Memory[addr+cell_color_offset] << "\n" << end(); } else { // just testing check_screen - raise << "expected screen location (" << row << ", " << column << ") to be in color " << color << " instead of " << Memory[addr+cell_color_offset] << '\n'; + raise << "expected screen location (" << row << ", " << column << ") to be in color " << color << " instead of " << Memory[addr+cell_color_offset] << '\n' << end(); } if (!Scenario_testing_scenario) { Passed = false; @@ -265,12 +265,12 @@ void check_screen(const string& expected_contents, const int color) { if (Current_scenario && !Scenario_testing_scenario) { // genuine test in a mu file - raise << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << " instead of " << Memory[addr] << actual_pretty << '\n'; + raise << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << " instead of " << Memory[addr] << actual_pretty << '\n' << end(); dump_screen(); } else { // just testing check_screen - raise << "expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << " instead of " << Memory[addr] << actual_pretty << '\n'; + raise << "expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << " instead of " << Memory[addr] << actual_pretty << '\n' << end(); } if (!Scenario_testing_scenario) { Passed = false; @@ -291,7 +291,7 @@ bool raw_string_stream::at_end() const { //? cerr << buf << "$\n"; //? 1 if (index >= max) return true; if (tb_utf8_char_length(buf[index]) > max-index) { - raise << "unicode string seems corrupted at index "<< index << " character " << static_cast<int>(buf[index]) << '\n'; + raise << "unicode string seems corrupted at index "<< index << " character " << static_cast<int>(buf[index]) << '\n' << end(); return true; } return false; diff --git a/075scenario_console.cc b/075scenario_console.cc index c5946617..bf58c46c 100644 --- a/075scenario_console.cc +++ b/075scenario_console.cc @@ -167,8 +167,10 @@ Recipe_ordinal["replace-in-console"] = REPLACE_IN_CONSOLE; case REPLACE_IN_CONSOLE: { assert(scalar(ingredients.at(0))); //? cerr << "console: " << Memory[CONSOLE] << '\n'; //? 1 - if (!Memory[CONSOLE]) - raise << "console not initialized\n" << die(); + if (!Memory[CONSOLE]) { + raise << "console not initialized\n" << end(); + break; + } long long int console_data = Memory[Memory[CONSOLE]+1]; //? cerr << "console data starts at " << console_data << '\n'; //? 1 long long int size = Memory[console_data]; // array size diff --git a/082persist.cc b/082persist.cc index b4817dc0..9d1fa8b2 100644 --- a/082persist.cc +++ b/082persist.cc @@ -9,7 +9,7 @@ Recipe_ordinal["restore"] = RESTORE; :(before "End Primitive Recipe Implementations") case RESTORE: { if (!scalar(ingredients.at(0))) - raise << "restore: illegal operand " << current_instruction().ingredients.at(0).to_string() << '\n'; + raise << "restore: illegal operand " << current_instruction().ingredients.at(0).to_string() << '\n' << end(); products.resize(1); string filename = current_instruction().ingredients.at(0).name; if (!is_literal(current_instruction().ingredients.at(0))) @@ -48,13 +48,13 @@ Recipe_ordinal["save"] = SAVE; :(before "End Primitive Recipe Implementations") case SAVE: { if (!scalar(ingredients.at(0))) - raise << "save: illegal operand 0 " << current_instruction().ingredients.at(0).to_string() << '\n'; + raise << "save: illegal operand 0 " << current_instruction().ingredients.at(0).to_string() << '\n' << end(); string filename = current_instruction().ingredients.at(0).name; if (!is_literal(current_instruction().ingredients.at(0))) filename = to_string(ingredients.at(0).at(0)); ofstream fout(("lesson/"+filename).c_str()); if (!scalar(ingredients.at(1))) - raise << "save: illegal operand 1 " << current_instruction().ingredients.at(1).to_string() << '\n'; + raise << "save: illegal operand 1 " << current_instruction().ingredients.at(1).to_string() << '\n' << end(); string contents = read_mu_string(ingredients.at(1).at(0)); fout << contents; fout.close(); @@ -62,7 +62,7 @@ case SAVE: { // bug in git: git diff -q messes up --exit-code int status = system("cd lesson; git add .; git diff HEAD --exit-code >/dev/null || git commit -a -m . >/dev/null"); if (status != 0) - raise << "error in commit: contents " << contents << '\n'; + raise << "error in commit: contents " << contents << '\n' << end(); break; } |