diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-05-17 18:25:26 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-05-17 18:25:26 -0700 |
commit | 882989243a31354b3b82df021847bb332b483fd2 (patch) | |
tree | 61ffbcd1ab5ede8f66209a4a721ff6f7f6e86094 /063rewrite_literal_string.cc | |
parent | 38f72faa1865e011df87cd76b39b54bc07eedb74 (diff) | |
download | mu-882989243a31354b3b82df021847bb332b483fd2.tar.gz |
2971
Long-overdue reorganization to support general 'dilated' reagents up front. This also allows me to move tests that are really about unrelated layers out of layers dealing with parsing.
Diffstat (limited to '063rewrite_literal_string.cc')
-rw-r--r-- | 063rewrite_literal_string.cc | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/063rewrite_literal_string.cc b/063rewrite_literal_string.cc new file mode 100644 index 00000000..9eeeefaa --- /dev/null +++ b/063rewrite_literal_string.cc @@ -0,0 +1,75 @@ +//: allow using literal strings anywhere that will accept immutable strings + +:(scenario passing_literals_to_recipes) +def main [ + 1:number/raw <- foo [abc] +] +def foo x:address:array:character -> n:number [ + local-scope + load-ingredients + n <- length *x +] ++mem: storing 3 in location 1 + +:(before "End Instruction Inserting/Deleting Transforms") +initialize_transform_rewrite_literal_string_to_text(); +Transform.push_back(rewrite_literal_string_to_text); + +:(before "End Globals") +set<string> recipes_taking_literal_strings; +:(code) +void initialize_transform_rewrite_literal_string_to_text() { + recipes_taking_literal_strings.insert("$print"); + recipes_taking_literal_strings.insert("$system"); + recipes_taking_literal_strings.insert("trace"); + recipes_taking_literal_strings.insert("stash"); + recipes_taking_literal_strings.insert("assert"); + recipes_taking_literal_strings.insert("new"); + recipes_taking_literal_strings.insert("run"); + recipes_taking_literal_strings.insert("assume-console"); + recipes_taking_literal_strings.insert("memory-should-contain"); + recipes_taking_literal_strings.insert("trace-should-contain"); + recipes_taking_literal_strings.insert("trace-should-not-contain"); + recipes_taking_literal_strings.insert("check-trace-count-for-label"); + recipes_taking_literal_strings.insert("screen-should-contain"); + recipes_taking_literal_strings.insert("screen-should-contain-in-color"); +} + +void rewrite_literal_string_to_text(recipe_ordinal r) { + recipe& caller = get(Recipe, r); + trace(9991, "transform") << "--- rewrite literal strings in recipe " << caller.name << end(); + if (contains_numeric_locations(caller)) return; + vector<instruction> new_instructions; + for (int i = 0; i < SIZE(caller.steps); ++i) { + instruction& inst = caller.steps.at(i); + if (recipes_taking_literal_strings.find(inst.name) == recipes_taking_literal_strings.end()) { + for (int j = 0; j < SIZE(inst.ingredients); ++j) { + if (!is_literal_string(inst.ingredients.at(j))) continue; + instruction def; + ostringstream ingredient_name; + ingredient_name << inst.name << '_' << i << '_' << j << ":address:array:character"; + def.name = "new"; + def.ingredients.push_back(inst.ingredients.at(j)); + def.products.push_back(reagent(ingredient_name.str())); + new_instructions.push_back(def); + inst.ingredients.at(j).clear(); // reclaim old memory + inst.ingredients.at(j) = reagent(ingredient_name.str()); + } + } + new_instructions.push_back(inst); + } + caller.steps.swap(new_instructions); +} + +bool contains_numeric_locations(const recipe& caller) { + for (int i = 0; i < SIZE(caller.steps); ++i) { + const instruction& inst = caller.steps.at(i); + for (int in = 0; in < SIZE(inst.ingredients); ++in) + if (is_numeric_location(inst.ingredients.at(in))) + return true; + for (int out = 0; out < SIZE(inst.products); ++out) + if (is_numeric_location(inst.products.at(out))) + return true; + } + return false; +} |