1
2
3 :(scenarios transform)
4 :(scenario rewrite_stashes_to_text)
5 def main [
6 local-scope
7 n:num <- copy 34
8 stash n
9 ]
10 +transform: {stash_2_0: ("address" "array" "character")} <- to-text-line {n: "number"}
11 +transform: stash {stash_2_0: ("address" "array" "character")}
12
13 :(scenario rewrite_traces_to_text)
14 def main [
15 local-scope
16 n:num <- copy 34
17 trace 2, [app], n
18 ]
19 +transform: {trace_2_2: ("address" "array" "character")} <- to-text-line {n: "number"}
20 +transform: trace {2: "literal"}, {"app": "literal-string"}, {trace_2_2: ("address" "array" "character")}
21
22
23
24
25 :(scenario rewrite_stashes_of_arrays)
26 def main [
27 local-scope
28 n:&:@:num <- new number:type, 3
29 stash *n
30 ]
31 +transform: {stash_2_0: ("address" "array" "character")} <- array-to-text-line {n: ("address" "array" "number")}
32 +transform: stash {stash_2_0: ("address" "array" "character")}
33
34 :(scenario ignore_stashes_of_static_arrays)
35 def main [
36 local-scope
37 n:@:num:3 <- create-array
38 stash n
39 ]
40 +transform: stash {n: ("array" "number" "3")}
41
42 :(scenario rewrite_stashes_of_recipe_header_products)
43 container foo [
44 x:num
45 ]
46 def bar -> x:foo [
47 local-scope
48 load-ingredients
49 x <- merge 34
50 stash x
51 ]
52 +transform: stash {stash_2_0: ("address" "array" "character")}
53
54
55
56 :(after "Transform.push_back(deduce_types_from_header)")
57 Transform.push_back(convert_ingredients_to_text);
58
59 :(code)
60 void convert_ingredients_to_text(const recipe_ordinal r) {
61 recipe& caller = get(Recipe, r);
62 trace(9991, "transform") << "--- convert some ingredients to text in recipe " << caller.name << end();
63
64 if (contains_numeric_locations(caller)) return;
65 convert_ingredients_to_text(caller);
66 }
67
68 void convert_ingredients_to_text(recipe& caller) {
69 vector<instruction> new_instructions;
70 for (int i = 0; i < SIZE(caller.steps); ++i) {
71 ¦ instruction& inst = caller.steps.at(i);
72 ¦
73 ¦ if (inst.name == "stash") {
74 ¦ ¦ for (int j = 0; j < SIZE(inst.ingredients); ++j) {
75 ¦ ¦ ¦ if (is_literal_text(inst.ingredients.at(j))) continue;
76 ¦ ¦ ¦ ostringstream ingredient_name;
77 ¦ ¦ ¦ ingredient_name << "stash_" << i << '_' << j << ":address:array:character";
78 ¦ ¦ ¦ convert_ingredient_to_text(inst.ingredients.at(j), new_instructions, ingredient_name.str());
79 ¦ ¦ }
80 ¦ }
81 ¦ else if (inst.name == "trace") {
82 ¦ ¦ for (int j = 2; j < SIZE(inst.ingredients); ++j) {
83 ¦ ¦ ¦ if (is_literal_text(inst.ingredients.at(j))) continue;
84 ¦ ¦ ¦ ostringstream ingredient_name;
85 ¦ ¦ ¦ ingredient_name << "trace_" << i << '_' << j << ":address:array:character";
86 ¦ ¦ ¦ convert_ingredient_to_text(inst.ingredients.at(j), new_instructions, ingredient_name.str());
87 ¦ ¦ }
88 ¦ }
89 ¦ else if (inst.name_before_rewrite == "append") {
90 ¦ ¦
91 ¦ ¦
92 ¦ ¦
93 ¦ ¦
94 ¦ ¦
95 ¦ ¦ if (is_literal_text(inst.ingredients.at(0)) || is_mu_text(inst.ingredients.at(0))) {
96 ¦ ¦ ¦ for (int j = 1; j < SIZE(inst.ingredients); ++j) {
97 ¦ ¦ ¦ ¦ ostringstream ingredient_name;
98 ¦ ¦ ¦ ¦ ingredient_name << "append_" << i << '_' << j << ":address:array:character";
99 ¦ ¦ ¦ ¦ convert_ingredient_to_text(inst.ingredients.at(j), new_instructions, ingredient_name.str());
100 ¦ ¦ ¦ }
101 ¦ ¦ }
102 ¦ }
103 ¦ trace(9993, "transform") << to_string(inst) << end();
104 ¦ new_instructions.push_back(inst);
105 }
106 caller.steps.swap(new_instructions);
107 }
108
109
110
111 void convert_ingredient_to_text(reagent& r, vector<instruction>& out, const string& tmp_var) {
112 if (!r.type) return;
113 if (is_mu_text(r)) return;
114
115 if (is_static_array(r)) return;
116 instruction def;
117 if (is_lookup_of_address_of_array(r)) {
118 ¦ def.name = "array-to-text-line";
119 ¦ reagent tmp = r;
120 ¦ drop_one_lookup(tmp);
121 ¦ def.ingredients.push_back(tmp);
122 }
123 else {
124 ¦ def.name = "to-text-line";
125 ¦ def.ingredients.push_back(r);
126 }
127 def.products.push_back(reagent(tmp_var));
128 trace(9993, "transform") << to_string(def) << end();
129 out.push_back(def);
130 r.clear();
131 r = reagent(tmp_var);
132 }
133
134 bool is_lookup_of_address_of_array(reagent x) {
135 if (x.type->atom) return false;
136 if (x.type->left->name != "address") return false;
137 if (!canonize_type(x)) return false;
138 return is_mu_array(x);
139 }
140
141 bool is_static_array(const reagent& x) {
142
143 return !x.type->atom && x.type->left->atom && x.type->left->name == "array";
144 }
145
146 :(scenarios run)
147 :(scenario append_other_types_to_text)
148 def main [
149 local-scope
150 n:num <- copy 11
151 c:character <- copy 111/o
152 a:text <- append [abc], 10, n, c
153 expected:text <- new [abc1011o]
154 10:bool/raw <- equal a, expected
155 ]
156
157
158
159
160 :(scenario rewrite_stash_continues_to_fall_back_to_default_implementation)
161
162 container foo [
163 x:num
164 y:num
165 ]
166 def main [
167 local-scope
168 x:foo <- merge 34, 35
169 stash x
170 ]
171 +app: 34 35