about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--013update_operation.cc10
-rw-r--r--057static_dispatch.cc21
-rw-r--r--059shape_shifting_recipe.cc12
-rw-r--r--edit/003-shortcuts.mu14
4 files changed, 47 insertions, 10 deletions
diff --git a/013update_operation.cc b/013update_operation.cc
index c02a24c5..63f4586e 100644
--- a/013update_operation.cc
+++ b/013update_operation.cc
@@ -7,15 +7,17 @@ Transform.push_back(update_instruction_operations);  // idempotent
 :(code)
 void update_instruction_operations(recipe_ordinal r) {
   trace(9991, "transform") << "--- compute instruction operations for recipe " << get(Recipe, r).name << end();
-//?   cerr << "--- compute instruction operations for recipe " << get(Recipe, r).name << '\n';
-  for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) {
-    instruction& inst = get(Recipe, r).steps.at(index);
+  recipe& caller = get(Recipe, r);
+//?   cerr << "--- compute instruction operations for recipe " << caller.name << '\n';
+  for (long long int index = 0; index < SIZE(caller.steps); ++index) {
+    instruction& inst = caller.steps.at(index);
     if (inst.is_label) continue;
     if (!contains_key(Recipe_ordinal, inst.name)) {
-      raise_error << maybe(get(Recipe, r).name) << "instruction " << inst.name << " has no recipe\n" << end();
+      raise_error << maybe(caller.name) << "instruction " << inst.name << " has no recipe\n" << end();
       return;
     }
     inst.operation = get(Recipe_ordinal, inst.name);
+    // End Instruction Operation Checks
   }
 }
 
diff --git a/057static_dispatch.cc b/057static_dispatch.cc
index 2d9af3d7..2aae9153 100644
--- a/057static_dispatch.cc
+++ b/057static_dispatch.cc
@@ -153,6 +153,9 @@ void replace_best_variant(instruction& inst, const recipe& caller_recipe) {
     }
   }
   // End Instruction Dispatch(inst, best_score)
+  if (best_score == -1 && get(Recipe_ordinal, inst.name) >= MAX_PRIMITIVE_RECIPES) {
+    raise_error << maybe(caller_recipe.name) << "failed to find a matching call for '" << inst.to_string() << "'\n" << end();
+  }
 }
 
 long long int variant_score(const instruction& inst, recipe_ordinal variant) {
@@ -200,6 +203,7 @@ long long int variant_score(const instruction& inst, recipe_ordinal variant) {
   }
   const vector<reagent>& header_products = get(Recipe, variant).products;
   for (long long int i = 0; i < SIZE(inst.products); ++i) {
+    if (is_dummy(inst.products.at(i))) continue;
     if (!types_match(header_products.at(i), inst.products.at(i))) {
       trace(9993, "transform") << "mismatch: product " << i << end();
 //?       cerr << "mismatch: product " << i << '\n';
@@ -267,6 +271,23 @@ recipe equal x:number, y:number -> z:boolean [
 # comparing booleans continues to use primitive
 +mem: storing 1 in location 6
 
+:(scenario static_dispatch_works_with_dummy_results_for_containers)
+% Hide_errors = true;
+recipe main [
+  _ <- test 3, 4
+]
+recipe test a:number -> z:point [
+  local-scope
+  load-ingredients
+  z <- merge a, 0
+]
+recipe test a:number, b:number -> z:point [
+  local-scope
+  load-ingredients
+  z <- merge a, b
+]
+$error: 0
+
 :(scenario static_dispatch_prefers_literals_to_be_numbers_rather_than_addresses)
 recipe main [
   1:number <- foo 0
diff --git a/059shape_shifting_recipe.cc b/059shape_shifting_recipe.cc
index 774230a2..04c72af8 100644
--- a/059shape_shifting_recipe.cc
+++ b/059shape_shifting_recipe.cc
@@ -72,6 +72,7 @@ if (best_score == -1) {
 //?   cerr << "no variant found for " << inst.name << "; searching for variant with suitable type ingredients" << '\n';
   recipe_ordinal exemplar = pick_matching_shape_shifting_variant(variants, inst, best_score);
   if (exemplar) {
+//?     cerr << "specializing " << inst.name << '\n';
     trace(9992, "transform") << "found variant to specialize: " << exemplar << ' ' << get(Recipe, exemplar).name << end();
 //?     cerr << "found variant to specialize: " << exemplar << ' ' << get(Recipe, exemplar).name << '\n';
     recipe_ordinal new_recipe_ordinal = new_variant(exemplar, inst, caller_recipe);
@@ -91,6 +92,16 @@ if (best_score == -1) {
   }
 }
 
+//: make sure we have no unspecialized shape-shifting recipes being called
+//: before running mu programs
+
+:(before "End Instruction Operation Checks")
+if (contains_key(Recipe, inst.operation)
+    && any_type_ingredient_in_header(inst.operation)) {
+  raise_error << maybe(caller.name) << "instruction " << inst.name << " has no valid specialization\n" << end();
+  return;
+}
+
 :(code)
 recipe_ordinal pick_matching_shape_shifting_variant(vector<recipe_ordinal>& variants, const instruction& inst, long long int& best_score) {
 //?   cerr << "---- " << inst.name << ": " << non_ghost_size(variants) << '\n';
@@ -138,6 +149,7 @@ long long int shape_shifting_variant_score(const instruction& inst, recipe_ordin
   }
   const vector<reagent>& header_products = get(Recipe, variant).products;
   for (long long int i = 0; i < SIZE(inst.products); ++i) {
+    if (is_dummy(inst.products.at(i))) continue;
     if (!deeply_equal_concrete_types(header_products.at(i), inst.products.at(i))) {
       trace(9993, "transform") << "mismatch: product " << i << end();
 //?       cerr << "mismatch: product " << i << '\n';
diff --git a/edit/003-shortcuts.mu b/edit/003-shortcuts.mu
index b3676efb..79d53b2a 100644
--- a/edit/003-shortcuts.mu
+++ b/edit/003-shortcuts.mu
@@ -84,6 +84,7 @@ recipe delete-before-cursor editor:address:editor-data, screen:address:screen ->
   local-scope
   load-ingredients
   before-cursor:address:address:duplex-list:character <- get-address *editor, before-cursor:offset
+  data:address:duplex-list:character <- get *editor, data:offset
   # if at start of text (before-cursor at § sentinel), return
   prev:address:duplex-list:character <- prev *before-cursor
   go-render?, backspaced-cell <- copy 0/no-more-render, 0/nothing-deleted
@@ -92,7 +93,7 @@ recipe delete-before-cursor editor:address:editor-data, screen:address:screen ->
   original-row:number <- get *editor, cursor-row:offset
   editor, scroll?:boolean <- move-cursor-coordinates-left editor
   backspaced-cell:address:duplex-list:character <- copy *before-cursor
-  remove *before-cursor  # will also neatly trim next/prev pointers in backspaced-cell/*before-cursor
+  data <- remove *before-cursor, data  # will also neatly trim next/prev pointers in backspaced-cell/*before-cursor
   *before-cursor <- copy prev
   go-render? <- copy 1/true
   reply-if scroll?
@@ -333,11 +334,12 @@ recipe delete-at-cursor editor:address:editor-data, screen:address:screen -> edi
   local-scope
   load-ingredients
   before-cursor:address:address:duplex-list:character <- get-address *editor, before-cursor:offset
+  data:address:duplex-list:character <- get *editor, data:offset
   deleted-cell:address:duplex-list:character <- next *before-cursor
   go-render? <- copy 0/false
   reply-unless deleted-cell
   currc:character <- get *deleted-cell, value:offset
-  remove deleted-cell
+  data <- remove deleted-cell, data
   deleted-newline?:boolean <- equal currc, 10/newline
   go-render? <- copy 1/true
   reply-if deleted-newline?
@@ -1244,7 +1246,7 @@ after <handle-special-key> [
   }
 ]
 
-recipe move-to-start-of-line editor:address:editor-data [
+recipe move-to-start-of-line editor:address:editor-data -> editor:address:editor-data [
   local-scope
   load-ingredients
   # update cursor column
@@ -1415,7 +1417,7 @@ after <handle-special-key> [
   }
 ]
 
-recipe move-to-end-of-line editor:address:editor-data [
+recipe move-to-end-of-line editor:address:editor-data -> editor:address:editor-data [
   local-scope
   load-ingredients
   before-cursor:address:address:duplex-list:character <- get-address *editor, before-cursor:offset
@@ -1545,7 +1547,7 @@ after <handle-special-character> [
   }
 ]
 
-recipe delete-to-start-of-line editor:address:editor-data -> result:address:duplex-list:character [
+recipe delete-to-start-of-line editor:address:editor-data -> result:address:duplex-list:character, editor:address:editor-data [
   local-scope
   load-ingredients
   # compute range to delete
@@ -1679,7 +1681,7 @@ after <handle-special-character> [
   }
 ]
 
-recipe delete-to-end-of-line editor:address:editor-data -> result:address:duplex-list:character [
+recipe delete-to-end-of-line editor:address:editor-data -> result:address:duplex-list:character, editor:address:editor-data [
   local-scope
   load-ingredients
   # compute range to delete