diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-10-07 00:22:49 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-10-07 00:22:49 -0700 |
commit | 7afe09fbfeb88e3be98dfe4f0db43f66724d4abf (patch) | |
tree | 0592cc6cf3e98aa25ec9c35b638a56baeff1d5e3 | |
parent | 857adbc496dca7d41e46cbece815a24d32c735fe (diff) | |
download | mu-7afe09fbfeb88e3be98dfe4f0db43f66724d4abf.tar.gz |
2262 - strengthen some type checks
-rw-r--r-- | 037recipe.cc | 11 | ||||
-rw-r--r-- | 038scheduler.cc | 12 | ||||
-rw-r--r-- | 043new.cc | 16 | ||||
-rw-r--r-- | 044space.cc | 8 | ||||
-rw-r--r-- | 053continuation.cc | 13 | ||||
-rw-r--r-- | 081run_interactive.cc | 21 |
6 files changed, 55 insertions, 26 deletions
diff --git a/037recipe.cc b/037recipe.cc index f7dd62d7..55522bd9 100644 --- a/037recipe.cc +++ b/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; +} diff --git a/038scheduler.cc b/038scheduler.cc index ac16db22..f66d5c80 100644 --- a/038scheduler.cc +++ b/038scheduler.cc @@ -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; } diff --git a/043new.cc b/043new.cc index f821fad3..e28284ae 100644 --- a/043new.cc +++ b/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"; +} diff --git a/044space.cc b/044space.cc index 55e3cc23..2d1a18f0 100644 --- a/044space.cc +++ b/044space.cc @@ -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; } diff --git a/053continuation.cc b/053continuation.cc index c9a6a5cb..9ccd6311 100644 --- a/053continuation.cc +++ b/053continuation.cc @@ -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; diff --git a/081run_interactive.cc b/081run_interactive.cc index e4c847f1..81c49d42 100644 --- a/081run_interactive.cc +++ b/081run_interactive.cc @@ -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; |