blob: 81260c5ef8be972599f819ea27f744b07ff973da (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
//: 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("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;
}
|