From b2757892d553352feb59d70b1e7241ccdafa6905 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Mon, 25 May 2015 20:33:37 -0700 Subject: 1458 While pushing out color support in fake screens I realized I've been complecting the special-case of a special-case to transform literal-string arguments for 'new'. As a result I hadn't been catching bad habits like giving its arg the wrong type. Now we have cleaner separation of the two variants of 'new', a few more checks, and better error messages when we mis-call it. Aside: I've added a third goto target. Sliding into spaghetti? Keep an eye on it. This goto might become a common pattern: a layer hooking into a previous one to prevent it from happening. In this case new on literal-strings prevents the transform for new from triggering. --- 042new.cc | 21 +++++++++++++++++---- 045closure_name.cc | 2 +- 071print.mu | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/042new.cc b/042new.cc index d297196b..d476a5c5 100644 --- a/042new.cc +++ b/042new.cc @@ -32,14 +32,18 @@ Type_number["type"] = 0; :(after "Per-recipe Transforms") // replace type names with type_numbers if (inst.operation == Recipe_number["new"]) { + // End NEW Transform Special-cases // first arg must be of type 'type' assert(SIZE(inst.ingredients) >= 1); -//? cout << inst.ingredients.at(0).to_string() << '\n'; //? 1 assert(isa_literal(inst.ingredients.at(0))); - if (inst.ingredients.at(0).properties.at(0).second.at(0) == "type") { - inst.ingredients.at(0).set_value(Type_number[inst.ingredients.at(0).name]); - } + if (inst.ingredients.at(0).properties.at(0).second.at(0) != "type") + raise << "tried to allocate non-type " << inst.ingredients.at(0).to_string() << " in recipe " << Recipe[r].name << '\n' << die(); + if (Type_number.find(inst.ingredients.at(0).name) == Type_number.end()) + raise << "unknown type " << inst.ingredients.at(0).name << " in recipe " << Recipe[r].name << '\n' << die(); +//? cerr << "type " << inst.ingredients.at(0).name << " => " << Type_number[inst.ingredients.at(0).name] << '\n'; //? 1 + inst.ingredients.at(0).set_value(Type_number[inst.ingredients.at(0).name]); trace(Primitive_recipe_depth, "new") << inst.ingredients.at(0).name << " -> " << inst.ingredients.at(0).value; + end_new_transform:; } //:: Now implement the primitive recipe. @@ -58,6 +62,7 @@ case NEW: { vector type; assert(isa_literal(current_instruction().ingredients.at(0))); type.push_back(current_instruction().ingredients.at(0).value); +//? trace(Primitive_recipe_depth, "mem") << "type " << current_instruction().ingredients.at(0).to_string() << ' ' << type.size() << ' ' << type.back() << " has size " << size_of(type); //? 1 if (SIZE(current_instruction().ingredients) > 1) { // array array_length = ingredients.at(1).at(0); @@ -74,6 +79,7 @@ case NEW: { ensure_space(size); const long long int result = Current_routine->alloc; trace(Primitive_recipe_depth, "mem") << "new alloc: " << result; +//? trace(Primitive_recipe_depth, "mem") << "size: " << size << " locations"; //? 1 // save result products.resize(1); products.at(0).push_back(result); @@ -163,6 +169,13 @@ recipe main [ # number code for 'e' +mem: storing 101 in location 2 +:(before "End NEW Transform Special-cases") + if (inst.ingredients.at(0).properties.at(0).second.at(0) == "literal-string") { + // skip transform + inst.ingredients.at(0).initialized = true; + goto end_new_transform; + } + :(after "case NEW" following "Primitive Recipe Implementations") if (isa_literal(current_instruction().ingredients.at(0)) && current_instruction().ingredients.at(0).properties.at(0).second.at(0) == "literal-string") { diff --git a/045closure_name.cc b/045closure_name.cc index 237eee3c..66696fc6 100644 --- a/045closure_name.cc +++ b/045closure_name.cc @@ -21,7 +21,7 @@ recipe init-counter [ ] recipe increment-counter [ - default-space:address:array:location <- new space:literal, 30:literal + default-space:address:array:location <- new location:type, 30:literal 0:address:array:location/names:init-counter <- next-ingredient # outer space must be created by 'init-counter' above y:number/space:1 <- add y:number/space:1, 1:literal # increment y:number <- copy 234:literal # dummy diff --git a/071print.mu b/071print.mu index 2c7250ba..d4d84bb2 100644 --- a/071print.mu +++ b/071print.mu @@ -22,7 +22,7 @@ recipe init-fake-screen [ column:address:number/deref <- copy 0:literal bufsize:number <- multiply width:address:number/deref, height:address:number/deref buf:address:address:array:character <- get-address result:address:screen/deref, data:offset - buf:address:address:array:character/deref <- new character:literal, bufsize:number + buf:address:address:array:character/deref <- new character:type, bufsize:number clear-screen result:address:screen reply result:address:screen ] -- cgit 1.4.1-2-gfad0