From b74744cd5851e034a88d4a335b22a372ebb39237 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 30 Aug 2017 03:07:18 -0700 Subject: 3985 --- 071recipe.cc | 4 +- html/071recipe.cc.html | 232 ++++++++++++++++++++++++------------------------- 2 files changed, 116 insertions(+), 120 deletions(-) diff --git a/071recipe.cc b/071recipe.cc index 9d77869d..a3a258c7 100644 --- a/071recipe.cc +++ b/071recipe.cc @@ -277,9 +277,7 @@ bool is_mu_recipe(const reagent& r) { if (!r.type) return false; if (r.type->atom) return r.type->name == "recipe-literal"; - if (!r.type->left->atom) return false; - if (r.type->left->name == "recipe") return true; - return false; + return r.type->left->atom && r.type->left->name == "recipe"; } :(scenario copy_typecheck_recipe_variable) diff --git a/html/071recipe.cc.html b/html/071recipe.cc.html index 4765419f..fec9a6f7 100644 --- a/html/071recipe.cc.html +++ b/html/071recipe.cc.html @@ -17,9 +17,9 @@ a:hover { text-decoration: underline; } * { font-size: 12pt; font-size: 1em; } .Constant { color: #00a0a0; } .muRecipe { color: #ff8700; } +.Special { color: #c00000; } .Conceal { color: #4e4e4e; } .SalientComment { color: #00ffff; } -.Special { color: #c00000; } .Comment { color: #9090ff; } .Comment a { color:#0000ee; text-decoration:underline; } .Delimiter { color: #800080; } @@ -341,122 +341,120 @@ if ('onhashchange' in window) { 277 if (!r.type) return false; 278 if (r.type->atom) 279 ¦ return r.type->name == "recipe-literal"; -280 if (!r.type->left->atom) return false; -281 if (r.type->left->name == "recipe") return true; -282 return false; -283 } -284 -285 :(scenario copy_typecheck_recipe_variable) -286 % Hide_errors = true; -287 def main [ -288 3:num <- copy 34 # abc def -289 {1: (recipe number -> number)} <- copy f # store literal in a matching variable -290 {2: (recipe boolean -> boolean)} <- copy {1: (recipe number -> number)} # mismatch between recipe variables -291 ] -292 def f x:num -> y:num [ -293 local-scope -294 load-ingredients -295 y <- copy x -296 ] -297 +error: main: can't copy '{1: (recipe number -> number)}' to '{2: (recipe boolean -> boolean)}'; types don't match -298 -299 :(scenario copy_typecheck_recipe_variable_2) -300 % Hide_errors = true; -301 def main [ -302 {1: (recipe number -> number)} <- copy f # mismatch with a recipe literal -303 ] -304 def f x:bool -> y:bool [ -305 local-scope -306 load-ingredients -307 y <- copy x -308 ] -309 +error: main: can't copy 'f' to '{1: (recipe number -> number)}'; types don't match -310 -311 :(before "End Matching Types For Literal(to)") -312 if (is_mu_recipe(to)) { -313 if (!contains_key(Recipe, from.value)) { -314 ¦ raise << "trying to store recipe " << from.name << " into " << to_string(to) << " but there's no such recipe\n" << end(); -315 ¦ return false; -316 } -317 const recipe& rrhs = get(Recipe, from.value); -318 const recipe& rlhs = from_reagent(to); -319 for (long int i = 0; i < min(SIZE(rlhs.ingredients), SIZE(rrhs.ingredients)); ++i) { -320 ¦ if (!types_match(rlhs.ingredients.at(i), rrhs.ingredients.at(i))) -321 ¦ ¦ return false; -322 } -323 for (long int i = 0; i < min(SIZE(rlhs.products), SIZE(rrhs.products)); ++i) { -324 ¦ if (!types_match(rlhs.products.at(i), rrhs.products.at(i))) -325 ¦ ¦ return false; -326 } -327 return true; -328 } -329 -330 :(scenario call_variable_compound_ingredient) -331 def main [ -332 {1: (recipe (address number) -> number)} <- copy f -333 2:&:num <- copy 0 -334 3:num <- call {1: (recipe (address number) -> number)}, 2:&:num -335 ] -336 def f x:&:num -> y:num [ -337 local-scope -338 load-ingredients -339 y <- copy x -340 ] -341 $error: 0 -342 -343 //: make sure we don't accidentally break on a function literal -344 :(scenario jump_forbidden_on_recipe_literals) -345 % Hide_errors = true; -346 def foo [ -347 local-scope -348 ] -349 def main [ -350 local-scope -351 { -352 ¦ break-if foo -353 } -354 ] -355 # error should be as if foo is not a recipe -356 +error: main: missing type for 'foo' in 'break-if foo' -357 -358 :(before "End JUMP_IF Checks") -359 check_for_recipe_literals(inst, get(Recipe, r)); -360 :(before "End JUMP_UNLESS Checks") -361 check_for_recipe_literals(inst, get(Recipe, r)); -362 :(code) -363 void check_for_recipe_literals(const instruction& inst, const recipe& caller) { -364 for (int i = 0; i < SIZE(inst.ingredients); ++i) { -365 ¦ if (is_mu_recipe(inst.ingredients.at(i))) { -366 ¦ ¦ raise << maybe(caller.name) << "missing type for '" << inst.ingredients.at(i).original_string << "' in '" << to_original_string(inst) << "'\n" << end(); -367 ¦ ¦ if (is_present_in_ingredients(caller, inst.ingredients.at(i).name)) -368 ¦ ¦ ¦ raise << " did you forget 'load-ingredients'?\n" << end(); -369 ¦ } -370 } -371 } -372 -373 :(scenario load_ingredients_missing_error_3) -374 % Hide_errors = true; -375 def foo {f: (recipe num -> num)} [ -376 local-scope -377 b:num <- call f, 1 -378 ] -379 +error: foo: missing type for 'f' in 'b:num <- call f, 1' -380 +error: did you forget 'load-ingredients'? -381 -382 :(before "End Mu Types Initialization") -383 put(Type_abbreviations, "function", new_type_tree("recipe")); -384 -385 :(scenario call_function) -386 def main [ -387 {1: (function number -> number)} <- copy f -388 2:num <- call {1: (function number -> number)}, 34 -389 ] -390 def f x:num -> y:num [ -391 local-scope -392 load-ingredients -393 y <- copy x -394 ] -395 +mem: storing 34 in location 2 +280 return r.type->left->atom && r.type->left->name == "recipe"; +281 } +282 +283 :(scenario copy_typecheck_recipe_variable) +284 % Hide_errors = true; +285 def main [ +286 3:num <- copy 34 # abc def +287 {1: (recipe number -> number)} <- copy f # store literal in a matching variable +288 {2: (recipe boolean -> boolean)} <- copy {1: (recipe number -> number)} # mismatch between recipe variables +289 ] +290 def f x:num -> y:num [ +291 local-scope +292 load-ingredients +293 y <- copy x +294 ] +295 +error: main: can't copy '{1: (recipe number -> number)}' to '{2: (recipe boolean -> boolean)}'; types don't match +296 +297 :(scenario copy_typecheck_recipe_variable_2) +298 % Hide_errors = true; +299 def main [ +300 {1: (recipe number -> number)} <- copy f # mismatch with a recipe literal +301 ] +302 def f x:bool -> y:bool [ +303 local-scope +304 load-ingredients +305 y <- copy x +306 ] +307 +error: main: can't copy 'f' to '{1: (recipe number -> number)}'; types don't match +308 +309 :(before "End Matching Types For Literal(to)") +310 if (is_mu_recipe(to)) { +311 if (!contains_key(Recipe, from.value)) { +312 ¦ raise << "trying to store recipe " << from.name << " into " << to_string(to) << " but there's no such recipe\n" << end(); +313 ¦ return false; +314 } +315 const recipe& rrhs = get(Recipe, from.value); +316 const recipe& rlhs = from_reagent(to); +317 for (long int i = 0; i < min(SIZE(rlhs.ingredients), SIZE(rrhs.ingredients)); ++i) { +318 ¦ if (!types_match(rlhs.ingredients.at(i), rrhs.ingredients.at(i))) +319 ¦ ¦ return false; +320 } +321 for (long int i = 0; i < min(SIZE(rlhs.products), SIZE(rrhs.products)); ++i) { +322 ¦ if (!types_match(rlhs.products.at(i), rrhs.products.at(i))) +323 ¦ ¦ return false; +324 } +325 return true; +326 } +327 +328 :(scenario call_variable_compound_ingredient) +329 def main [ +330 {1: (recipe (address number) -> number)} <- copy f +331 2:&:num <- copy 0 +332 3:num <- call {1: (recipe (address number) -> number)}, 2:&:num +333 ] +334 def f x:&:num -> y:num [ +335 local-scope +336 load-ingredients +337 y <- copy x +338 ] +339 $error: 0 +340 +341 //: make sure we don't accidentally break on a function literal +342 :(scenario jump_forbidden_on_recipe_literals) +343 % Hide_errors = true; +344 def foo [ +345 local-scope +346 ] +347 def main [ +348 local-scope +349 { +350 ¦ break-if foo +351 } +352 ] +353 # error should be as if foo is not a recipe +354 +error: main: missing type for 'foo' in 'break-if foo' +355 +356 :(before "End JUMP_IF Checks") +357 check_for_recipe_literals(inst, get(Recipe, r)); +358 :(before "End JUMP_UNLESS Checks") +359 check_for_recipe_literals(inst, get(Recipe, r)); +360 :(code) +361 void check_for_recipe_literals(const instruction& inst, const recipe& caller) { +362 for (int i = 0; i < SIZE(inst.ingredients); ++i) { +363 ¦ if (is_mu_recipe(inst.ingredients.at(i))) { +364 ¦ ¦ raise << maybe(caller.name) << "missing type for '" << inst.ingredients.at(i).original_string << "' in '" << to_original_string(inst) << "'\n" << end(); +365 ¦ ¦ if (is_present_in_ingredients(caller, inst.ingredients.at(i).name)) +366 ¦ ¦ ¦ raise << " did you forget 'load-ingredients'?\n" << end(); +367 ¦ } +368 } +369 } +370 +371 :(scenario load_ingredients_missing_error_3) +372 % Hide_errors = true; +373 def foo {f: (recipe num -> num)} [ +374 local-scope +375 b:num <- call f, 1 +376 ] +377 +error: foo: missing type for 'f' in 'b:num <- call f, 1' +378 +error: did you forget 'load-ingredients'? +379 +380 :(before "End Mu Types Initialization") +381 put(Type_abbreviations, "function", new_type_tree("recipe")); +382 +383 :(scenario call_function) +384 def main [ +385 {1: (function number -> number)} <- copy f +386 2:num <- call {1: (function number -> number)}, 34 +387 ] +388 def f x:num -> y:num [ +389 local-scope +390 load-ingredients +391 y <- copy x +392 ] +393 +mem: storing 34 in location 2 -- cgit 1.4.1-2-gfad0