2262 - strengthen some type checks
This commit is contained in:
parent
857adbc496
commit
7afe09fbfe
11
037recipe.cc
11
037recipe.cc
|
@ -46,7 +46,7 @@ case CALL: {
|
|||
raise_error << maybe(Recipe[r].name) << "'call' requires at least one ingredient (the recipe to call)\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
if (!is_mu_recipe(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(Recipe[r].name) << "first ingredient of 'call' should be a recipe, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
|
@ -59,3 +59,12 @@ case CALL: {
|
|||
ingredients.erase(ingredients.begin()); // drop the callee
|
||||
goto call_housekeeping;
|
||||
}
|
||||
|
||||
:(code)
|
||||
bool is_mu_recipe(reagent r) {
|
||||
if (r.types.empty()) return false;
|
||||
if (r.types.at(0) == Type_ordinal["recipe"]) return true;
|
||||
if (r.types.at(0) == Type_ordinal["recipe-ordinal"]) return true;
|
||||
// End is_mu_recipe Cases
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ case START_RUNNING: {
|
|||
raise_error << maybe(Recipe[r].name) << "'start-running' requires at least one ingredient: the recipe to start running\n" << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
if (!is_mu_recipe(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(Recipe[r].name) << "first ingredient of 'start-running' should be a recipe, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ case ROUTINE_STATE: {
|
|||
raise_error << maybe(Recipe[r].name) << "'routine-state' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(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;
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ case RESTART: {
|
|||
raise_error << maybe(Recipe[r].name) << "'restart' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(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;
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ case STOP: {
|
|||
raise_error << maybe(Recipe[r].name) << "'stop' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(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;
|
||||
}
|
||||
|
@ -479,11 +479,11 @@ case LIMIT_TIME: {
|
|||
raise_error << maybe(Recipe[r].name) << "'limit-time' requires exactly two ingredient, but got " << inst.to_string() << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
if (!is_mu_number(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(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_scalar(inst.ingredients.at(1))) {
|
||||
if (!is_mu_number(inst.ingredients.at(1))) {
|
||||
raise_error << maybe(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;
|
||||
}
|
||||
|
|
16
043new.cc
16
043new.cc
|
@ -35,9 +35,7 @@ if (inst.operation == Recipe_ordinal["new"]) {
|
|||
// first arg must be of type 'type'
|
||||
if (inst.ingredients.empty())
|
||||
raise_error << maybe(Recipe[r].name) << "'new' expects one or two ingredients\n" << end();
|
||||
if (inst.ingredients.at(0).properties.empty()
|
||||
|| inst.ingredients.at(0).properties.at(0).second.empty()
|
||||
|| inst.ingredients.at(0).properties.at(0).second.at(0) != "type")
|
||||
if (!is_mu_type_literal(inst.ingredients.at(0)))
|
||||
raise_error << maybe(Recipe[r].name) << "first ingredient of 'new' should be a type, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
if (Type_ordinal.find(inst.ingredients.at(0).name) == Type_ordinal.end())
|
||||
raise_error << maybe(Recipe[r].name) << "unknown type " << inst.ingredients.at(0).name << '\n' << end();
|
||||
|
@ -59,8 +57,9 @@ case NEW: {
|
|||
raise_error << maybe(Recipe[r].name) << "'new' requires one or two ingredients, but got " << inst.to_string() << '\n' << end();
|
||||
break;
|
||||
}
|
||||
// End NEW Checks
|
||||
reagent type = inst.ingredients.at(0);
|
||||
if (!is_mu_scalar(type) && !is_literal(type)) {
|
||||
if (!is_mu_type_literal(type)) {
|
||||
raise_error << maybe(Recipe[r].name) << "first ingredient of 'new' should be a type, but got " << type.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
|
@ -323,9 +322,10 @@ recipe main [
|
|||
goto end_new_transform;
|
||||
}
|
||||
|
||||
:(before "End NEW Checks")
|
||||
if (is_literal_string(inst.ingredients.at(0))) break;
|
||||
:(after "case NEW" following "Primitive Recipe Implementations")
|
||||
if (is_literal(current_instruction().ingredients.at(0))
|
||||
&& current_instruction().ingredients.at(0).properties.at(0).second.at(0) == "literal-string") {
|
||||
if (is_literal_string(current_instruction().ingredients.at(0))) {
|
||||
products.resize(1);
|
||||
products.at(0).push_back(new_mu_string(current_instruction().ingredients.at(0).name));
|
||||
break;
|
||||
|
@ -428,3 +428,7 @@ string read_mu_string(long long int address) {
|
|||
}
|
||||
return tmp.str();
|
||||
}
|
||||
|
||||
bool is_mu_type_literal(reagent r) {
|
||||
return is_literal(r) && !r.properties.empty() && !r.properties.at(0).second.empty() && r.properties.at(0).second.at(0) == "type";
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ recipe main [
|
|||
|
||||
//:: first disable name conversion for 'default-space'
|
||||
:(scenario convert_names_passes_default_space)
|
||||
% Hide_errors = true;
|
||||
recipe main [
|
||||
default-space:number, x:number <- copy 0, 1
|
||||
]
|
||||
|
@ -211,8 +212,13 @@ long long int address(long long int offset, long long int base) {
|
|||
|
||||
:(after "void write_memory(reagent x, vector<double> data)")
|
||||
if (x.name == "default-space") {
|
||||
if (!scalar(data))
|
||||
if (!scalar(data)
|
||||
|| SIZE(x.types) != 3
|
||||
|| x.types.at(0) != Type_ordinal["address"]
|
||||
|| x.types.at(1) != Type_ordinal["array"]
|
||||
|| x.types.at(2) != Type_ordinal["location"]) {
|
||||
raise_error << maybe(current_recipe_name()) << "'default-space' should be of type address:array:location, but tried to write " << to_string(data) << '\n' << end();
|
||||
}
|
||||
Current_routine->calls.front().default_space = data.at(0);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ CONTINUE_FROM,
|
|||
Recipe_ordinal["continue-from"] = CONTINUE_FROM;
|
||||
:(before "End Primitive Recipe Checks")
|
||||
case CONTINUE_FROM: {
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(Recipe[r].name) << "first ingredient of 'continue-from' should be a continuation id generated by 'current-continuation', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
if (!is_mu_continuation(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(Recipe[r].name) << "first ingredient of 'continue-from' should be a continuation generated by 'current-continuation', but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -57,6 +57,12 @@ case CONTINUE_FROM: {
|
|||
continue; // skip rest of this instruction
|
||||
}
|
||||
|
||||
:(code)
|
||||
bool is_mu_continuation(const reagent& x) {
|
||||
if (x.types.empty()) return false;
|
||||
return x.types.at(0) == Type_ordinal["continuation"];
|
||||
}
|
||||
|
||||
:(scenario continuation)
|
||||
# simulate a loop using continuations
|
||||
recipe main [
|
||||
|
@ -253,3 +259,6 @@ call_stack::iterator find_reset(call_stack& c) {
|
|||
ingredients.erase(ingredients.begin()); // drop the callee
|
||||
goto call_housekeeping;
|
||||
}
|
||||
|
||||
:(before "End is_mu_recipe Cases")
|
||||
if (r.types.at(0) == Type_ordinal["continuation"]) return true;
|
||||
|
|
|
@ -12,10 +12,11 @@ recipe main [
|
|||
|
||||
:(scenario run_interactive_empty)
|
||||
recipe main [
|
||||
1:address:array:character <- run-interactive 0
|
||||
1:address:array:character <- copy 0/raw
|
||||
2:address:array:character <- run-interactive 1:address:array:character
|
||||
]
|
||||
# result is null
|
||||
+mem: storing 0 in location 1
|
||||
+mem: storing 0 in location 2
|
||||
|
||||
//: run code in 'interactive mode', i.e. with errors+warnings off and return:
|
||||
//: stringified output in case we want to print it to screen
|
||||
|
@ -32,7 +33,7 @@ case RUN_INTERACTIVE: {
|
|||
raise_error << maybe(Recipe[r].name) << "'run-interactive' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
if (!is_mu_string(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(Recipe[r].name) << "first ingredient of 'run-interactive' should be a string, but got " << inst.ingredients.at(0).to_string() << '\n' << end();
|
||||
break;
|
||||
}
|
||||
|
@ -138,7 +139,7 @@ load(string(
|
|||
"completed?:boolean <- equal sandbox-state, 1/completed\n" +
|
||||
"output:address:array:character <- $most-recent-products\n" +
|
||||
"warnings:address:array:character <- save-errors-warnings\n" +
|
||||
"stashes:address:array:character <- save-trace [app]\n" +
|
||||
"stashes:address:array:character <- save-app-trace\n" +
|
||||
"$cleanup-run-interactive\n" +
|
||||
"reply output, warnings, screen, stashes, completed?\n" +
|
||||
"]\n");
|
||||
|
@ -217,15 +218,15 @@ case SAVE_ERRORS_WARNINGS: {
|
|||
}
|
||||
|
||||
:(before "End Primitive Recipe Declarations")
|
||||
SAVE_TRACE,
|
||||
SAVE_APP_TRACE,
|
||||
:(before "End Primitive Recipe Numbers")
|
||||
Recipe_ordinal["save-trace"] = SAVE_TRACE;
|
||||
Recipe_ordinal["save-app-trace"] = SAVE_APP_TRACE;
|
||||
:(before "End Primitive Recipe Checks")
|
||||
case SAVE_TRACE: {
|
||||
case SAVE_APP_TRACE: {
|
||||
break;
|
||||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case SAVE_TRACE: {
|
||||
case SAVE_APP_TRACE: {
|
||||
products.resize(1);
|
||||
products.at(0).push_back(trace_app_contents());
|
||||
break;
|
||||
|
@ -393,8 +394,8 @@ case RELOAD: {
|
|||
raise_error << maybe(Recipe[r].name) << "'reload' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (!is_mu_scalar(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(Recipe[r].name) << "first ingredient of 'reload' should be a literal string, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
if (!is_mu_string(inst.ingredients.at(0))) {
|
||||
raise_error << maybe(Recipe[r].name) << "first ingredient of 'reload' should be a string, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue
Block a user