From 850822ffbfd441d05161452be28b54f882b1b378 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 1 Nov 2017 03:41:16 -0700 Subject: 4102 --- html/042name.cc.html | 371 ++++++++++++++++++++++++++------------------------- 1 file changed, 189 insertions(+), 182 deletions(-) (limited to 'html/042name.cc.html') diff --git a/html/042name.cc.html b/html/042name.cc.html index 5ba9de66..7d046a9f 100644 --- a/html/042name.cc.html +++ b/html/042name.cc.html @@ -116,8 +116,8 @@ if ('onhashchange' in window) { 51 ¦ ¦ reagent& ingredient = inst.ingredients.at(in); 52 ¦ ¦ // Begin transform_names Ingredient Special-cases(ingredient, inst, caller) 53 ¦ ¦ if (is_disqualified(ingredient, inst, caller.name)) continue; - 54 ¦ ¦ if (is_numeric_location(ingredient)) numeric_locations_used = true; - 55 ¦ ¦ if (is_named_location(ingredient)) names_used = true; + 54 ¦ ¦ if (is_numeric_location(ingredient)) numeric_locations_used = true; + 55 ¦ ¦ if (is_named_location(ingredient)) names_used = true; 56 ¦ ¦ if (is_integer(ingredient.name)) continue; 57 ¦ ¦ if (!already_transformed(ingredient, names)) { 58 ¦ ¦ ¦ raise << maybe(caller.name) << "tried to read ingredient '" << ingredient.name << "' in '" << to_original_string(inst) << "' but it hasn't been written to yet\n" << end(); @@ -138,8 +138,8 @@ if ('onhashchange' in window) { 73 ¦ ¦ reagent& product = inst.products.at(out); 74 ¦ ¦ // Begin transform_names Product Special-cases(product, inst, caller) 75 ¦ ¦ if (is_disqualified(product, inst, caller.name)) continue; - 76 ¦ ¦ if (is_numeric_location(product)) numeric_locations_used = true; - 77 ¦ ¦ if (is_named_location(product)) names_used = true; + 76 ¦ ¦ if (is_numeric_location(product)) numeric_locations_used = true; + 77 ¦ ¦ if (is_named_location(product)) names_used = true; 78 ¦ ¦ if (is_integer(product.name)) continue; 79 ¦ ¦ if (names.find(product.name) == names.end()) { 80 ¦ ¦ ¦ trace(9993, "name") << "assign " << product.name << " " << curr_idx << end(); @@ -183,7 +183,7 @@ if ('onhashchange' in window) { 118 } 119 120 type_ordinal skip_addresses(type_tree* type) { -121 while (type && is_compound_type_starting_with(type, "address")) +121 while (type && is_compound_type_starting_with(type, "address")) 122 ¦ type = type->right; 123 if (!type) return -1; // error handled elsewhere 124 if (type->atom) return type->value; @@ -195,199 +195,206 @@ if ('onhashchange' in window) { 130 return base_type->left->value; 131 } 132 -133 int find_element_name(const type_ordinal t, const string& name, const string& recipe_name) { -134 const type_info& container = get(Type, t); -135 for (int i = 0; i < SIZE(container.elements); ++i) -136 ¦ if (container.elements.at(i).name == name) return i; -137 raise << maybe(recipe_name) << "unknown element '" << name << "' in container '" << get(Type, t).name << "'\n" << end(); -138 return -1; -139 } -140 -141 bool is_numeric_location(const reagent& x) { -142 if (is_literal(x)) return false; -143 if (is_raw(x)) return false; -144 if (x.name == "0") return false; // used for chaining lexical scopes -145 return is_integer(x.name); +133 bool is_compound_type_starting_with(const type_tree* type, const string& expected_name) { +134 if (!type) return false; +135 if (type->atom) return false; +136 if (!type->left->atom) return false; +137 return type->left->value == get(Type_ordinal, expected_name); +138 } +139 +140 int find_element_name(const type_ordinal t, const string& name, const string& recipe_name) { +141 const type_info& container = get(Type, t); +142 for (int i = 0; i < SIZE(container.elements); ++i) +143 ¦ if (container.elements.at(i).name == name) return i; +144 raise << maybe(recipe_name) << "unknown element '" << name << "' in container '" << get(Type, t).name << "'\n" << end(); +145 return -1; 146 } 147 -148 bool is_named_location(const reagent& x) { +148 bool is_numeric_location(const reagent& x) { 149 if (is_literal(x)) return false; 150 if (is_raw(x)) return false; -151 if (is_special_name(x.name)) return false; -152 return !is_integer(x.name); +151 if (x.name == "0") return false; // used for chaining lexical scopes +152 return is_integer(x.name); 153 } 154 -155 // all names here should either be disqualified or also in bind_special_scenario_names -156 bool is_special_name(const string& s) { -157 if (s == "_") return true; -158 if (s == "0") return true; -159 // End is_special_name Special-cases -160 return false; -161 } -162 -163 :(scenario transform_names_supports_containers) -164 def main [ -165 x:point <- merge 34, 35 -166 y:num <- copy 3 -167 ] -168 +name: assign x 1 -169 # skip location 2 because x occupies two locations -170 +name: assign y 3 -171 -172 :(scenario transform_names_supports_static_arrays) -173 def main [ -174 x:@:num:3 <- create-array -175 y:num <- copy 3 -176 ] -177 +name: assign x 1 -178 # skip locations 2, 3, 4 because x occupies four locations -179 +name: assign y 5 -180 -181 :(scenario transform_names_passes_dummy) -182 # _ is just a dummy result that never gets consumed -183 def main [ -184 _, x:num <- copy 0, 1 -185 ] -186 +name: assign x 1 -187 -name: assign _ 1 -188 -189 //: an escape hatch to suppress name conversion that we'll use later -190 :(scenarios run) -191 :(scenario transform_names_passes_raw) -192 % Hide_errors = true; -193 def main [ -194 x:num/raw <- copy 0 -195 ] -196 -name: assign x 1 -197 +error: can't write to location 0 in 'x:num/raw <- copy 0' -198 -199 :(scenarios transform) -200 :(scenario transform_names_fails_when_mixing_names_and_numeric_locations) -201 % Hide_errors = true; -202 def main [ -203 x:num <- copy 1:num -204 ] -205 +error: main: mixing variable names and numeric addresses -206 -207 :(scenario transform_names_fails_when_mixing_names_and_numeric_locations_2) +155 bool is_named_location(const reagent& x) { +156 if (is_literal(x)) return false; +157 if (is_raw(x)) return false; +158 if (is_special_name(x.name)) return false; +159 return !is_integer(x.name); +160 } +161 +162 // all names here should either be disqualified or also in bind_special_scenario_names +163 bool is_special_name(const string& s) { +164 if (s == "_") return true; +165 if (s == "0") return true; +166 // End is_special_name Special-cases +167 return false; +168 } +169 +170 :(scenario transform_names_supports_containers) +171 def main [ +172 x:point <- merge 34, 35 +173 y:num <- copy 3 +174 ] +175 +name: assign x 1 +176 # skip location 2 because x occupies two locations +177 +name: assign y 3 +178 +179 :(scenario transform_names_supports_static_arrays) +180 def main [ +181 x:@:num:3 <- create-array +182 y:num <- copy 3 +183 ] +184 +name: assign x 1 +185 # skip locations 2, 3, 4 because x occupies four locations +186 +name: assign y 5 +187 +188 :(scenario transform_names_passes_dummy) +189 # _ is just a dummy result that never gets consumed +190 def main [ +191 _, x:num <- copy 0, 1 +192 ] +193 +name: assign x 1 +194 -name: assign _ 1 +195 +196 //: an escape hatch to suppress name conversion that we'll use later +197 :(scenarios run) +198 :(scenario transform_names_passes_raw) +199 % Hide_errors = true; +200 def main [ +201 x:num/raw <- copy 0 +202 ] +203 -name: assign x 1 +204 +error: can't write to location 0 in 'x:num/raw <- copy 0' +205 +206 :(scenarios transform) +207 :(scenario transform_names_fails_when_mixing_names_and_numeric_locations) 208 % Hide_errors = true; 209 def main [ -210 x:num <- copy 1 -211 1:num <- copy x:num -212 ] -213 +error: main: mixing variable names and numeric addresses -214 -215 :(scenario transform_names_does_not_fail_when_mixing_names_and_raw_locations) +210 x:num <- copy 1:num +211 ] +212 +error: main: mixing variable names and numeric addresses +213 +214 :(scenario transform_names_fails_when_mixing_names_and_numeric_locations_2) +215 % Hide_errors = true; 216 def main [ -217 x:num <- copy 1:num/raw -218 ] -219 -error: main: mixing variable names and numeric addresses -220 $error: 0 +217 x:num <- copy 1 +218 1:num <- copy x:num +219 ] +220 +error: main: mixing variable names and numeric addresses 221 -222 :(scenario transform_names_does_not_fail_when_mixing_names_and_literals) +222 :(scenario transform_names_does_not_fail_when_mixing_names_and_raw_locations) 223 def main [ -224 x:num <- copy 1 +224 x:num <- copy 1:num/raw 225 ] 226 -error: main: mixing variable names and numeric addresses 227 $error: 0 228 -229 //:: Support element names for containers in 'get' and 'get-location' and 'put'. -230 //: (get-location is implemented later) -231 -232 :(before "End update GET offset_value in Check") -233 else { -234 if (!offset.initialized) { -235 ¦ raise << maybe(get(Recipe, r).name) << "uninitialized offset '" << offset.name << "' in '" << to_original_string(inst) << "'\n" << end(); -236 ¦ break; -237 } -238 offset_value = offset.value; -239 } -240 -241 :(scenario transform_names_transforms_container_elements) -242 def main [ -243 p:&:point <- copy 0 -244 a:num <- get *p:&:point, y:offset -245 b:num <- get *p:&:point, x:offset -246 ] -247 +name: element y of type point is at offset 1 -248 +name: element x of type point is at offset 0 -249 -250 :(before "End transform_names(inst) Special-cases") -251 // replace element names of containers with offsets -252 if (inst.name == "get" || inst.name == "get-location" || inst.name == "put") { -253 //: avoid raising any errors here; later layers will support overloading new -254 //: instructions with the same names (static dispatch), which could lead to -255 //: spurious errors -256 if (SIZE(inst.ingredients) < 2) -257 ¦ break; // error raised elsewhere -258 if (!is_literal(inst.ingredients.at(1))) -259 ¦ break; // error raised elsewhere -260 if (inst.ingredients.at(1).name.find_first_not_of("0123456789") != string::npos) { -261 ¦ // since first non-address in base type must be a container, we don't have to canonize -262 ¦ type_ordinal base_type = skip_addresses(inst.ingredients.at(0).type); -263 ¦ if (contains_key(Type, base_type)) { // otherwise we'll raise an error elsewhere -264 ¦ ¦ inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name, get(Recipe, r).name)); -265 ¦ ¦ trace(9993, "name") << "element " << inst.ingredients.at(1).name << " of type " << get(Type, base_type).name << " is at offset " << no_scientific(inst.ingredients.at(1).value) << end(); -266 ¦ } -267 } -268 } -269 -270 :(scenario missing_type_in_get) -271 % Hide_errors = true; -272 def main [ -273 get a, x:offset -274 ] -275 +error: main: missing type for 'a' in 'get a, x:offset' +229 :(scenario transform_names_does_not_fail_when_mixing_names_and_literals) +230 def main [ +231 x:num <- copy 1 +232 ] +233 -error: main: mixing variable names and numeric addresses +234 $error: 0 +235 +236 //:: Support element names for containers in 'get' and 'get-location' and 'put'. +237 //: (get-location is implemented later) +238 +239 :(before "End update GET offset_value in Check") +240 else { +241 if (!offset.initialized) { +242 ¦ raise << maybe(get(Recipe, r).name) << "uninitialized offset '" << offset.name << "' in '" << to_original_string(inst) << "'\n" << end(); +243 ¦ break; +244 } +245 offset_value = offset.value; +246 } +247 +248 :(scenario transform_names_transforms_container_elements) +249 def main [ +250 p:&:point <- copy 0 +251 a:num <- get *p:&:point, y:offset +252 b:num <- get *p:&:point, x:offset +253 ] +254 +name: element y of type point is at offset 1 +255 +name: element x of type point is at offset 0 +256 +257 :(before "End transform_names(inst) Special-cases") +258 // replace element names of containers with offsets +259 if (inst.name == "get" || inst.name == "get-location" || inst.name == "put") { +260 //: avoid raising any errors here; later layers will support overloading new +261 //: instructions with the same names (static dispatch), which could lead to +262 //: spurious errors +263 if (SIZE(inst.ingredients) < 2) +264 ¦ break; // error raised elsewhere +265 if (!is_literal(inst.ingredients.at(1))) +266 ¦ break; // error raised elsewhere +267 if (inst.ingredients.at(1).name.find_first_not_of("0123456789") != string::npos) { +268 ¦ // since first non-address in base type must be a container, we don't have to canonize +269 ¦ type_ordinal base_type = skip_addresses(inst.ingredients.at(0).type); +270 ¦ if (contains_key(Type, base_type)) { // otherwise we'll raise an error elsewhere +271 ¦ ¦ inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name, get(Recipe, r).name)); +272 ¦ ¦ trace(9993, "name") << "element " << inst.ingredients.at(1).name << " of type " << get(Type, base_type).name << " is at offset " << no_scientific(inst.ingredients.at(1).value) << end(); +273 ¦ } +274 } +275 } 276 -277 //: this test is actually illegal so can't call run -278 :(scenarios transform) -279 :(scenario transform_names_handles_containers) -280 def main [ -281 a:point <- copy 0/unsafe -282 b:num <- copy 0/unsafe -283 ] -284 +name: assign a 1 -285 +name: assign b 3 -286 -287 //:: Support variant names for exclusive containers in 'maybe-convert'. -288 -289 :(scenarios run) -290 :(scenario transform_names_handles_exclusive_containers) -291 def main [ -292 12:num <- copy 1 -293 13:num <- copy 35 -294 14:num <- copy 36 -295 20:point, 22:bool <- maybe-convert 12:number-or-point/unsafe, p:variant -296 ] -297 +name: variant p of type number-or-point has tag 1 -298 +mem: storing 1 in location 22 -299 +mem: storing 35 in location 20 -300 +mem: storing 36 in location 21 -301 -302 :(before "End transform_names(inst) Special-cases") -303 // convert variant names of exclusive containers -304 if (inst.name == "maybe-convert") { -305 if (SIZE(inst.ingredients) != 2) { -306 ¦ raise << maybe(get(Recipe, r).name) << "exactly 2 ingredients expected in '" << to_original_string(inst) << "'\n" << end(); -307 ¦ break; -308 } -309 assert(is_literal(inst.ingredients.at(1))); -310 if (inst.ingredients.at(1).name.find_first_not_of("0123456789") != string::npos) { -311 ¦ // since first non-address in base type must be an exclusive container, we don't have to canonize -312 ¦ type_ordinal base_type = skip_addresses(inst.ingredients.at(0).type); -313 ¦ if (contains_key(Type, base_type)) { // otherwise we'll raise an error elsewhere -314 ¦ ¦ inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name, get(Recipe, r).name)); -315 ¦ ¦ trace(9993, "name") << "variant " << inst.ingredients.at(1).name << " of type " << get(Type, base_type).name << " has tag " << no_scientific(inst.ingredients.at(1).value) << end(); -316 ¦ } -317 } -318 } -319 -320 :(scenario missing_type_in_maybe_convert) -321 % Hide_errors = true; -322 def main [ -323 maybe-convert a, x:variant -324 ] -325 +error: main: missing type for 'a' in 'maybe-convert a, x:variant' +277 :(scenario missing_type_in_get) +278 % Hide_errors = true; +279 def main [ +280 get a, x:offset +281 ] +282 +error: main: missing type for 'a' in 'get a, x:offset' +283 +284 //: this test is actually illegal so can't call run +285 :(scenarios transform) +286 :(scenario transform_names_handles_containers) +287 def main [ +288 a:point <- copy 0/unsafe +289 b:num <- copy 0/unsafe +290 ] +291 +name: assign a 1 +292 +name: assign b 3 +293 +294 //:: Support variant names for exclusive containers in 'maybe-convert'. +295 +296 :(scenarios run) +297 :(scenario transform_names_handles_exclusive_containers) +298 def main [ +299 12:num <- copy 1 +300 13:num <- copy 35 +301 14:num <- copy 36 +302 20:point, 22:bool <- maybe-convert 12:number-or-point/unsafe, p:variant +303 ] +304 +name: variant p of type number-or-point has tag 1 +305 +mem: storing 1 in location 22 +306 +mem: storing 35 in location 20 +307 +mem: storing 36 in location 21 +308 +309 :(before "End transform_names(inst) Special-cases") +310 // convert variant names of exclusive containers +311 if (inst.name == "maybe-convert") { +312 if (SIZE(inst.ingredients) != 2) { +313 ¦ raise << maybe(get(Recipe, r).name) << "exactly 2 ingredients expected in '" << to_original_string(inst) << "'\n" << end(); +314 ¦ break; +315 } +316 assert(is_literal(inst.ingredients.at(1))); +317 if (inst.ingredients.at(1).name.find_first_not_of("0123456789") != string::npos) { +318 ¦ // since first non-address in base type must be an exclusive container, we don't have to canonize +319 ¦ type_ordinal base_type = skip_addresses(inst.ingredients.at(0).type); +320 ¦ if (contains_key(Type, base_type)) { // otherwise we'll raise an error elsewhere +321 ¦ ¦ inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name, get(Recipe, r).name)); +322 ¦ ¦ trace(9993, "name") << "variant " << inst.ingredients.at(1).name << " of type " << get(Type, base_type).name << " has tag " << no_scientific(inst.ingredients.at(1).value) << end(); +323 ¦ } +324 } +325 } +326 +327 :(scenario missing_type_in_maybe_convert) +328 % Hide_errors = true; +329 def main [ +330 maybe-convert a, x:variant +331 ] +332 +error: main: missing type for 'a' in 'maybe-convert a, x:variant' -- cgit 1.4.1-2-gfad0