2712
This commit is contained in:
parent
b436291f40
commit
1b76245c63
|
@ -157,7 +157,7 @@ trace_stream* Trace_stream = NULL;
|
|||
#define trace(...) !Trace_stream ? cerr /*print nothing*/ : Trace_stream->stream(__VA_ARGS__)
|
||||
|
||||
// Errors are a special layer.
|
||||
#define raise_error (!Trace_stream ? (tb_shutdown(),cerr) /*do print*/ : Trace_stream->stream(Error_depth, "error"))
|
||||
#define raise (!Trace_stream ? (tb_shutdown(),cerr) /*do print*/ : Trace_stream->stream(Error_depth, "error"))
|
||||
// Inside tests, fail any tests that displayed (unexpected) errors.
|
||||
// Expected errors in tests should always be hidden and silently checked for.
|
||||
:(before "End Test Teardown")
|
||||
|
|
18
011load.cc
18
011load.cc
|
@ -34,7 +34,7 @@ vector<recipe_ordinal> load(istream& in) {
|
|||
}
|
||||
// End Command Handlers
|
||||
else {
|
||||
raise_error << "unknown top-level command: " << command << '\n' << end();
|
||||
raise << "unknown top-level command: " << command << '\n' << end();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -47,14 +47,14 @@ long long int slurp_recipe(istream& in) {
|
|||
skip_whitespace_but_not_newline(in);
|
||||
// End Recipe Refinements
|
||||
if (result.name.empty())
|
||||
raise_error << "empty result.name\n" << end();
|
||||
raise << "empty result.name\n" << end();
|
||||
trace(9991, "parse") << "--- defining " << result.name << end();
|
||||
if (!contains_key(Recipe_ordinal, result.name))
|
||||
put(Recipe_ordinal, result.name, Next_recipe_ordinal++);
|
||||
if (Recipe.find(get(Recipe_ordinal, result.name)) != Recipe.end()) {
|
||||
trace(9991, "parse") << "already exists" << end();
|
||||
if (should_check_for_redefine(result.name))
|
||||
raise_error << "redefining recipe " << result.name << "\n" << end();
|
||||
raise << "redefining recipe " << result.name << "\n" << end();
|
||||
Recipe.erase(get(Recipe_ordinal, result.name));
|
||||
}
|
||||
slurp_body(in, result);
|
||||
|
@ -69,7 +69,7 @@ void slurp_body(istream& in, recipe& result) {
|
|||
in >> std::noskipws;
|
||||
skip_whitespace_but_not_newline(in);
|
||||
if (in.get() != '[')
|
||||
raise_error << "recipe body must begin with '['\n" << end();
|
||||
raise << "recipe body must begin with '['\n" << end();
|
||||
skip_whitespace_and_comments(in); // permit trailing comment after '['
|
||||
instruction curr;
|
||||
while (next_instruction(in, &curr)) {
|
||||
|
@ -86,7 +86,7 @@ bool next_instruction(istream& in, instruction* curr) {
|
|||
curr->clear();
|
||||
skip_whitespace_and_comments(in);
|
||||
if (!has_data(in)) {
|
||||
raise_error << "0: unbalanced '[' for recipe\n" << end();
|
||||
raise << "0: unbalanced '[' for recipe\n" << end();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ bool next_instruction(istream& in, instruction* curr) {
|
|||
while (has_data(in) && in.peek() != '\n') {
|
||||
skip_whitespace_but_not_newline(in);
|
||||
if (!has_data(in)) {
|
||||
raise_error << "1: unbalanced '[' for recipe\n" << end();
|
||||
raise << "1: unbalanced '[' for recipe\n" << end();
|
||||
return false;
|
||||
}
|
||||
string word = next_word(in);
|
||||
|
@ -110,7 +110,7 @@ bool next_instruction(istream& in, instruction* curr) {
|
|||
curr->label = words.at(0);
|
||||
trace(9993, "parse") << "label: " << curr->label << end();
|
||||
if (!has_data(in)) {
|
||||
raise_error << "7: unbalanced '[' for recipe\n" << end();
|
||||
raise << "7: unbalanced '[' for recipe\n" << end();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -124,7 +124,7 @@ bool next_instruction(istream& in, instruction* curr) {
|
|||
}
|
||||
|
||||
if (p == words.end()) {
|
||||
raise_error << "instruction prematurely ended with '<-'\n" << end();
|
||||
raise << "instruction prematurely ended with '<-'\n" << end();
|
||||
return false;
|
||||
}
|
||||
curr->old_name = curr->name = *p; p++;
|
||||
|
@ -140,7 +140,7 @@ bool next_instruction(istream& in, instruction* curr) {
|
|||
for (vector<reagent>::iterator p = curr->products.begin(); p != curr->products.end(); ++p)
|
||||
trace(9993, "parse") << " product: " << to_string(*p) << end();
|
||||
if (!has_data(in)) {
|
||||
raise_error << "9: unbalanced '[' for recipe\n" << end();
|
||||
raise << "9: unbalanced '[' for recipe\n" << end();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -13,7 +13,7 @@ void update_instruction_operations(recipe_ordinal r) {
|
|||
instruction& inst = caller.steps.at(index);
|
||||
if (inst.is_label) continue;
|
||||
if (!contains_key(Recipe_ordinal, inst.name)) {
|
||||
raise_error << maybe(caller.name) << "instruction " << inst.name << " has no recipe\n" << end();
|
||||
raise << maybe(caller.name) << "instruction " << inst.name << " has no recipe\n" << end();
|
||||
continue;
|
||||
}
|
||||
inst.operation = get(Recipe_ordinal, inst.name);
|
||||
|
|
|
@ -72,7 +72,7 @@ void slurp_quoted_comment_oblivious(istream& in, ostream& out) {
|
|||
if (brace_depth == 0) break;
|
||||
}
|
||||
if (!has_data(in) && brace_depth > 0) {
|
||||
raise_error << "unbalanced '['\n" << end();
|
||||
raise << "unbalanced '['\n" << end();
|
||||
out.clear();
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ void slurp_quoted_comment_aware(istream& in, ostream& out) {
|
|||
out << c;
|
||||
if (c == ']') return;
|
||||
}
|
||||
raise_error << "unbalanced '['\n" << end();
|
||||
raise << "unbalanced '['\n" << end();
|
||||
out.clear();
|
||||
}
|
||||
|
||||
|
|
10
020run.cc
10
020run.cc
|
@ -63,7 +63,7 @@ void run_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_error << "something wrote to location 0; this should never happen\n" << end();
|
||||
raise << "something wrote to location 0; this should never happen\n" << end();
|
||||
put(Memory, 0, 0);
|
||||
}
|
||||
// read all ingredients from memory, each potentially spanning multiple locations
|
||||
|
@ -86,7 +86,7 @@ void run_current_routine()
|
|||
}
|
||||
}
|
||||
if (SIZE(products) < SIZE(current_instruction().products)) {
|
||||
raise_error << SIZE(products) << " vs " << SIZE(current_instruction().products) << ": failed to write to all products! " << to_string(current_instruction()) << '\n' << end();
|
||||
raise << SIZE(products) << " vs " << SIZE(current_instruction().products) << ": failed to write to all products! " << to_string(current_instruction()) << '\n' << end();
|
||||
}
|
||||
else {
|
||||
for (long long int i = 0; i < SIZE(current_instruction().products); ++i) {
|
||||
|
@ -210,7 +210,7 @@ void load_permanently(string filename) {
|
|||
}
|
||||
ifstream fin(filename.c_str());
|
||||
if (!fin) {
|
||||
raise_error << "no such file " << filename << '\n' << end();
|
||||
raise << "no such file " << filename << '\n' << end();
|
||||
return;
|
||||
}
|
||||
trace(9990, "load") << "=== " << filename << end();
|
||||
|
@ -264,7 +264,7 @@ vector<double> read_memory(reagent x) {
|
|||
|
||||
void write_memory(reagent x, vector<double> data) {
|
||||
if (!x.type) {
|
||||
raise_error << "can't write to " << to_string(x) << "; no type\n" << end();
|
||||
raise << "can't write to " << to_string(x) << "; no type\n" << end();
|
||||
return;
|
||||
}
|
||||
if (is_dummy(x)) return;
|
||||
|
@ -272,7 +272,7 @@ void write_memory(reagent x, vector<double> data) {
|
|||
long long int base = x.value;
|
||||
if (base == 0) return;
|
||||
if (size_mismatch(x, data)) {
|
||||
raise_error << maybe(current_recipe_name()) << "size mismatch in storing to " << x.original_string << " (" << size_of(x.type) << " vs " << SIZE(data) << ") at '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "size mismatch in storing to " << x.original_string << " (" << size_of(x.type) << " vs " << SIZE(data) << ") at '" << to_string(current_instruction()) << "'\n" << end();
|
||||
return;
|
||||
}
|
||||
// End write_memory(reagent x, long long int base) Special-cases
|
||||
|
|
|
@ -23,12 +23,12 @@ void check_instruction(const recipe_ordinal r) {
|
|||
// Primitive Recipe Checks
|
||||
case COPY: {
|
||||
if (SIZE(inst.products) != SIZE(inst.ingredients)) {
|
||||
raise_error << "ingredients and products should match in '" << to_string(inst) << "'\n" << end();
|
||||
raise << "ingredients and products should match in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!types_coercible(inst.products.at(i), inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "can't copy " << inst.ingredients.at(i).original_string << " to " << inst.products.at(i).original_string << "; types don't match\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "can't copy " << inst.ingredients.at(i).original_string << " to " << inst.products.at(i).original_string << "; types don't match\n" << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,16 +9,16 @@ case ADD: {
|
|||
// primary goal of these checks is to forbid address arithmetic
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_number(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'add' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'add' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'add' yields exactly one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'add' yields exactly one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'add' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'add' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -75,22 +75,22 @@ put(Recipe_ordinal, "subtract", SUBTRACT);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case SUBTRACT: {
|
||||
if (inst.ingredients.empty()) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'subtract' has no ingredients\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'subtract' has no ingredients\n" << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (is_raw(inst.ingredients.at(i))) continue; // permit address offset computations in tests
|
||||
if (!is_mu_number(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'subtract' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'subtract' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'subtract' yields exactly one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'subtract' yields exactly one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'subtract' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'subtract' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -137,16 +137,16 @@ put(Recipe_ordinal, "multiply", MULTIPLY);
|
|||
case MULTIPLY: {
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_number(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'multiply' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'multiply' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'multiply' yields exactly one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'multiply' yields exactly one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'multiply' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'multiply' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -189,21 +189,21 @@ put(Recipe_ordinal, "divide", DIVIDE);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case DIVIDE: {
|
||||
if (inst.ingredients.empty()) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'divide' has no ingredients\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'divide' has no ingredients\n" << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_number(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'divide' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'divide' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'divide' yields exactly one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'divide' yields exactly one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'divide' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'divide' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -247,20 +247,20 @@ put(Recipe_ordinal, "divide-with-remainder", DIVIDE_WITH_REMAINDER);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case DIVIDE_WITH_REMAINDER: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'divide-with-remainder' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'divide-with-remainder' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'divide-with-remainder' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'divide-with-remainder' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (SIZE(inst.products) > 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'divide-with-remainder' yields two products in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'divide-with-remainder' yields two products in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.products); ++i) {
|
||||
if (!is_dummy(inst.products.at(i)) && !is_mu_number(inst.products.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'divide-with-remainder' should yield a number, but got " << inst.products.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'divide-with-remainder' should yield a number, but got " << inst.products.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ case DIVIDE_WITH_REMAINDER: {
|
|||
long long int a = static_cast<long long int>(ingredients.at(0).at(0));
|
||||
long long int b = static_cast<long long int>(ingredients.at(1).at(0));
|
||||
if (b == 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "divide by zero in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "divide by zero in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
products.resize(2);
|
||||
products.at(0).push_back(0);
|
||||
products.at(1).push_back(0);
|
||||
|
@ -331,19 +331,19 @@ put(Recipe_ordinal, "shift-left", SHIFT_LEFT);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case SHIFT_LEFT: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'shift-left' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'shift-left' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'shift-left' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'shift-left' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'shift-left' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'shift-left' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'shift-left' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'shift-left' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
break;
|
||||
|
@ -355,7 +355,7 @@ case SHIFT_LEFT: {
|
|||
long long int b = static_cast<long long int>(ingredients.at(1).at(0));
|
||||
products.resize(1);
|
||||
if (b < 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "second ingredient can't be negative in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "second ingredient can't be negative in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
products.at(0).push_back(0);
|
||||
break;
|
||||
}
|
||||
|
@ -402,19 +402,19 @@ put(Recipe_ordinal, "shift-right", SHIFT_RIGHT);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case SHIFT_RIGHT: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'shift-right' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'shift-right' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'shift-right' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'shift-right' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'shift-right' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'shift-right' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'shift-right' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'shift-right' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
break;
|
||||
|
@ -426,7 +426,7 @@ case SHIFT_RIGHT: {
|
|||
long long int b = static_cast<long long int>(ingredients.at(1).at(0));
|
||||
products.resize(1);
|
||||
if (b < 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "second ingredient can't be negative in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "second ingredient can't be negative in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
products.at(0).push_back(0);
|
||||
break;
|
||||
}
|
||||
|
@ -473,19 +473,19 @@ put(Recipe_ordinal, "and-bits", AND_BITS);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case AND_BITS: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'and-bits' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'and-bits' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'and-bits' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'and-bits' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'and-bits' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'and-bits' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'and-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'and-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
break;
|
||||
|
@ -531,19 +531,19 @@ put(Recipe_ordinal, "or-bits", OR_BITS);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case OR_BITS: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'or-bits' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'or-bits' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'or-bits' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'or-bits' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'or-bits' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'or-bits' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'or-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'or-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
break;
|
||||
|
@ -583,19 +583,19 @@ put(Recipe_ordinal, "xor-bits", XOR_BITS);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case XOR_BITS: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'xor-bits' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'xor-bits' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'xor-bits' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'xor-bits' requires number ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'xor-bits' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'xor-bits' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'xor-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'xor-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
break;
|
||||
|
@ -635,19 +635,19 @@ put(Recipe_ordinal, "flip-bits", FLIP_BITS);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case FLIP_BITS: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'flip-bits' requires exactly one ingredient, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'flip-bits' requires exactly one ingredient, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'flip-bits' requires a number ingredient, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'flip-bits' requires a number ingredient, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (SIZE(inst.products) > 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'flip-bits' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'flip-bits' yields one product in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'flip-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'flip-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -8,7 +8,7 @@ put(Recipe_ordinal, "and", AND);
|
|||
case AND: {
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_scalar(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'and' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'and' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ put(Recipe_ordinal, "or", OR);
|
|||
case OR: {
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_scalar(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'and' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'and' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
|
@ -107,12 +107,12 @@ put(Recipe_ordinal, "not", NOT);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case NOT: {
|
||||
if (SIZE(inst.products) > SIZE(inst.ingredients)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'not' cannot have fewer ingredients than products in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'not' cannot have fewer ingredients than products in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_scalar(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'not' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'not' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
|
|
16
024jump.cc
16
024jump.cc
|
@ -16,11 +16,11 @@ put(Recipe_ordinal, "jump", JUMP);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case JUMP: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'jump' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'jump' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'jump' should be a label or offset, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'jump' should be a label or offset, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -55,15 +55,15 @@ put(Recipe_ordinal, "jump-if", JUMP_IF);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case JUMP_IF: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'jump-if' requires exactly two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'jump-if' requires exactly two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'jump-if' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'jump-if' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'jump-if' requires a label or offset for its second ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'jump-if' requires a label or offset for its second ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -107,15 +107,15 @@ put(Recipe_ordinal, "jump-unless", JUMP_UNLESS);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case JUMP_UNLESS: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'jump-unless' requires exactly two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'jump-unless' requires exactly two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'jump-unless' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'jump-unless' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'jump-unless' requires a label or offset for its second ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'jump-unless' requires a label or offset for its second ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -7,7 +7,7 @@ put(Recipe_ordinal, "equal", EQUAL);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case EQUAL: {
|
||||
if (SIZE(inst.ingredients) <= 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'equal' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'equal' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -66,12 +66,12 @@ put(Recipe_ordinal, "greater-than", GREATER_THAN);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case GREATER_THAN: {
|
||||
if (SIZE(inst.ingredients) <= 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'greater-than' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'greater-than' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_number(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'greater-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'greater-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
|
@ -125,12 +125,12 @@ put(Recipe_ordinal, "lesser-than", LESSER_THAN);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case LESSER_THAN: {
|
||||
if (SIZE(inst.ingredients) <= 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'lesser-than' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'lesser-than' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_number(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'lesser-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'lesser-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
|
@ -184,12 +184,12 @@ put(Recipe_ordinal, "greater-or-equal", GREATER_OR_EQUAL);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case GREATER_OR_EQUAL: {
|
||||
if (SIZE(inst.ingredients) <= 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'greater-or-equal' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'greater-or-equal' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_number(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'greater-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'greater-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
|
@ -251,12 +251,12 @@ put(Recipe_ordinal, "lesser-or-equal", LESSER_OR_EQUAL);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case LESSER_OR_EQUAL: {
|
||||
if (SIZE(inst.ingredients) <= 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'lesser-or-equal' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'lesser-or-equal' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
|
||||
if (!is_mu_number(inst.ingredients.at(i))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'lesser-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'lesser-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
|
||||
goto finish_checking_instruction;
|
||||
}
|
||||
}
|
||||
|
|
16
029tools.cc
16
029tools.cc
|
@ -13,15 +13,15 @@ put(Recipe_ordinal, "trace", TRACE);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case TRACE: {
|
||||
if (SIZE(inst.ingredients) < 3) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'trace' takes three or more ingredients rather than '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'trace' takes three or more ingredients rather than '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'trace' should be a number (depth), but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'trace' should be a number (depth), but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_literal_string(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'trace' should be a literal string (label), but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'trace' should be a literal string (label), but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -199,15 +199,15 @@ put(Recipe_ordinal, "assert", ASSERT);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case ASSERT: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'assert' takes exactly two ingredients rather than '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'assert' takes exactly two ingredients rather than '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'assert' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'assert' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_literal_string(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'assert' requires a literal string for its second ingredient, but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'assert' requires a literal string for its second ingredient, but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -215,7 +215,7 @@ case ASSERT: {
|
|||
:(before "End Primitive Recipe Implementations")
|
||||
case ASSERT: {
|
||||
if (!ingredients.at(0).at(0)) {
|
||||
raise_error << current_instruction().ingredients.at(1).name << '\n' << end();
|
||||
raise << current_instruction().ingredients.at(1).name << '\n' << end();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ put(Recipe_ordinal, "$system", _SYSTEM);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case _SYSTEM: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'$system' requires exactly one ingredient, but got none\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'$system' requires exactly one ingredient, but got none\n" << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -88,7 +88,7 @@ if (type->value == 0) {
|
|||
return 1;
|
||||
}
|
||||
if (!contains_key(Type, type->value)) {
|
||||
raise_error << "no such type " << type->value << '\n' << end();
|
||||
raise << "no such type " << type->value << '\n' << end();
|
||||
return 0;
|
||||
}
|
||||
type_info t = get(Type, type->value);
|
||||
|
@ -98,7 +98,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 (t.elements.at(i).type->value == type->value) {
|
||||
raise_error << "container " << t.name << " can't include itself as a member\n" << end();
|
||||
raise << "container " << t.name << " can't include itself as a member\n" << end();
|
||||
return 0;
|
||||
}
|
||||
reagent tmp;
|
||||
|
@ -133,19 +133,19 @@ put(Recipe_ordinal, "get", GET);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case GET: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'get' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'get' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0); // new copy for every invocation
|
||||
// Update GET base in Check
|
||||
if (!base.type || !base.type->value || !contains_key(Type, base.type->value) || get(Type, base.type->value).kind != CONTAINER) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'get' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'get' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
type_ordinal base_type = base.type->value;
|
||||
reagent offset = inst.ingredients.at(1);
|
||||
if (!is_literal(offset) || !is_mu_scalar(offset)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'get' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'get' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
long long int offset_value = 0;
|
||||
|
@ -154,7 +154,7 @@ case GET: {
|
|||
else
|
||||
offset_value = offset.value;
|
||||
if (offset_value < 0 || offset_value >= SIZE(get(Type, base_type).elements)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << get(Type, base_type).name << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << get(Type, base_type).name << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (inst.products.empty()) break;
|
||||
|
@ -162,7 +162,7 @@ case GET: {
|
|||
// Update GET product in Check
|
||||
const reagent element = element_type(base, offset_value);
|
||||
if (!types_coercible(product, element)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'get " << base.original_string << ", " << offset.original_string << "' should write to " << names_to_string_without_quotes(element.type) << " but " << product.name << " has type " << names_to_string_without_quotes(product.type) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'get " << base.original_string << ", " << offset.original_string << "' should write to " << names_to_string_without_quotes(element.type) << " but " << product.name << " has type " << names_to_string_without_quotes(product.type) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -173,7 +173,7 @@ case GET: {
|
|||
// Update GET base in Run
|
||||
long long int base_address = base.value;
|
||||
if (base_address == 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
type_ordinal base_type = base.type->value;
|
||||
|
@ -270,26 +270,26 @@ put(Recipe_ordinal, "get-address", GET_ADDRESS);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case GET_ADDRESS: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'get-address' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'get-address' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0);
|
||||
// Update GET_ADDRESS base in Check
|
||||
if (!base.type || !base.type->value || !contains_key(Type, base.type->value) || get(Type, base.type->value).kind != CONTAINER) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'get-address' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'get-address' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
type_ordinal base_type = base.type->value;
|
||||
reagent offset = inst.ingredients.at(1);
|
||||
if (!is_literal(offset) || !is_mu_scalar(offset)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'get' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'get' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
long long int offset_value = 0;
|
||||
if (is_integer(offset.name)) { // later layers permit non-integer offsets
|
||||
offset_value = to_integer(offset.name);
|
||||
if (offset_value < 0 || offset_value >= SIZE(get(Type, base_type).elements)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << get(Type, base_type).name << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << get(Type, base_type).name << '\n' << end();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ case GET_ADDRESS: {
|
|||
// ..except for an address at the start
|
||||
element.type = new type_tree("address", get(Type_ordinal, "address"), element.type);
|
||||
if (!types_coercible(product, element)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'get-address " << base.original_string << ", " << offset.original_string << "' should write to " << names_to_string_without_quotes(element.type) << " but " << product.name << " has type " << names_to_string_without_quotes(product.type) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'get-address " << base.original_string << ", " << offset.original_string << "' should write to " << names_to_string_without_quotes(element.type) << " but " << product.name << " has type " << names_to_string_without_quotes(product.type) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -314,7 +314,7 @@ case GET_ADDRESS: {
|
|||
// Update GET_ADDRESS base in Run
|
||||
long long int base_address = base.value;
|
||||
if (base_address == 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
type_ordinal base_type = base.type->value;
|
||||
|
@ -453,7 +453,7 @@ void replace_unknown_types_with_unique_ordinals(type_tree* type, const type_info
|
|||
void skip_bracket(istream& in, string message) {
|
||||
skip_whitespace_and_comments(in);
|
||||
if (in.get() != '[')
|
||||
raise_error << message << '\n' << end();
|
||||
raise << message << '\n' << end();
|
||||
}
|
||||
|
||||
:(scenarios run)
|
||||
|
@ -559,7 +559,7 @@ void check_or_set_invalid_types(type_tree* type, const string& block, const stri
|
|||
if (contains_key(Type_ordinal, type->name))
|
||||
type->value = get(Type_ordinal, type->name);
|
||||
else
|
||||
raise_error << block << "unknown type " << type->name << " in " << name << '\n' << end();
|
||||
raise << block << "unknown type " << type->name << " in " << name << '\n' << end();
|
||||
}
|
||||
check_or_set_invalid_types(type->left, block, name);
|
||||
check_or_set_invalid_types(type->right, block, name);
|
||||
|
@ -603,7 +603,7 @@ void check_invalid_types(const type_tree* type, const string& block, const strin
|
|||
return;
|
||||
}
|
||||
if (!contains_key(Type, type->value))
|
||||
raise_error << block << "unknown type in " << name << '\n' << end();
|
||||
raise << block << "unknown type in " << name << '\n' << end();
|
||||
check_invalid_types(type->left, block, name);
|
||||
check_invalid_types(type->right, block, name);
|
||||
}
|
||||
|
@ -722,19 +722,19 @@ void check_merge_calls(const recipe_ordinal r) {
|
|||
const instruction& inst = caller.steps.at(i);
|
||||
if (inst.name != "merge") continue;
|
||||
if (SIZE(inst.products) != 1) {
|
||||
raise_error << maybe(caller.name) << "'merge' should yield a single product in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "'merge' should yield a single product in '" << to_string(inst) << "'\n" << end();
|
||||
continue;
|
||||
}
|
||||
reagent product = inst.products.at(0);
|
||||
// Update product While Type-checking Merge
|
||||
type_ordinal product_type = product.type->value;
|
||||
if (product_type == 0 || !contains_key(Type, product_type)) {
|
||||
raise_error << maybe(caller.name) << "'merge' should yield a container in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "'merge' should yield a container in '" << to_string(inst) << "'\n" << end();
|
||||
continue;
|
||||
}
|
||||
const type_info& info = get(Type, product_type);
|
||||
if (info.kind != CONTAINER && info.kind != EXCLUSIVE_CONTAINER) {
|
||||
raise_error << maybe(caller.name) << "'merge' should yield a container in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "'merge' should yield a container in '" << to_string(inst) << "'\n" << end();
|
||||
continue;
|
||||
}
|
||||
check_merge_call(inst.ingredients, product, caller, inst);
|
||||
|
@ -749,7 +749,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
|
|||
assert(!state.data.empty());
|
||||
trace(9999, "transform") << ingredient_index << " vs " << SIZE(ingredients) << end();
|
||||
if (ingredient_index >= SIZE(ingredients)) {
|
||||
raise_error << maybe(caller.name) << "too few ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "too few ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
return;
|
||||
}
|
||||
reagent& container = state.data.top().container;
|
||||
|
@ -766,7 +766,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
|
|||
state.data.pop();
|
||||
if (state.data.empty()) {
|
||||
if (ingredient_index < SIZE(ingredients))
|
||||
raise_error << maybe(caller.name) << "too many ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "too many ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
return;
|
||||
}
|
||||
++state.data.top().container_element_index;
|
||||
|
@ -782,7 +782,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
|
|||
// End valid_merge Cases
|
||||
default: {
|
||||
if (!types_coercible(container, ingredients.at(ingredient_index))) {
|
||||
raise_error << maybe(caller.name) << "incorrect type of ingredient " << ingredient_index << " in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "incorrect type of ingredient " << ingredient_index << " in '" << to_string(inst) << "'\n" << end();
|
||||
cerr << " expected " << debug_string(container) << '\n';
|
||||
cerr << " got " << debug_string(ingredients.at(ingredient_index)) << '\n';
|
||||
return;
|
||||
|
@ -793,7 +793,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
|
|||
state.data.pop();
|
||||
if (state.data.empty()) {
|
||||
if (ingredient_index < SIZE(ingredients))
|
||||
raise_error << maybe(caller.name) << "too many ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "too many ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
return;
|
||||
}
|
||||
++state.data.top().container_element_index;
|
||||
|
|
|
@ -25,7 +25,7 @@ recipe main [
|
|||
:(before "long long int base = x.value" following "void write_memory(reagent x, vector<double> data)")
|
||||
canonize(x);
|
||||
if (x.value == 0) {
|
||||
raise_error << "can't write to location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << "can't write to location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -49,12 +49,12 @@ void canonize(reagent& x) {
|
|||
|
||||
void lookup_memory(reagent& x) {
|
||||
if (!x.type || x.type->value != get(Type_ordinal, "address")) {
|
||||
raise_error << maybe(current_recipe_name()) << "tried to /lookup " << x.original_string << " but it isn't an address\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "tried to /lookup " << x.original_string << " but it isn't an address\n" << end();
|
||||
return;
|
||||
}
|
||||
// compute value
|
||||
if (x.value == 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "tried to /lookup 0\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "tried to /lookup 0\n" << end();
|
||||
return;
|
||||
}
|
||||
trace(9999, "mem") << "location " << x.value << " is " << no_scientific(get_or_insert(Memory, x.value)) << end();
|
||||
|
@ -91,7 +91,7 @@ if (!canonize_type(product)) continue;
|
|||
bool canonize_type(reagent& r) {
|
||||
while (has_property(r, "lookup")) {
|
||||
if (!r.type || r.type->value != get(Type_ordinal, "address")) {
|
||||
raise_error << "can't lookup non-address: " << to_string(r) << ": " << to_string(r.type) << '\n' << end();
|
||||
raise << "can't lookup non-address: " << to_string(r) << ": " << to_string(r.type) << '\n' << end();
|
||||
return false;
|
||||
}
|
||||
drop_from_type(r, "address");
|
||||
|
@ -103,11 +103,11 @@ bool canonize_type(reagent& r) {
|
|||
|
||||
void drop_from_type(reagent& r, string expected_type) {
|
||||
if (!r.type) {
|
||||
raise_error << "can't drop " << expected_type << " from " << to_string(r) << '\n' << end();
|
||||
raise << "can't drop " << expected_type << " from " << to_string(r) << '\n' << end();
|
||||
return;
|
||||
}
|
||||
if (r.type->name != expected_type) {
|
||||
raise_error << "can't drop2 " << expected_type << " from " << to_string(r) << '\n' << end();
|
||||
raise << "can't drop2 " << expected_type << " from " << to_string(r) << '\n' << end();
|
||||
return;
|
||||
}
|
||||
type_tree* tmp = r.type;
|
||||
|
@ -197,7 +197,7 @@ recipe main [
|
|||
properties.push_back(pair<string, string_tree*>("lookup", NULL));
|
||||
}
|
||||
if (name.empty())
|
||||
raise_error << "illegal name " << original_string << '\n' << end();
|
||||
raise << "illegal name " << original_string << '\n' << end();
|
||||
}
|
||||
|
||||
//:: helpers for debugging
|
||||
|
|
42
032array.cc
42
032array.cc
|
@ -20,26 +20,26 @@ put(Recipe_ordinal, "create-array", CREATE_ARRAY);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case CREATE_ARRAY: {
|
||||
if (inst.products.empty()) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'create-array' needs one product and no ingredients but got '" << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'create-array' needs one product and no ingredients but got '" << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
reagent product = inst.products.at(0);
|
||||
canonize_type(product);
|
||||
if (!is_mu_array(product)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'create-array' cannot create non-array " << product.original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'create-array' cannot create non-array " << product.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!product.type->right) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "create array of what? " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "create array of what? " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
// 'create-array' will need to check properties rather than types
|
||||
if (!product.type->right->right) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "create array of what size? " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "create array of what size? " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_integer(product.type->right->right->name)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'create-array' product should specify size of array after its element type, but got " << product.type->right->right->name << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'create-array' product should specify size of array after its element type, but got " << product.type->right->right->name << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -109,7 +109,7 @@ if (x.type && x.type->value == get(Type_ordinal, "array")) return false;
|
|||
:(before "End size_of(reagent) Cases")
|
||||
if (r.type && r.type->value == get(Type_ordinal, "array")) {
|
||||
if (!r.type->right) {
|
||||
raise_error << maybe(current_recipe_name()) << "'" << r.original_string << "' is an array of what?\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "'" << r.original_string << "' is an array of what?\n" << end();
|
||||
return 1;
|
||||
}
|
||||
return 1 + get_or_insert(Memory, r.value)*size_of(array_element(r.type));
|
||||
|
@ -136,11 +136,11 @@ container foo [
|
|||
const type_tree* type = info.elements.back().type;
|
||||
if (type->name == "array") {
|
||||
if (!type->right) {
|
||||
raise_error << "container '" << name << "' doesn't specify type of array elements for " << info.elements.back().name << '\n' << end();
|
||||
raise << "container '" << name << "' doesn't specify type of array elements for " << info.elements.back().name << '\n' << end();
|
||||
continue;
|
||||
}
|
||||
if (!type->right->right) { // array has no length
|
||||
raise_error << "container '" << name << "' cannot determine size of element " << info.elements.back().name << '\n' << end();
|
||||
raise << "container '" << name << "' cannot determine size of element " << info.elements.back().name << '\n' << end();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -176,13 +176,13 @@ put(Recipe_ordinal, "index", INDEX);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case INDEX: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'index' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'index' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0);
|
||||
canonize_type(base);
|
||||
if (!is_mu_array(base)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'index' on a non-array " << base.original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'index' on a non-array " << base.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (inst.products.empty()) break;
|
||||
|
@ -191,7 +191,7 @@ case INDEX: {
|
|||
reagent element;
|
||||
element.type = new type_tree(*array_element(base.type));
|
||||
if (!types_coercible(product, element)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << names_to_string_without_quotes(element.type) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << names_to_string_without_quotes(element.type) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -203,7 +203,7 @@ case INDEX: {
|
|||
long long int base_address = base.value;
|
||||
trace(9998, "run") << "base address is " << base_address << end();
|
||||
if (base_address == 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent offset = current_instruction().ingredients.at(1);
|
||||
|
@ -211,7 +211,7 @@ case INDEX: {
|
|||
vector<double> offset_val(read_memory(offset));
|
||||
type_tree* element_type = array_element(base.type);
|
||||
if (offset_val.at(0) < 0 || offset_val.at(0) >= get_or_insert(Memory, base_address)) {
|
||||
raise_error << maybe(current_recipe_name()) << "invalid index " << no_scientific(offset_val.at(0)) << '\n' << end();
|
||||
raise << maybe(current_recipe_name()) << "invalid index " << no_scientific(offset_val.at(0)) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
long long int src = base_address + 1 + offset_val.at(0)*size_of(element_type);
|
||||
|
@ -316,13 +316,13 @@ put(Recipe_ordinal, "index-address", INDEX_ADDRESS);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case INDEX_ADDRESS: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'index-address' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'index-address' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0);
|
||||
canonize_type(base);
|
||||
if (!is_mu_array(base)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'index-address' on a non-array " << base.original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'index-address' on a non-array " << base.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (inst.products.empty()) break;
|
||||
|
@ -332,7 +332,7 @@ case INDEX_ADDRESS: {
|
|||
element.type = new type_tree("address", get(Type_ordinal, "address"),
|
||||
new type_tree(*array_element(base.type)));
|
||||
if (!types_coercible(product, element)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << names_to_string_without_quotes(element.type) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << names_to_string_without_quotes(element.type) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -343,7 +343,7 @@ case INDEX_ADDRESS: {
|
|||
canonize(base);
|
||||
long long int base_address = base.value;
|
||||
if (base_address == 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent offset = current_instruction().ingredients.at(1);
|
||||
|
@ -351,7 +351,7 @@ case INDEX_ADDRESS: {
|
|||
vector<double> offset_val(read_memory(offset));
|
||||
type_tree* element_type = array_element(base.type);
|
||||
if (offset_val.at(0) < 0 || offset_val.at(0) >= get_or_insert(Memory, base_address)) {
|
||||
raise_error << maybe(current_recipe_name()) << "invalid index " << no_scientific(offset_val.at(0)) << '\n' << end();
|
||||
raise << maybe(current_recipe_name()) << "invalid index " << no_scientific(offset_val.at(0)) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
long long int result = base_address + 1 + offset_val.at(0)*size_of(element_type);
|
||||
|
@ -424,13 +424,13 @@ put(Recipe_ordinal, "length", LENGTH);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case LENGTH: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'length' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'length' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent x = inst.ingredients.at(0);
|
||||
canonize_type(x);
|
||||
if (!is_mu_array(x)) {
|
||||
raise_error << "tried to calculate length of non-array " << x.original_string << '\n' << end();
|
||||
raise << "tried to calculate length of non-array " << x.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -440,7 +440,7 @@ case LENGTH: {
|
|||
reagent x = current_instruction().ingredients.at(0);
|
||||
canonize(x);
|
||||
if (x.value == 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
products.resize(1);
|
||||
|
|
|
@ -81,17 +81,17 @@ put(Recipe_ordinal, "maybe-convert", MAYBE_CONVERT);
|
|||
case MAYBE_CONVERT: {
|
||||
const recipe& caller = get(Recipe, r);
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(caller.name) << "'maybe-convert' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "'maybe-convert' expects exactly 2 ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0);
|
||||
canonize_type(base);
|
||||
if (!base.type || !base.type->value || get(Type, base.type->value).kind != EXCLUSIVE_CONTAINER) {
|
||||
raise_error << maybe(caller.name) << "first ingredient of 'maybe-convert' should be an exclusive-container, but got " << base.original_string << '\n' << end();
|
||||
raise << maybe(caller.name) << "first ingredient of 'maybe-convert' should be an exclusive-container, but got " << base.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_literal(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(caller.name) << "second ingredient of 'maybe-convert' should have type 'variant', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(caller.name) << "second ingredient of 'maybe-convert' should have type 'variant', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (inst.products.empty()) break;
|
||||
|
@ -100,13 +100,13 @@ case MAYBE_CONVERT: {
|
|||
reagent& offset = inst.ingredients.at(1);
|
||||
populate_value(offset);
|
||||
if (offset.value >= SIZE(get(Type, base.type->value).elements)) {
|
||||
raise_error << maybe(caller.name) << "invalid tag " << offset.value << " in '" << to_string(inst) << '\n' << end();
|
||||
raise << maybe(caller.name) << "invalid tag " << offset.value << " in '" << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
reagent variant = variant_type(base, offset.value);
|
||||
variant.type = new type_tree("address", get(Type_ordinal, "address"), variant.type);
|
||||
if (!types_coercible(product, variant)) {
|
||||
raise_error << maybe(caller.name) << "'maybe-convert " << base.original_string << ", " << inst.ingredients.at(1).original_string << "' should write to " << to_string(variant.type) << " but " << product.name << " has type " << to_string(product.type) << '\n' << end();
|
||||
raise << maybe(caller.name) << "'maybe-convert " << base.original_string << ", " << inst.ingredients.at(1).original_string << "' should write to " << to_string(variant.type) << " but " << product.name << " has type " << to_string(product.type) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -117,7 +117,7 @@ case MAYBE_CONVERT: {
|
|||
canonize(base);
|
||||
long long int base_address = base.value;
|
||||
if (base_address == 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_string(current_instruction()) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
long long int tag = current_instruction().ingredients.at(1).value;
|
||||
|
@ -242,13 +242,13 @@ case EXCLUSIVE_CONTAINER: {
|
|||
assert(state.data.top().container_element_index == 0);
|
||||
trace(9999, "transform") << "checking exclusive container " << to_string(container) << " vs ingredient " << ingredient_index << end();
|
||||
if (!is_literal(ingredients.at(ingredient_index))) {
|
||||
raise_error << maybe(caller.name) << "ingredient " << ingredient_index << " of 'merge' should be a literal, for the tag of exclusive-container " << container_info.name << '\n' << end();
|
||||
raise << maybe(caller.name) << "ingredient " << ingredient_index << " of 'merge' should be a literal, for the tag of exclusive-container " << container_info.name << '\n' << end();
|
||||
return;
|
||||
}
|
||||
reagent ingredient = ingredients.at(ingredient_index); // unnecessary copy just to keep this function from modifying caller
|
||||
populate_value(ingredient);
|
||||
if (ingredient.value >= SIZE(container_info.elements)) {
|
||||
raise_error << maybe(caller.name) << "invalid tag at " << ingredient_index << " for " << container_info.name << " in '" << to_string(inst) << '\n' << end();
|
||||
raise << maybe(caller.name) << "invalid tag at " << ingredient_index << " for " << container_info.name << " in '" << to_string(inst) << '\n' << end();
|
||||
return;
|
||||
}
|
||||
reagent variant = variant_type(container, ingredient.value);
|
||||
|
|
|
@ -97,7 +97,7 @@ inline const instruction& to_instruction(const call& call) {
|
|||
:(after "Defined Recipe Checks")
|
||||
// not a primitive; check that it's present in the book of recipes
|
||||
if (!contains_key(Recipe, inst.operation)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "undefined operation in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "undefined operation in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
:(replace{} "default:" following "End Primitive Recipe Implementations")
|
||||
|
|
|
@ -42,7 +42,7 @@ put(Recipe_ordinal, "next-ingredient", NEXT_INGREDIENT);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case NEXT_INGREDIENT: {
|
||||
if (!inst.ingredients.empty()) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'next-ingredient' didn't expect any ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'next-ingredient' didn't expect any ingredients in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -57,11 +57,11 @@ case NEXT_INGREDIENT: {
|
|||
// no ingredient types since the call might be implicit; assume ingredients are always strings
|
||||
// todo: how to test this?
|
||||
if (!is_mu_string(product))
|
||||
raise_error << "main: wrong type for ingredient " << product.original_string << '\n' << end();
|
||||
raise << "main: wrong type for ingredient " << product.original_string << '\n' << end();
|
||||
}
|
||||
else if (!types_coercible(product,
|
||||
current_call().ingredients.at(current_call().next_ingredient_to_process))) {
|
||||
raise_error << maybe(current_recipe_name()) << "wrong type for ingredient " << product.original_string << '\n' << end();
|
||||
raise << maybe(current_recipe_name()) << "wrong type for ingredient " << product.original_string << '\n' << end();
|
||||
// End next-ingredient Type Mismatch Error
|
||||
}
|
||||
products.push_back(
|
||||
|
@ -72,7 +72,7 @@ case NEXT_INGREDIENT: {
|
|||
}
|
||||
else {
|
||||
if (SIZE(current_instruction().products) < 2)
|
||||
raise_error << maybe(current_recipe_name()) << "no ingredient to save in " << current_instruction().products.at(0).original_string << '\n' << end();
|
||||
raise << maybe(current_recipe_name()) << "no ingredient to save in " << current_instruction().products.at(0).original_string << '\n' << end();
|
||||
if (current_instruction().products.empty()) break;
|
||||
products.resize(2);
|
||||
// pad the first product with sufficient zeros to match its type
|
||||
|
@ -141,11 +141,11 @@ put(Recipe_ordinal, "ingredient", INGREDIENT);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case INGREDIENT: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'ingredient' expects exactly one ingredient, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'ingredient' expects exactly one ingredient, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_literal(inst.ingredients.at(0)) && !is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'ingredient' expects a literal ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'ingredient' expects a literal ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -77,7 +77,7 @@ void check_types_of_reply_instructions(recipe_ordinal r) {
|
|||
if (reply_inst.operation != REPLY) continue;
|
||||
// check types with the caller
|
||||
if (SIZE(caller_instruction.products) > SIZE(reply_inst.ingredients)) {
|
||||
raise_error << maybe(caller.name) << "too few values replied from " << callee.name << '\n' << end();
|
||||
raise << maybe(caller.name) << "too few values replied from " << callee.name << '\n' << end();
|
||||
break;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(caller_instruction.products); ++i) {
|
||||
|
@ -86,8 +86,8 @@ void check_types_of_reply_instructions(recipe_ordinal r) {
|
|||
reagent rhs = caller_instruction.products.at(i);
|
||||
canonize_type(rhs);
|
||||
if (!types_coercible(rhs, lhs)) {
|
||||
raise_error << maybe(callee.name) << "reply ingredient " << lhs.original_string << " can't be saved in " << rhs.original_string << '\n' << end();
|
||||
raise_error << to_string(lhs.type) << " vs " << to_string(rhs.type) << '\n' << end();
|
||||
raise << maybe(callee.name) << "reply ingredient " << lhs.original_string << " can't be saved in " << rhs.original_string << '\n' << end();
|
||||
raise << to_string(lhs.type) << " vs " << to_string(rhs.type) << '\n' << end();
|
||||
goto finish_reply_check;
|
||||
}
|
||||
}
|
||||
|
@ -97,16 +97,16 @@ void check_types_of_reply_instructions(recipe_ordinal r) {
|
|||
if (has_property(reply_inst.ingredients.at(i), "same-as-ingredient")) {
|
||||
string_tree* tmp = property(reply_inst.ingredients.at(i), "same-as-ingredient");
|
||||
if (!tmp || tmp->right) {
|
||||
raise_error << maybe(caller.name) << "'same-as-ingredient' metadata should take exactly one value in " << to_string(reply_inst) << '\n' << end();
|
||||
raise << maybe(caller.name) << "'same-as-ingredient' metadata should take exactly one value in " << to_string(reply_inst) << '\n' << end();
|
||||
goto finish_reply_check;
|
||||
}
|
||||
long long int ingredient_index = to_integer(tmp->value);
|
||||
if (ingredient_index >= SIZE(caller_instruction.ingredients)) {
|
||||
raise_error << maybe(caller.name) << "too few ingredients in '" << to_string(caller_instruction) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "too few ingredients in '" << to_string(caller_instruction) << "'\n" << end();
|
||||
goto finish_reply_check;
|
||||
}
|
||||
if (!is_dummy(caller_instruction.products.at(i)) && !is_literal(caller_instruction.ingredients.at(ingredient_index)) && caller_instruction.products.at(i).name != caller_instruction.ingredients.at(ingredient_index).name) {
|
||||
raise_error << maybe(caller.name) << "'" << to_string(caller_instruction) << "' should write to " << caller_instruction.ingredients.at(ingredient_index).original_string << " rather than " << caller_instruction.products.at(i).original_string << '\n' << end();
|
||||
raise << maybe(caller.name) << "'" << to_string(caller_instruction) << "' should write to " << caller_instruction.ingredients.at(ingredient_index).original_string << " rather than " << caller_instruction.products.at(i).original_string << '\n' << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ if (curr.name == "reply-if") {
|
|||
curr.ingredients.swap(results);
|
||||
}
|
||||
else {
|
||||
raise_error << "'reply-if' never yields any products\n" << end();
|
||||
raise << "'reply-if' never yields any products\n" << end();
|
||||
}
|
||||
}
|
||||
// rewrite `reply-unless a, b, c, ...` to
|
||||
|
@ -239,6 +239,6 @@ if (curr.name == "reply-unless") {
|
|||
curr.ingredients.swap(results);
|
||||
}
|
||||
else {
|
||||
raise_error << "'reply-unless' never yields any products\n" << end();
|
||||
raise << "'reply-unless' never yields any products\n" << end();
|
||||
}
|
||||
}
|
||||
|
|
18
037new.cc
18
037new.cc
|
@ -81,21 +81,21 @@ put(Recipe_ordinal, "new", NEW);
|
|||
case NEW: {
|
||||
const recipe& caller = get(Recipe, r);
|
||||
if (inst.ingredients.empty() || SIZE(inst.ingredients) > 2) {
|
||||
raise_error << maybe(caller.name) << "'new' requires one or two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(caller.name) << "'new' requires one or two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
// End NEW Check Special-cases
|
||||
reagent type = inst.ingredients.at(0);
|
||||
if (!is_mu_type_literal(type)) {
|
||||
raise_error << maybe(caller.name) << "first ingredient of 'new' should be a type, but got " << type.original_string << '\n' << end();
|
||||
raise << maybe(caller.name) << "first ingredient of 'new' should be a type, but got " << type.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (inst.products.empty()) {
|
||||
raise_error << maybe(caller.name) << "result of 'new' should never be ignored\n" << end();
|
||||
raise << maybe(caller.name) << "result of 'new' should never be ignored\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!product_of_new_is_valid(inst)) {
|
||||
raise_error << maybe(caller.name) << "product of 'new' has incorrect type: " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(caller.name) << "product of 'new' has incorrect type: " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -187,14 +187,14 @@ case ALLOCATE: {
|
|||
//:: ensure we never call 'allocate' directly; its types are not checked
|
||||
:(before "End Primitive Recipe Checks")
|
||||
case ALLOCATE: {
|
||||
raise_error << "never call 'allocate' directly'; always use 'new'\n" << end();
|
||||
raise << "never call 'allocate' directly'; always use 'new'\n" << end();
|
||||
break;
|
||||
}
|
||||
|
||||
//:: ensure we never call 'new' without translating it (unless we add special-cases later)
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case NEW: {
|
||||
raise_error << "no implementation for 'new'; why wasn't it translated to 'allocate'? Please save a copy of your program and send it to Kartik.\n" << end();
|
||||
raise << "no implementation for 'new'; why wasn't it translated to 'allocate'? Please save a copy of your program and send it to Kartik.\n" << end();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -300,13 +300,13 @@ put(Recipe_ordinal, "abandon", ABANDON);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case ABANDON: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'abandon' requires one ingredient, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'abandon' requires one ingredient, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent types = inst.ingredients.at(0);
|
||||
canonize_type(types);
|
||||
if (!types.type || types.type->value != get(Type_ordinal, "address") || types.type->right->value != get(Type_ordinal, "shared")) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'abandon' should be an address:shared:___, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'abandon' should be an address:shared:___, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -353,7 +353,7 @@ if (get_or_insert(Free_list, size)) {
|
|||
put(Free_list, size, get_or_insert(Memory, result));
|
||||
for (long long int curr = result+1; curr < result+size; ++curr) {
|
||||
if (get_or_insert(Memory, curr) != 0) {
|
||||
raise_error << maybe(current_recipe_name()) << "memory in free list was not zeroed out: " << curr << '/' << result << "; somebody wrote to us after free!!!\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "memory in free list was not zeroed out: " << curr << '/' << result << "; somebody wrote to us after free!!!\n" << end();
|
||||
break; // always fatal
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ put(Recipe_ordinal, "to-location-array", TO_LOCATION_ARRAY);
|
|||
case TO_LOCATION_ARRAY: {
|
||||
const recipe& caller = get(Recipe, r);
|
||||
if (!is_shared_address_of_array_of_numbers(inst.products.at(0))) {
|
||||
raise_error << maybe(caller.name) << "product of 'to-location-array' has incorrect type: " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(caller.name) << "product of 'to-location-array' has incorrect type: " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -61,7 +61,7 @@ void transform_braces(const recipe_ordinal r) {
|
|||
}
|
||||
if (inst.label == "}") {
|
||||
if (open_braces.empty()) {
|
||||
raise_error << "missing '{' in " << get(Recipe, r).name << '\n' << end();
|
||||
raise << "missing '{' in " << get(Recipe, r).name << '\n' << end();
|
||||
return;
|
||||
}
|
||||
open_braces.pop();
|
||||
|
@ -80,7 +80,7 @@ void transform_braces(const recipe_ordinal r) {
|
|||
// check for errors
|
||||
if (inst.old_name.find("-if") != string::npos || inst.old_name.find("-unless") != string::npos) {
|
||||
if (inst.ingredients.empty()) {
|
||||
raise_error << inst.old_name << " expects 1 or 2 ingredients, but got none\n" << end();
|
||||
raise << inst.old_name << " expects 1 or 2 ingredients, but got none\n" << end();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ void transform_braces(const recipe_ordinal r) {
|
|||
target.type = new type_tree("offset", get(Type_ordinal, "offset"));
|
||||
target.set_value(0);
|
||||
if (open_braces.empty())
|
||||
raise_error << inst.old_name << " needs a '{' before\n" << end();
|
||||
raise << inst.old_name << " needs a '{' before\n" << end();
|
||||
else if (inst.old_name.find("loop") != string::npos)
|
||||
target.set_value(open_braces.top()-index);
|
||||
else // break instruction
|
||||
|
@ -140,7 +140,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_error << maybe(get(Recipe, r).name) << "unbalanced '{'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "unbalanced '{'\n" << end();
|
||||
return SIZE(get(Recipe, r).steps); // exit current routine
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ void transform_labels(const recipe_ordinal r) {
|
|||
put(offset, inst.label, i);
|
||||
}
|
||||
else {
|
||||
raise_error << maybe(get(Recipe, r).name) << "duplicate label '" << inst.label << "'" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "duplicate label '" << inst.label << "'" << end();
|
||||
// have all jumps skip some random but noticeable and deterministic amount of code
|
||||
put(offset, inst.label, 9999);
|
||||
}
|
||||
|
@ -60,19 +60,19 @@ void transform_labels(const recipe_ordinal r) {
|
|||
:(code)
|
||||
void replace_offset(reagent& x, /*const*/ map<string, long long int>& offset, const long long int current_offset, const recipe_ordinal r) {
|
||||
if (!is_literal(x)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "jump target must be offset or label but is " << x.original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "jump target must be offset or label but is " << x.original_string << '\n' << end();
|
||||
x.set_value(0); // no jump by default
|
||||
return;
|
||||
}
|
||||
if (x.initialized) return;
|
||||
if (is_integer(x.name)) return; // non-labels will be handled like other number operands
|
||||
if (!is_jump_target(x.name)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "can't jump to label " << x.name << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "can't jump to label " << x.name << '\n' << end();
|
||||
x.set_value(0); // no jump by default
|
||||
return;
|
||||
}
|
||||
if (!contains_key(offset, x.name)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "can't find label " << x.name << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "can't find label " << x.name << '\n' << end();
|
||||
x.set_value(0); // no jump by default
|
||||
return;
|
||||
}
|
||||
|
|
16
042name.cc
16
042name.cc
|
@ -49,7 +49,7 @@ void transform_names(const recipe_ordinal r) {
|
|||
if (is_named_location(inst.ingredients.at(in))) names_used = true;
|
||||
if (is_integer(inst.ingredients.at(in).name)) continue;
|
||||
if (!already_transformed(inst.ingredients.at(in), names)) {
|
||||
raise_error << maybe(caller.name) << "use before set: " << inst.ingredients.at(in).name << '\n' << end();
|
||||
raise << maybe(caller.name) << "use before set: " << inst.ingredients.at(in).name << '\n' << end();
|
||||
}
|
||||
inst.ingredients.at(in).set_value(lookup_name(inst.ingredients.at(in), r));
|
||||
}
|
||||
|
@ -67,13 +67,13 @@ void transform_names(const recipe_ordinal r) {
|
|||
}
|
||||
}
|
||||
if (names_used && numeric_locations_used)
|
||||
raise_error << maybe(caller.name) << "mixing variable names and numeric addresses\n" << end();
|
||||
raise << maybe(caller.name) << "mixing variable names and numeric addresses\n" << end();
|
||||
}
|
||||
|
||||
bool is_disqualified(/*mutable*/ reagent& x, const instruction& inst, const string& recipe_name) {
|
||||
if (!x.type) {
|
||||
// End Null-type is_disqualified Exceptions
|
||||
raise_error << maybe(recipe_name) << "missing type for " << x.original_string << " in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(recipe_name) << "missing type for " << x.original_string << " in '" << to_string(inst) << "'\n" << end();
|
||||
return true;
|
||||
}
|
||||
if (is_raw(x)) return true;
|
||||
|
@ -98,7 +98,7 @@ type_ordinal skip_addresses(type_tree* type, const string& recipe_name) {
|
|||
if (type->value != address && type->value != shared)
|
||||
return type->value;
|
||||
}
|
||||
raise_error << maybe(recipe_name) << "expected a container" << '\n' << end();
|
||||
raise << maybe(recipe_name) << "expected a container" << '\n' << end();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ int find_element_name(const type_ordinal t, const string& name, const string& re
|
|||
const type_info& container = get(Type, t);
|
||||
for (long long int i = 0; i < SIZE(container.elements); ++i)
|
||||
if (container.elements.at(i).name == name) return i;
|
||||
raise_error << maybe(recipe_name) << "unknown element " << name << " in container " << get(Type, t).name << '\n' << end();
|
||||
raise << maybe(recipe_name) << "unknown element " << name << " in container " << get(Type, t).name << '\n' << end();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -194,11 +194,11 @@ recipe main [
|
|||
// replace element names of containers with offsets
|
||||
if (inst.name == "get" || inst.name == "get-address") {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "exactly 2 ingredients expected in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "exactly 2 ingredients expected in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_literal(inst.ingredients.at(1)))
|
||||
raise_error << maybe(get(Recipe, r).name) << "expected ingredient 1 of " << (inst.name == "get" ? "'get'" : "'get-address'") << " to have type 'offset'; got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "expected ingredient 1 of " << (inst.name == "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).type, get(Recipe, r).name);
|
||||
|
@ -236,7 +236,7 @@ recipe main [
|
|||
// convert variant names of exclusive containers
|
||||
if (inst.name == "maybe-convert") {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "exactly 2 ingredients expected in '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "exactly 2 ingredients expected in '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
assert(is_literal(inst.ingredients.at(1)));
|
||||
|
|
16
043space.cc
16
043space.cc
|
@ -56,7 +56,7 @@ void absolutize(reagent& x) {
|
|||
if (is_raw(x) || is_dummy(x)) return;
|
||||
if (x.name == "default-space") return;
|
||||
if (!x.initialized) {
|
||||
raise_error << to_string(current_instruction()) << ": reagent not initialized: " << x.original_string << '\n' << end();
|
||||
raise << to_string(current_instruction()) << ": reagent not initialized: " << x.original_string << '\n' << end();
|
||||
}
|
||||
x.set_value(address(x.value, space_base(x)));
|
||||
x.properties.push_back(pair<string, string_tree*>("raw", NULL));
|
||||
|
@ -73,7 +73,7 @@ long long int address(long long int offset, long long int base) {
|
|||
long long int size = get_or_insert(Memory, base);
|
||||
if (offset >= size) {
|
||||
// todo: test
|
||||
raise_error << "location " << offset << " is out of bounds " << size << " at " << base << '\n' << end();
|
||||
raise << "location " << offset << " is out of bounds " << size << " at " << base << '\n' << end();
|
||||
return 0;
|
||||
}
|
||||
return base + /*skip length*/1 + offset;
|
||||
|
@ -93,7 +93,7 @@ long long int address(long long int offset, long long int base) {
|
|||
|| !x.type->right->right->right
|
||||
|| x.type->right->right->right->value != get(Type_ordinal, "location")
|
||||
|| x.type->right->right->right->right) {
|
||||
raise_error << maybe(current_recipe_name()) << "'default-space' should be of type address:shared:array:location, but tried to write " << to_string(data) << '\n' << end();
|
||||
raise << maybe(current_recipe_name()) << "'default-space' should be of type address:shared:array:location, but tried to write " << to_string(data) << '\n' << end();
|
||||
}
|
||||
current_call().default_space = data.at(0);
|
||||
return;
|
||||
|
@ -184,12 +184,12 @@ if (curr.name == "new-default-space") {
|
|||
vector<double> result;
|
||||
result.push_back(Name[get(Recipe_ordinal, current_recipe_name())][""]);
|
||||
if (result.back() == 0)
|
||||
raise_error << "no space allocated for default-space in recipe " << current_recipe_name() << "; are you using names?\n" << end();
|
||||
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") {
|
||||
raise_error << maybe(current_recipe_name()) << "can't write to special name 'number-of-locals'\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "can't write to special name 'number-of-locals'\n" << end();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -235,12 +235,12 @@ void try_reclaim_locals() {
|
|||
|
||||
void rewrite_default_space_instruction(instruction& curr) {
|
||||
if (!curr.ingredients.empty())
|
||||
raise_error << to_string(curr) << " can't take any ingredients\n" << end();
|
||||
raise << to_string(curr) << " can't take any ingredients\n" << end();
|
||||
curr.name = "new";
|
||||
curr.ingredients.push_back(reagent("location:type"));
|
||||
curr.ingredients.push_back(reagent("number-of-locals:literal"));
|
||||
if (!curr.products.empty())
|
||||
raise_error << "new-default-space can't take any results\n" << end();
|
||||
raise << "new-default-space can't take any results\n" << end();
|
||||
curr.products.push_back(reagent("default-space:address:shared:array:location"));
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ void check_default_space(const recipe_ordinal r) {
|
|||
if (caller.steps.empty()) return;
|
||||
if (caller.steps.at(0).products.empty()
|
||||
|| caller.steps.at(0).products.at(0).name != "default-space") {
|
||||
raise_error << maybe(caller.name) << " does not seem to start with default-space or local-scope\n" << end();
|
||||
raise << maybe(caller.name) << " does not seem to start with default-space or local-scope\n" << end();
|
||||
}
|
||||
}
|
||||
:(after "Load .mu Core")
|
||||
|
|
|
@ -49,7 +49,7 @@ long long int space_index(const reagent& x) {
|
|||
for (long long int i = 0; i < SIZE(x.properties); ++i) {
|
||||
if (x.properties.at(i).first == "space") {
|
||||
if (!x.properties.at(i).second || x.properties.at(i).second->right)
|
||||
raise_error << maybe(current_recipe_name()) << "/space metadata should take exactly one value in " << x.original_string << '\n' << end();
|
||||
raise << maybe(current_recipe_name()) << "/space metadata should take exactly one value in " << x.original_string << '\n' << end();
|
||||
return to_integer(x.properties.at(i).second->value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,28 +58,28 @@ void collect_surrounding_spaces(const recipe_ordinal r) {
|
|||
|| !type->right->right->right
|
||||
|| type->right->right->right->value != get(Type_ordinal, "location")
|
||||
|| type->right->right->right->right) {
|
||||
raise_error << "slot 0 should always have type address:shared:array:location, but is " << to_string(inst.products.at(j)) << '\n' << end();
|
||||
raise << "slot 0 should always have type address:shared:array:location, but is " << to_string(inst.products.at(j)) << '\n' << end();
|
||||
continue;
|
||||
}
|
||||
string_tree* s = property(inst.products.at(j), "names");
|
||||
if (!s) {
|
||||
raise_error << "slot 0 requires a /names property in recipe " << get(Recipe, r).name << end();
|
||||
raise << "slot 0 requires a /names property in recipe " << get(Recipe, r).name << end();
|
||||
continue;
|
||||
}
|
||||
if (s->right) raise_error << "slot 0 should have a single value in /names, but got " << to_string(inst.products.at(j)) << '\n' << end();
|
||||
if (s->right) raise << "slot 0 should have a single value in /names, but got " << to_string(inst.products.at(j)) << '\n' << end();
|
||||
const string& surrounding_recipe_name = s->value;
|
||||
if (surrounding_recipe_name.empty()) {
|
||||
raise_error << "slot 0 doesn't initialize its /names property in recipe " << get(Recipe, r).name << end();
|
||||
raise << "slot 0 doesn't initialize its /names property in recipe " << get(Recipe, r).name << end();
|
||||
continue;
|
||||
}
|
||||
if (contains_key(Surrounding_space, r)
|
||||
&& get(Surrounding_space, r) != get(Recipe_ordinal, surrounding_recipe_name)) {
|
||||
raise_error << "recipe " << get(Recipe, r).name << " can have only one 'surrounding' recipe but has " << get(Recipe, get(Surrounding_space, r)).name << " and " << surrounding_recipe_name << '\n' << end();
|
||||
raise << "recipe " << get(Recipe, r).name << " can have only one 'surrounding' recipe but has " << get(Recipe, get(Surrounding_space, r)).name << " and " << surrounding_recipe_name << '\n' << end();
|
||||
continue;
|
||||
}
|
||||
trace(9993, "name") << "lexically surrounding space for recipe " << get(Recipe, r).name << " comes from " << surrounding_recipe_name << end();
|
||||
if (!contains_key(Recipe_ordinal, surrounding_recipe_name)) {
|
||||
raise_error << "can't find recipe providing surrounding space for " << get(Recipe, r).name << ": " << surrounding_recipe_name << '\n' << end();
|
||||
raise << "can't find recipe providing surrounding space for " << get(Recipe, r).name << ": " << surrounding_recipe_name << '\n' << end();
|
||||
continue;
|
||||
}
|
||||
put(Surrounding_space, r, get(Recipe_ordinal, surrounding_recipe_name));
|
||||
|
@ -93,11 +93,11 @@ void collect_surrounding_spaces(const recipe_ordinal r) {
|
|||
:(replace{} "long long int lookup_name(const reagent& r, const recipe_ordinal default_recipe)")
|
||||
long long int lookup_name(const reagent& x, const recipe_ordinal default_recipe) {
|
||||
if (!has_property(x, "space")) {
|
||||
if (Name[default_recipe].empty()) raise_error << "name not found: " << x.name << '\n' << end();
|
||||
if (Name[default_recipe].empty()) raise << "name not found: " << x.name << '\n' << end();
|
||||
return Name[default_recipe][x.name];
|
||||
}
|
||||
string_tree* p = property(x, "space");
|
||||
if (!p || p->right) raise_error << "/space property should have exactly one (non-negative integer) value\n" << end();
|
||||
if (!p || p->right) raise << "/space property should have exactly one (non-negative integer) value\n" << end();
|
||||
long long int n = to_integer(p->value);
|
||||
assert(n >= 0);
|
||||
recipe_ordinal surrounding_recipe = lookup_surrounding_recipe(default_recipe, n);
|
||||
|
@ -111,11 +111,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 (contains_key(done, r)) {
|
||||
raise_error << "can't compute address of " << to_string(x) << " because " << end();
|
||||
raise << "can't compute address of " << to_string(x) << " because " << end();
|
||||
for (long long int i = 1; i < SIZE(path); ++i) {
|
||||
raise_error << path.at(i-1) << " requires computing names of " << path.at(i) << '\n' << end();
|
||||
raise << path.at(i-1) << " requires computing names of " << path.at(i) << '\n' << end();
|
||||
}
|
||||
raise_error << path.at(SIZE(path)-1) << " requires computing names of " << r << "..ad infinitum\n" << end();
|
||||
raise << path.at(SIZE(path)-1) << " requires computing names of " << r << "..ad infinitum\n" << end();
|
||||
return 0;
|
||||
}
|
||||
done.insert(r);
|
||||
|
@ -128,7 +128,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 (!contains_key(Surrounding_space, r)) {
|
||||
raise_error << "don't know surrounding recipe of " << get(Recipe, r).name << '\n' << end();
|
||||
raise << "don't know surrounding recipe of " << get(Recipe, r).name << '\n' << end();
|
||||
return 0;
|
||||
}
|
||||
assert(contains_key(Surrounding_space, r));
|
||||
|
@ -141,7 +141,7 @@ bool already_transformed(const reagent& r, const map<string, long long int>& nam
|
|||
if (has_property(r, "space")) {
|
||||
string_tree* p = property(r, "space");
|
||||
if (!p || p->right) {
|
||||
raise_error << "/space property should have exactly one (non-negative integer) value in " << r.original_string << '\n' << end();
|
||||
raise << "/space property should have exactly one (non-negative integer) value in " << r.original_string << '\n' << end();
|
||||
return false;
|
||||
}
|
||||
if (p->value != "0") return true;
|
||||
|
|
|
@ -46,10 +46,10 @@ global_space = 0;
|
|||
|| !x.type->right->right->right
|
||||
|| x.type->right->right->right->value != get(Type_ordinal, "location")
|
||||
|| x.type->right->right->right->right) {
|
||||
raise_error << maybe(current_recipe_name()) << "'global-space' should be of type address:shared:array:location, but tried to write " << to_string(data) << '\n' << end();
|
||||
raise << maybe(current_recipe_name()) << "'global-space' should be of type address:shared:array:location, but tried to write " << to_string(data) << '\n' << end();
|
||||
}
|
||||
if (Current_routine->global_space)
|
||||
raise_error << "routine already has a global-space; you can't over-write your globals" << end();
|
||||
raise << "routine already has a global-space; you can't over-write your globals" << end();
|
||||
Current_routine->global_space = data.at(0);
|
||||
return;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ global_space = 0;
|
|||
:(after "long long int space_base(const reagent& x)")
|
||||
if (is_global(x)) {
|
||||
if (!Current_routine->global_space)
|
||||
raise_error << "routine has no global space\n" << end();
|
||||
raise << "routine has no global space\n" << end();
|
||||
return Current_routine->global_space + /*skip refcount*/1;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,16 +50,16 @@ void check_type(map<string, type_tree*>& type, const reagent& x, const recipe_or
|
|||
put(type, x.name, x.type);
|
||||
}
|
||||
if (!types_strictly_match(get(type, x.name), x.type)) {
|
||||
raise_error << maybe(get(Recipe, r).name) << x.name << " used with multiple types\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << x.name << " used with multiple types\n" << end();
|
||||
return;
|
||||
}
|
||||
if (get(type, x.name)->name == "array") {
|
||||
if (!get(type, x.name)->right) {
|
||||
raise_error << maybe(get(Recipe, r).name) << x.name << " can't be just an array. What is it an array of?\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << x.name << " can't be just an array. What is it an array of?\n" << end();
|
||||
return;
|
||||
}
|
||||
if (!get(type, x.name)->right->right) {
|
||||
raise_error << get(Recipe, r).name << " can't determine the size of array variable " << x.name << ". Either allocate it separately and make the type of " << x.name << " address:shared:..., or specify the length of the array in the type of " << x.name << ".\n" << end();
|
||||
raise << get(Recipe, r).name << " can't determine the size of array variable " << x.name << ". Either allocate it separately and make the type of " << x.name << " address:shared:..., or specify the length of the array in the type of " << x.name << ".\n" << end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ scenario parse_scenario(istream& in) {
|
|||
scenario result;
|
||||
result.name = next_word(in);
|
||||
if (contains_key(Scenario_names, result.name))
|
||||
raise_error << "duplicate scenario name: " << result.name << '\n' << end();
|
||||
raise << "duplicate scenario name: " << result.name << '\n' << end();
|
||||
Scenario_names.insert(result.name);
|
||||
skip_whitespace_and_comments(in);
|
||||
assert(in.peek() == '[');
|
||||
|
@ -297,10 +297,10 @@ void check_memory(const string& s) {
|
|||
if (!is_integer(rhs) && !is_noninteger(rhs)) {
|
||||
if (Current_scenario && !Scenario_testing_scenario)
|
||||
// genuine test in a mu file
|
||||
raise_error << "\nF - " << Current_scenario->name << ": location " << address << " can't contain non-number " << rhs << '\n' << end();
|
||||
raise << "\nF - " << Current_scenario->name << ": location " << address << " can't contain non-number " << rhs << '\n' << end();
|
||||
else
|
||||
// just testing scenario support
|
||||
raise_error << "location " << address << " can't contain non-number " << rhs << '\n' << end();
|
||||
raise << "location " << address << " can't contain non-number " << rhs << '\n' << end();
|
||||
if (!Scenario_testing_scenario) {
|
||||
Passed = false;
|
||||
++Num_failures;
|
||||
|
@ -309,16 +309,16 @@ void check_memory(const string& s) {
|
|||
}
|
||||
double value = to_double(rhs);
|
||||
if (contains_key(locations_checked, address))
|
||||
raise_error << "duplicate expectation for location " << address << '\n' << end();
|
||||
raise << "duplicate expectation for location " << address << '\n' << end();
|
||||
trace(9999, "run") << "checking location " << address << end();
|
||||
if (get_or_insert(Memory, address) != value) {
|
||||
if (Current_scenario && !Scenario_testing_scenario) {
|
||||
// genuine test in a mu file
|
||||
raise_error << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << no_scientific(value) << " but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end();
|
||||
raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << no_scientific(value) << " but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end();
|
||||
}
|
||||
else {
|
||||
// just testing scenario support
|
||||
raise_error << "expected location " << address << " to contain " << no_scientific(value) << " but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end();
|
||||
raise << "expected location " << address << " to contain " << no_scientific(value) << " but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end();
|
||||
}
|
||||
if (!Scenario_testing_scenario) {
|
||||
Passed = false;
|
||||
|
@ -349,16 +349,16 @@ void check_type(const string& lhs, istream& in) {
|
|||
return;
|
||||
}
|
||||
// End Scenario Type Cases
|
||||
raise_error << "don't know how to check memory for " << lhs << '\n' << end();
|
||||
raise << "don't know how to check memory for " << lhs << '\n' << end();
|
||||
}
|
||||
|
||||
void check_string(long long int address, const string& literal) {
|
||||
trace(9999, "run") << "checking string length at " << address << end();
|
||||
if (get_or_insert(Memory, address) != SIZE(literal)) {
|
||||
if (Current_scenario && !Scenario_testing_scenario)
|
||||
raise_error << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << no_scientific(get_or_insert(Memory, address)) << " (" << read_mu_string(address) << ")\n" << end();
|
||||
raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << no_scientific(get_or_insert(Memory, address)) << " (" << read_mu_string(address) << ")\n" << end();
|
||||
else
|
||||
raise_error << "expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end();
|
||||
raise << "expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end();
|
||||
if (!Scenario_testing_scenario) {
|
||||
Passed = false;
|
||||
++Num_failures;
|
||||
|
@ -371,11 +371,11 @@ void check_string(long long int address, const string& literal) {
|
|||
if (get_or_insert(Memory, address+i) != literal.at(i)) {
|
||||
if (Current_scenario && !Scenario_testing_scenario) {
|
||||
// genuine test in a mu file
|
||||
raise_error << "\nF - " << Current_scenario->name << ": expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << no_scientific(get_or_insert(Memory, address+i)) << " ('" << static_cast<char>(get_or_insert(Memory, address+i)) << "')\n" << end();
|
||||
raise << "\nF - " << Current_scenario->name << ": expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << no_scientific(get_or_insert(Memory, address+i)) << " ('" << static_cast<char>(get_or_insert(Memory, address+i)) << "')\n" << end();
|
||||
}
|
||||
else {
|
||||
// just testing scenario support
|
||||
raise_error << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << no_scientific(get_or_insert(Memory, address+i)) << '\n' << end();
|
||||
raise << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << no_scientific(get_or_insert(Memory, address+i)) << '\n' << end();
|
||||
}
|
||||
if (!Scenario_testing_scenario) {
|
||||
Passed = false;
|
||||
|
@ -495,7 +495,7 @@ void check_trace(const string& expected) {
|
|||
if (curr_expected_line == SIZE(expected_lines)) return;
|
||||
}
|
||||
|
||||
raise_error << "missing [" << expected_lines.at(curr_expected_line).contents << "] "
|
||||
raise << "missing [" << expected_lines.at(curr_expected_line).contents << "] "
|
||||
<< "in trace with label " << expected_lines.at(curr_expected_line).label << '\n' << end();
|
||||
Passed = false;
|
||||
}
|
||||
|
@ -579,7 +579,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_error << "unexpected [" << lines.at(i).contents << "] in trace with label " << lines.at(i).label << '\n' << end();
|
||||
raise << "unexpected [" << lines.at(i).contents << "] in trace with label " << lines.at(i).label << '\n' << end();
|
||||
Passed = false;
|
||||
return false;
|
||||
}
|
||||
|
@ -626,15 +626,15 @@ put(Recipe_ordinal, "check-trace-count-for-label", CHECK_TRACE_COUNT_FOR_LABEL);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case CHECK_TRACE_COUNT_FOR_LABEL: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'check-trace-for-label' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'check-trace-for-label' requires exactly two ingredients, but got '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'check-trace-for-label' should be a number (count), but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'check-trace-for-label' should be a number (count), but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_literal_string(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'check-trace-for-label' should be a literal string (label), but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'check-trace-for-label' should be a literal string (label), but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -648,12 +648,12 @@ case CHECK_TRACE_COUNT_FOR_LABEL: {
|
|||
if (count != expected_count) {
|
||||
if (Current_scenario && !Scenario_testing_scenario) {
|
||||
// genuine test in a mu file
|
||||
raise_error << "\nF - " << Current_scenario->name << ": " << maybe(current_recipe_name()) << "expected " << expected_count << " lines in trace with label " << label << " in trace: " << end();
|
||||
raise << "\nF - " << Current_scenario->name << ": " << maybe(current_recipe_name()) << "expected " << expected_count << " lines in trace with label " << label << " in trace: " << end();
|
||||
DUMP(label);
|
||||
}
|
||||
else {
|
||||
// just testing scenario support
|
||||
raise_error << maybe(current_recipe_name()) << "expected " << expected_count << " lines in trace with label " << label << " in trace\n" << end();
|
||||
raise << maybe(current_recipe_name()) << "expected " << expected_count << " lines in trace with label " << label << " in trace\n" << end();
|
||||
}
|
||||
if (!Scenario_testing_scenario) {
|
||||
Passed = false;
|
||||
|
|
|
@ -40,7 +40,7 @@ else if (command == "before") {
|
|||
if (is_waypoint(label))
|
||||
Before_fragments[label].steps.insert(Before_fragments[label].steps.end(), tmp.steps.begin(), tmp.steps.end());
|
||||
else
|
||||
raise_error << "can't tangle before label " << label << '\n' << end();
|
||||
raise << "can't tangle before label " << label << '\n' << end();
|
||||
}
|
||||
else if (command == "after") {
|
||||
string label = next_word(in);
|
||||
|
@ -49,7 +49,7 @@ else if (command == "after") {
|
|||
if (is_waypoint(label))
|
||||
After_fragments[label].steps.insert(After_fragments[label].steps.begin(), tmp.steps.begin(), tmp.steps.end());
|
||||
else
|
||||
raise_error << "can't tangle after label " << label << '\n' << end();
|
||||
raise << "can't tangle after label " << label << '\n' << end();
|
||||
}
|
||||
|
||||
//: after all recipes are loaded, insert fragments at appropriate labels.
|
||||
|
@ -143,11 +143,11 @@ void check_insert_fragments(unused recipe_ordinal) {
|
|||
Transform_check_insert_fragments_Ran = true;
|
||||
for (map<string, recipe>::iterator p = Before_fragments.begin(); p != Before_fragments.end(); ++p) {
|
||||
if (!contains_key(Fragments_used, p->first))
|
||||
raise_error << "could not locate insert before " << p->first << '\n' << end();
|
||||
raise << "could not locate insert before " << p->first << '\n' << end();
|
||||
}
|
||||
for (map<string, recipe>::iterator p = After_fragments.begin(); p != After_fragments.end(); ++p) {
|
||||
if (!contains_key(Fragments_used, p->first))
|
||||
raise_error << "could not locate insert after " << p->first << '\n' << end();
|
||||
raise << "could not locate insert after " << p->first << '\n' << end();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,11 +97,11 @@ if (s.at(0) == '{') {
|
|||
in.get(); // skip '{'
|
||||
name = slurp_key(in);
|
||||
if (name.empty()) {
|
||||
raise_error << "invalid reagent " << s << " without a name\n" << end();
|
||||
raise << "invalid reagent " << s << " without a name\n" << end();
|
||||
return;
|
||||
}
|
||||
if (name == "}") {
|
||||
raise_error << "invalid empty reagent " << s << '\n' << end();
|
||||
raise << "invalid empty reagent " << s << '\n' << end();
|
||||
return;
|
||||
}
|
||||
{
|
||||
|
|
|
@ -218,17 +218,17 @@ void check_calls_against_header(const recipe_ordinal r) {
|
|||
for (long int i = 0; i < min(SIZE(inst.ingredients), SIZE(callee.ingredients)); ++i) {
|
||||
// ingredients coerced from call to callee
|
||||
if (!types_coercible(callee.ingredients.at(i), inst.ingredients.at(i)))
|
||||
raise_error << maybe(caller.name) << "ingredient " << i << " has the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "ingredient " << i << " has the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
if (is_unique_address(inst.ingredients.at(i)))
|
||||
raise_error << maybe(caller.name) << "avoid passing non-shared addresses into calls, like ingredient " << i << " at '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "avoid passing non-shared addresses into calls, like ingredient " << i << " at '" << to_string(inst) << "'\n" << end();
|
||||
}
|
||||
for (long int i = 0; i < min(SIZE(inst.products), SIZE(callee.products)); ++i) {
|
||||
if (is_dummy(inst.products.at(i))) continue;
|
||||
// products coerced from callee to call
|
||||
if (!types_coercible(inst.products.at(i), callee.products.at(i)))
|
||||
raise_error << maybe(caller.name) << "product " << i << " has the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "product " << i << " has the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
if (is_unique_address(inst.products.at(i)))
|
||||
raise_error << maybe(caller.name) << "avoid getting non-shared addresses out of calls, like product " << i << " at '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "avoid getting non-shared addresses out of calls, like product " << i << " at '" << to_string(inst) << "'\n" << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,12 +292,12 @@ void check_reply_instructions_against_header(const recipe_ordinal r) {
|
|||
const instruction& inst = caller_recipe.steps.at(i);
|
||||
if (inst.name != "reply") continue;
|
||||
if (SIZE(caller_recipe.products) != SIZE(inst.ingredients)) {
|
||||
raise_error << maybe(caller_recipe.name) << "replied with the wrong number of products at '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller_recipe.name) << "replied with the wrong number of products at '" << to_string(inst) << "'\n" << end();
|
||||
continue;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(caller_recipe.products); ++i) {
|
||||
if (!types_match(caller_recipe.products.at(i), inst.ingredients.at(i)))
|
||||
raise_error << maybe(caller_recipe.name) << "replied with the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller_recipe.name) << "replied with the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ void check_header_ingredients(const recipe_ordinal r) {
|
|||
trace(9991, "transform") << "--- checking reply instructions against header for " << caller_recipe.name << end();
|
||||
for (long long int i = 0; i < SIZE(caller_recipe.ingredients); ++i) {
|
||||
if (contains_key(caller_recipe.ingredient_index, caller_recipe.ingredients.at(i).name))
|
||||
raise_error << maybe(caller_recipe.name) << caller_recipe.ingredients.at(i).name << " can't repeat in the ingredients\n" << end();
|
||||
raise << maybe(caller_recipe.name) << caller_recipe.ingredients.at(i).name << " can't repeat in the ingredients\n" << end();
|
||||
put(caller_recipe.ingredient_index, caller_recipe.ingredients.at(i).name, i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,22 +187,22 @@ string best_variant(instruction& inst, const recipe& caller_recipe) {
|
|||
|
||||
// error messages
|
||||
if (get(Recipe_ordinal, inst.name) >= MAX_PRIMITIVE_RECIPES) { // we currently don't check types for primitive variants
|
||||
raise_error << maybe(caller_recipe.name) << "failed to find a matching call for '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller_recipe.name) << "failed to find a matching call for '" << to_string(inst) << "'\n" << end();
|
||||
for (list<call>::iterator p = /*skip*/++resolve_stack.begin(); p != resolve_stack.end(); ++p) {
|
||||
const recipe& specializer_recipe = get(Recipe, p->running_recipe);
|
||||
const instruction& specializer_inst = specializer_recipe.steps.at(p->running_step_index);
|
||||
if (specializer_recipe.name != "interactive")
|
||||
raise_error << " (from '" << to_string(specializer_inst) << "' in " << specializer_recipe.name << ")\n" << end();
|
||||
raise << " (from '" << to_string(specializer_inst) << "' in " << specializer_recipe.name << ")\n" << end();
|
||||
else
|
||||
raise_error << " (from '" << to_string(specializer_inst) << "')\n" << end();
|
||||
raise << " (from '" << to_string(specializer_inst) << "')\n" << end();
|
||||
// One special-case to help with the rewrite_stash transform. (cross-layer)
|
||||
if (specializer_inst.products.at(0).name.find("stash_") == 0) {
|
||||
instruction stash_inst;
|
||||
if (next_stash(*p, &stash_inst)) {
|
||||
if (specializer_recipe.name != "interactive")
|
||||
raise_error << " (part of '" << stash_inst.original_string << "' in " << specializer_recipe.name << ")\n" << end();
|
||||
raise << " (part of '" << stash_inst.original_string << "' in " << specializer_recipe.name << ")\n" << end();
|
||||
else
|
||||
raise_error << " (part of '" << stash_inst.original_string << "')\n" << end();
|
||||
raise << " (part of '" << stash_inst.original_string << "')\n" << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ void read_type_ingredients(string& name) {
|
|||
while (has_data(in)) {
|
||||
string curr = slurp_until(in, ':');
|
||||
if (info.type_ingredient_names.find(curr) != info.type_ingredient_names.end()) {
|
||||
raise_error << "can't repeat type ingredient names in a single container definition\n" << end();
|
||||
raise << "can't repeat type ingredient names in a single container definition\n" << end();
|
||||
return;
|
||||
}
|
||||
put(info.type_ingredient_names, curr, next_type_ordinal++);
|
||||
|
@ -168,7 +168,7 @@ const type_tree* type = get(Type, base_type).elements.at(i).type;
|
|||
if (type->value >= START_TYPE_INGREDIENTS) {
|
||||
long long int size = size_of_type_ingredient(type, base.type->right);
|
||||
if (!size)
|
||||
raise_error << "illegal field type '" << to_string(type) << "' seems to be missing a type ingredient or three\n" << end();
|
||||
raise << "illegal field type '" << to_string(type) << "' seems to be missing a type ingredient or three\n" << end();
|
||||
src += size;
|
||||
continue;
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ recipe main [
|
|||
:(before "End element_type Special-cases")
|
||||
if (contains_type_ingredient(element)) {
|
||||
if (!canonized_base.type->right)
|
||||
raise_error << "illegal type " << names_to_string(canonized_base.type) << " seems to be missing a type ingredient or three\n" << end();
|
||||
raise << "illegal type " << names_to_string(canonized_base.type) << " seems to be missing a type ingredient or three\n" << end();
|
||||
replace_type_ingredients(element.type, canonized_base.type->right, info);
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ void replace_type_ingredients(type_tree* element_type, const type_tree* callsite
|
|||
|
||||
const long long int type_ingredient_index = element_type->value-START_TYPE_INGREDIENTS;
|
||||
if (!has_nth_type(callsite_type, type_ingredient_index)) {
|
||||
raise_error << "illegal type " << names_to_string(callsite_type) << " seems to be missing a type ingredient or three\n" << end();
|
||||
raise << "illegal type " << names_to_string(callsite_type) << " seems to be missing a type ingredient or three\n" << end();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -462,7 +462,7 @@ const type_tree* type = get(Type, base_type).elements.at(i).type;
|
|||
if (type->value >= START_TYPE_INGREDIENTS) {
|
||||
long long int size = size_of_type_ingredient(type, base.type->right);
|
||||
if (!size)
|
||||
raise_error << "illegal type '" << to_string(type) << "' seems to be missing a type ingredient or three\n" << end();
|
||||
raise << "illegal type '" << to_string(type) << "' seems to be missing a type ingredient or three\n" << end();
|
||||
result += size;
|
||||
continue;
|
||||
}
|
||||
|
@ -550,6 +550,6 @@ recipe main [
|
|||
:(before "End variant_type Special-cases")
|
||||
if (contains_type_ingredient(element)) {
|
||||
if (!canonized_base.type->right)
|
||||
raise_error << "illegal type '" << to_string(canonized_base.type) << "' seems to be missing a type ingredient or three\n" << end();
|
||||
raise << "illegal type '" << to_string(canonized_base.type) << "' seems to be missing a type ingredient or three\n" << end();
|
||||
replace_type_ingredients(element.type, canonized_base.type->right, info);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ if (any_type_ingredient_in_header(/*recipe_ordinal*/p->first)) continue;
|
|||
if (Current_routine->calls.front().running_step_index == 0
|
||||
&& any_type_ingredient_in_header(Current_routine->calls.front().running_recipe)) {
|
||||
//? DUMP("");
|
||||
raise_error << "ran into unspecialized shape-shifting recipe " << current_recipe_name() << '\n' << end();
|
||||
raise << "ran into unspecialized shape-shifting recipe " << current_recipe_name() << '\n' << end();
|
||||
}
|
||||
|
||||
//: Make sure we don't match up literals with type ingredients without
|
||||
|
@ -92,7 +92,7 @@ skip_shape_shifting_variants:;
|
|||
:(before "End Instruction Operation Checks")
|
||||
if (contains_key(Recipe, inst.operation) && inst.operation >= MAX_PRIMITIVE_RECIPES
|
||||
&& any_type_ingredient_in_header(inst.operation)) {
|
||||
raise_error << maybe(caller.name) << "instruction " << inst.name << " has no valid specialization\n" << end();
|
||||
raise << maybe(caller.name) << "instruction " << inst.name << " has no valid specialization\n" << end();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -290,7 +290,7 @@ void save_or_deduce_type_name(reagent& x, map<string, type_tree*>& type, const r
|
|||
return;
|
||||
}
|
||||
if (!x.type) {
|
||||
raise_error << maybe(variant.original_name) << "unknown type for " << x.original_string << " (check the name for typos)\n" << end();
|
||||
raise << maybe(variant.original_name) << "unknown type for " << x.original_string << " (check the name for typos)\n" << end();
|
||||
return;
|
||||
}
|
||||
if (contains_key(type, x.name)) return;
|
||||
|
@ -330,7 +330,7 @@ void accumulate_type_ingredients(const type_tree* exemplar_type, const type_tree
|
|||
if (!exemplar_type) return;
|
||||
if (!refinement_type) {
|
||||
// todo: make this smarter; only flag an error if exemplar_type contains some *new* type ingredient
|
||||
raise_error << maybe(exemplar.name) << "missing type ingredient in " << exemplar_reagent.original_string << '\n' << end();
|
||||
raise << maybe(exemplar.name) << "missing type ingredient in " << exemplar_reagent.original_string << '\n' << end();
|
||||
return;
|
||||
}
|
||||
if (is_type_ingredient_name(exemplar_type->name)) {
|
||||
|
@ -341,7 +341,7 @@ void accumulate_type_ingredients(const type_tree* exemplar_type, const type_tree
|
|||
}
|
||||
else {
|
||||
if (!deeply_equal_type_names(get(mappings, exemplar_type->name), refinement_type)) {
|
||||
raise_error << maybe(caller_recipe.name) << "no call found for '" << to_string(call_instruction) << "'\n" << end();
|
||||
raise << maybe(caller_recipe.name) << "no call found for '" << to_string(call_instruction) << "'\n" << end();
|
||||
*error = true;
|
||||
return;
|
||||
}
|
||||
|
@ -388,7 +388,7 @@ void replace_type_ingredients(reagent& x, const map<string, const type_tree*>& m
|
|||
string before = to_string(x);
|
||||
trace(9993, "transform") << "replacing in ingredient " << x.original_string << end();
|
||||
if (!x.type) {
|
||||
raise_error << "specializing " << caller.original_name << ": missing type for " << x.original_string << '\n' << end();
|
||||
raise << "specializing " << caller.original_name << ": missing type for " << x.original_string << '\n' << end();
|
||||
return;
|
||||
}
|
||||
replace_type_ingredients(x.type, mappings);
|
||||
|
@ -497,12 +497,12 @@ void ensure_all_concrete_types(/*const*/ recipe& new_recipe, const recipe& exemp
|
|||
|
||||
void ensure_all_concrete_types(/*const*/ reagent& x, const recipe& exemplar) {
|
||||
if (!x.type || contains_type_ingredient_name(x.type)) {
|
||||
raise_error << maybe(exemplar.name) << "failed to map a type to " << x.original_string << '\n' << end();
|
||||
raise << maybe(exemplar.name) << "failed to map a type to " << x.original_string << '\n' << end();
|
||||
if (!x.type) x.type = new type_tree("", 0); // just to prevent crashes later
|
||||
return;
|
||||
}
|
||||
if (x.type->value == -1) {
|
||||
raise_error << maybe(exemplar.name) << "failed to map a type to the unknown " << x.original_string << '\n' << end();
|
||||
raise << maybe(exemplar.name) << "failed to map a type to the unknown " << x.original_string << '\n' << end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -238,9 +238,9 @@ void check_immutable_ingredient_in_instruction(const instruction& inst, const se
|
|||
// primitive recipe
|
||||
if (inst.operation == GET_ADDRESS || inst.operation == INDEX_ADDRESS) {
|
||||
if (current_ingredient_name == original_ingredient_name)
|
||||
raise_error << maybe(caller.name) << "cannot modify ingredient " << current_ingredient_name << " after instruction '" << to_string(inst) << "' because it's not also a product of " << caller.name << '\n' << end();
|
||||
raise << maybe(caller.name) << "cannot modify ingredient " << current_ingredient_name << " after instruction '" << to_string(inst) << "' because it's not also a product of " << caller.name << '\n' << end();
|
||||
else
|
||||
raise_error << maybe(caller.name) << "cannot modify " << current_ingredient_name << " after instruction '" << to_string(inst) << "' because that would modify ingredient " << original_ingredient_name << " which is not also a product of " << caller.name << '\n' << end();
|
||||
raise << maybe(caller.name) << "cannot modify " << current_ingredient_name << " after instruction '" << to_string(inst) << "' because that would modify ingredient " << original_ingredient_name << " which is not also a product of " << caller.name << '\n' << end();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -248,9 +248,9 @@ void check_immutable_ingredient_in_instruction(const instruction& inst, const se
|
|||
if (!is_mu_address(current_ingredient)) return; // making a copy is ok
|
||||
if (is_modified_in_recipe(inst.operation, current_ingredient_index, caller)) {
|
||||
if (current_ingredient_name == original_ingredient_name)
|
||||
raise_error << maybe(caller.name) << "cannot modify ingredient " << current_ingredient_name << " at instruction '" << to_string(inst) << "' because it's not also a product of " << caller.name << '\n' << end();
|
||||
raise << maybe(caller.name) << "cannot modify ingredient " << current_ingredient_name << " at instruction '" << to_string(inst) << "' because it's not also a product of " << caller.name << '\n' << end();
|
||||
else
|
||||
raise_error << maybe(caller.name) << "cannot modify " << current_ingredient_name << " after instruction '" << to_string(inst) << "' because that would modify ingredient " << original_ingredient_name << " which is not also a product of " << caller.name << '\n' << end();
|
||||
raise << maybe(caller.name) << "cannot modify " << current_ingredient_name << " after instruction '" << to_string(inst) << "' because that would modify ingredient " << original_ingredient_name << " which is not also a product of " << caller.name << '\n' << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ void check_immutable_ingredient_in_instruction(const instruction& inst, const se
|
|||
bool is_modified_in_recipe(recipe_ordinal r, long long int ingredient_index, const recipe& caller) {
|
||||
const recipe& callee = get(Recipe, r);
|
||||
if (!callee.has_header) {
|
||||
raise_error << maybe(caller.name) << "can't check mutability of ingredients in " << callee.name << " because it uses 'next-ingredient' directly, rather than a recipe header.\n" << end();
|
||||
raise << maybe(caller.name) << "can't check mutability of ingredients in " << callee.name << " because it uses 'next-ingredient' directly, rather than a recipe header.\n" << end();
|
||||
return true;
|
||||
}
|
||||
if (ingredient_index >= SIZE(callee.ingredients)) return false; // optional immutable ingredient
|
||||
|
@ -337,6 +337,6 @@ if (has_property(current_ingredient, "contained-in")) {
|
|||
if (tmp->left || tmp->right
|
||||
|| !is_present_in_ingredients(caller, tmp->value)
|
||||
|| !is_present_in_products(caller, tmp->value))
|
||||
raise_error << maybe(caller.name) << "contained-in can only point to another ingredient+product, but got " << to_string(property(current_ingredient, "contained-in")) << '\n' << end();
|
||||
raise << maybe(caller.name) << "contained-in can only point to another ingredient+product, but got " << to_string(property(current_ingredient, "contained-in")) << '\n' << end();
|
||||
continue;
|
||||
}
|
||||
|
|
10
061recipe.cc
10
061recipe.cc
|
@ -47,11 +47,11 @@ put(Recipe_ordinal, "call", CALL);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case CALL: {
|
||||
if (inst.ingredients.empty()) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'call' requires at least one ingredient (the recipe to call)\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'call' requires at least one ingredient (the recipe to call)\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_recipe(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'call' should be a recipe, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'call' should be a recipe, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -116,12 +116,12 @@ void check_indirect_calls_against_header(const recipe_ordinal r) {
|
|||
if (!callee_header.has_header) continue;
|
||||
for (long int i = /*skip callee*/1; i < min(SIZE(inst.ingredients), SIZE(callee_header.ingredients)+/*skip callee*/1); ++i) {
|
||||
if (!types_coercible(callee_header.ingredients.at(i-/*skip callee*/1), inst.ingredients.at(i)))
|
||||
raise_error << maybe(caller.name) << "ingredient " << i-/*skip callee*/1 << " has the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "ingredient " << i-/*skip callee*/1 << " has the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
}
|
||||
for (long int i = 0; i < min(SIZE(inst.products), SIZE(callee_header.products)); ++i) {
|
||||
if (is_dummy(inst.products.at(i))) continue;
|
||||
if (!types_coercible(callee_header.products.at(i), inst.products.at(i)))
|
||||
raise_error << maybe(caller.name) << "product " << i << " has the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(caller.name) << "product " << i << " has the wrong type at '" << to_string(inst) << "'\n" << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ recipe f x:boolean -> y:boolean [
|
|||
:(before "End Matching Types For Literal(to)")
|
||||
if (is_mu_recipe(to)) {
|
||||
if (!contains_key(Recipe, from.value)) {
|
||||
raise_error << "trying to store recipe " << from.name << " into " << to_string(to) << " but there's no such recipe\n" << end();
|
||||
raise << "trying to store recipe " << from.name << " into " << to_string(to) << " but there's no such recipe\n" << end();
|
||||
return false;
|
||||
}
|
||||
const recipe& rrhs = get(Recipe, from.value);
|
||||
|
|
|
@ -153,11 +153,11 @@ put(Recipe_ordinal, "start-running", START_RUNNING);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case START_RUNNING: {
|
||||
if (inst.ingredients.empty()) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'start-running' requires at least one ingredient: the recipe to start running\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'start-running' requires at least one ingredient: the recipe to start running\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_recipe(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'start-running' should be a recipe, but got " << to_string(inst.ingredients.at(0)) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'start-running' should be a recipe, but got " << to_string(inst.ingredients.at(0)) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -343,11 +343,11 @@ put(Recipe_ordinal, "routine-state", ROUTINE_STATE);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case ROUTINE_STATE: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'routine-state' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'routine-state' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'routine-state' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'routine-state' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -376,11 +376,11 @@ put(Recipe_ordinal, "restart", RESTART);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case RESTART: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'restart' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'restart' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'restart' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'restart' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -404,11 +404,11 @@ put(Recipe_ordinal, "stop", STOP);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case STOP: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'stop' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'stop' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'stop' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'stop' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -486,15 +486,15 @@ put(Recipe_ordinal, "limit-time", LIMIT_TIME);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case LIMIT_TIME: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'limit-time' requires exactly two ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'limit-time' requires exactly two ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'limit-time' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'limit-time' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'limit-time' should be a number (of instructions to run for), but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'limit-time' should be a number (of instructions to run for), but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -96,11 +96,11 @@ put(Recipe_ordinal, "wait-for-routine", WAIT_FOR_ROUTINE);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case WAIT_FOR_ROUTINE: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'wait-for-routine' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'wait-for-routine' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'wait-for-routine' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'wait-for-routine' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -108,7 +108,7 @@ case WAIT_FOR_ROUTINE: {
|
|||
:(before "End Primitive Recipe Implementations")
|
||||
case WAIT_FOR_ROUTINE: {
|
||||
if (ingredients.at(0).at(0) == Current_routine->id) {
|
||||
raise_error << maybe(current_recipe_name()) << "routine can't wait for itself! " << to_string(current_instruction()) << '\n' << end();
|
||||
raise << maybe(current_recipe_name()) << "routine can't wait for itself! " << to_string(current_instruction()) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
Current_routine->state = WAITING;
|
||||
|
|
|
@ -36,11 +36,11 @@ put(Recipe_ordinal, "round", ROUND);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case ROUND: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'round' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'round' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'round' should be a number, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'round' should be a number, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -15,7 +15,7 @@ put(Recipe_ordinal, "hash", HASH);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case HASH: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'hash' takes exactly one ingredient rather than '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'hash' takes exactly one ingredient rather than '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -121,7 +121,7 @@ size_t hash_mu_exclusive_container(size_t h, const reagent& r) {
|
|||
reagent variant = variant_type(r, tag);
|
||||
// todo: move this error to container definition time
|
||||
if (has_property(variant, "ignore-for-hash"))
|
||||
raise_error << get(Type, r.type->value).name << ": /ignore-for-hash won't work in exclusive containers\n" << end();
|
||||
raise << get(Type, r.type->value).name << ": /ignore-for-hash won't work in exclusive containers\n" << end();
|
||||
variant.set_value(r.value + /*skip tag*/1);
|
||||
h = hash(h, variant);
|
||||
return h;
|
||||
|
@ -362,11 +362,11 @@ put(Recipe_ordinal, "hash_old", HASH_OLD);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case HASH_OLD: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'hash_old' takes exactly one ingredient rather than '" << to_string(inst) << "'\n" << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'hash_old' takes exactly one ingredient rather than '" << to_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_string(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'hash_old' currently only supports strings (address:shared:array:character), but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'hash_old' currently only supports strings (address:shared:array:character), but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -22,9 +22,9 @@ case OPEN_CONSOLE: {
|
|||
long long int height = tb_height();
|
||||
if (width > 222 || height > 222) tb_shutdown();
|
||||
if (width > 222)
|
||||
raise_error << "sorry, mu doesn't support windows wider than 222 characters. Please resize your window.\n" << end();
|
||||
raise << "sorry, mu doesn't support windows wider than 222 characters. Please resize your window.\n" << end();
|
||||
if (height > 222)
|
||||
raise_error << "sorry, mu doesn't support windows taller than 222 characters. Please resize your window.\n" << end();
|
||||
raise << "sorry, mu doesn't support windows taller than 222 characters. Please resize your window.\n" << end();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -100,22 +100,22 @@ put(Recipe_ordinal, "print-character-to-display", PRINT_CHARACTER_TO_DISPLAY);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case PRINT_CHARACTER_TO_DISPLAY: {
|
||||
if (inst.ingredients.empty()) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'print-character-to-display' requires at least one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'print-character-to-display' requires at least one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'print-character-to-display' should be a character, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'print-character-to-display' should be a character, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (SIZE(inst.ingredients) > 1) {
|
||||
if (!is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'print-character-to-display' should be a foreground color number, but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'print-character-to-display' should be a foreground color number, but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (SIZE(inst.ingredients) > 2) {
|
||||
if (!is_mu_number(inst.ingredients.at(2))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "third ingredient of 'print-character-to-display' should be a background color number, but got " << inst.ingredients.at(2).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "third ingredient of 'print-character-to-display' should be a background color number, but got " << inst.ingredients.at(2).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -186,15 +186,15 @@ put(Recipe_ordinal, "move-cursor-on-display", MOVE_CURSOR_ON_DISPLAY);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case MOVE_CURSOR_ON_DISPLAY: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'move-cursor-on-display' requires two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'move-cursor-on-display' requires two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'move-cursor-on-display' should be a row number, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'move-cursor-on-display' should be a row number, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'move-cursor-on-display' should be a column number, but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'move-cursor-on-display' should be a column number, but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -233,11 +233,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_error << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ", address " << addr << ", value " << no_scientific(get_or_insert(Memory, addr)) << ") to be in color " << color << " instead of " << no_scientific(get_or_insert(Memory, addr+cell_color_offset)) << "\n" << end();
|
||||
raise << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ", address " << addr << ", value " << no_scientific(get_or_insert(Memory, addr)) << ") to be in color " << color << " instead of " << no_scientific(get_or_insert(Memory, addr+cell_color_offset)) << "\n" << end();
|
||||
}
|
||||
else {
|
||||
// just testing check_screen
|
||||
raise_error << "expected screen location (" << row << ", " << column << ") to be in color " << color << " instead of " << no_scientific(get_or_insert(Memory, addr+cell_color_offset)) << '\n' << end();
|
||||
raise << "expected screen location (" << row << ", " << column << ") to be in color " << color << " instead of " << no_scientific(get_or_insert(Memory, addr+cell_color_offset)) << '\n' << end();
|
||||
}
|
||||
if (!Scenario_testing_scenario) {
|
||||
Passed = false;
|
||||
|
@ -263,12 +263,12 @@ void check_screen(const string& expected_contents, const int color) {
|
|||
if (color != -1) color_phrase << " in color " << color;
|
||||
if (Current_scenario && !Scenario_testing_scenario) {
|
||||
// genuine test in a mu file
|
||||
raise_error << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << color_phrase.str() << " instead of " << no_scientific(get_or_insert(Memory, addr)) << actual_pretty << '\n' << end();
|
||||
raise << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << color_phrase.str() << " instead of " << no_scientific(get_or_insert(Memory, addr)) << actual_pretty << '\n' << end();
|
||||
dump_screen();
|
||||
}
|
||||
else {
|
||||
// just testing check_screen
|
||||
raise_error << "expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << color_phrase.str() << " instead of " << no_scientific(get_or_insert(Memory, addr)) << actual_pretty << '\n' << end();
|
||||
raise << "expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << color_phrase.str() << " instead of " << no_scientific(get_or_insert(Memory, addr)) << actual_pretty << '\n' << end();
|
||||
}
|
||||
if (!Scenario_testing_scenario) {
|
||||
Passed = false;
|
||||
|
@ -287,7 +287,7 @@ raw_string_stream::raw_string_stream(const string& backing) :index(0), max(SIZE(
|
|||
bool raw_string_stream::at_end() const {
|
||||
if (index >= max) return true;
|
||||
if (tb_utf8_char_length(buf[index]) > max-index) {
|
||||
raise_error << "unicode string seems corrupted at index "<< index << " character " << static_cast<int>(buf[index]) << '\n' << end();
|
||||
raise << "unicode string seems corrupted at index "<< index << " character " << static_cast<int>(buf[index]) << '\n' << end();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -78,7 +78,7 @@ case ASSUME_CONSOLE: {
|
|||
else if (contains_key(Key, key))
|
||||
put(Memory, Current_routine->alloc+1, Key[key]);
|
||||
else
|
||||
raise_error << "assume-console: can't press " << key << '\n' << end();
|
||||
raise << "assume-console: can't press " << key << '\n' << end();
|
||||
if (get_or_insert(Memory, Current_routine->alloc+1) < 256)
|
||||
// these keys are in ascii
|
||||
put(Memory, Current_routine->alloc, /*tag for 'text' variant of 'event' exclusive-container*/0);
|
||||
|
@ -245,7 +245,7 @@ case REPLACE_IN_CONSOLE: {
|
|||
case REPLACE_IN_CONSOLE: {
|
||||
assert(scalar(ingredients.at(0)));
|
||||
if (!get_or_insert(Memory, CONSOLE)) {
|
||||
raise_error << "console not initialized\n" << end();
|
||||
raise << "console not initialized\n" << end();
|
||||
break;
|
||||
}
|
||||
long long int console_address = get_or_insert(Memory, CONSOLE);
|
||||
|
|
|
@ -30,11 +30,11 @@ put(Recipe_ordinal, "run-interactive", RUN_INTERACTIVE);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case RUN_INTERACTIVE: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'run-interactive' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'run-interactive' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_string(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'run-interactive' should be a string, but got " << to_string(inst.ingredients.at(0)) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'run-interactive' should be a string, but got " << to_string(inst.ingredients.at(0)) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -445,11 +445,11 @@ put(Recipe_ordinal, "reload", RELOAD);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case RELOAD: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'reload' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'reload' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_string(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'reload' should be a string, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'reload' should be a string, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -9,7 +9,7 @@ put(Recipe_ordinal, "restore", RESTORE);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case RESTORE: {
|
||||
if (SIZE(inst.ingredients) != 1) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'restore' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'restore' requires exactly one ingredient, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
string filename;
|
||||
|
@ -20,7 +20,7 @@ case RESTORE: {
|
|||
;
|
||||
}
|
||||
else {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'restore' should be a string, but got " << to_string(inst.ingredients.at(0)) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'restore' should be a string, but got " << to_string(inst.ingredients.at(0)) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -73,7 +73,7 @@ put(Recipe_ordinal, "save", SAVE);
|
|||
:(before "End Primitive Recipe Checks")
|
||||
case SAVE: {
|
||||
if (SIZE(inst.ingredients) != 2) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "'save' requires exactly two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "'save' requires exactly two ingredients, but got " << to_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (is_literal_string(inst.ingredients.at(0))) {
|
||||
|
@ -83,11 +83,11 @@ case SAVE: {
|
|||
;
|
||||
}
|
||||
else {
|
||||
raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'save' should be a string, but got " << to_string(inst.ingredients.at(0)) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'save' should be a string, but got " << to_string(inst.ingredients.at(0)) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_string(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'save' should be an address:array:character, but got " << to_string(inst.ingredients.at(1)) << '\n' << end();
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'save' should be an address:array:character, but got " << to_string(inst.ingredients.at(1)) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -111,7 +111,7 @@ case SAVE: {
|
|||
// explicitly say '--all' for git 1.9
|
||||
int status = system("cd lesson; git add --all .; git diff HEAD --exit-code >/dev/null || git commit -a -m . >/dev/null");
|
||||
if (status != 0)
|
||||
raise_error << "error in commit: contents " << contents << '\n' << end();
|
||||
raise << "error in commit: contents " << contents << '\n' << end();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue