about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2018-02-20 01:11:22 -0800
committerKartik K. Agaram <vc@akkartik.com>2018-02-20 01:11:22 -0800
commitcd1113882450382ebe39db7dd8690812bac1aba7 (patch)
treee730c681d5b51d88624987f6975af16b7f88c67c
parent94ffc3776c8037416e4834eb5b94644587c18e10 (diff)
downloadmu-cd1113882450382ebe39db7dd8690812bac1aba7.tar.gz
4210 - a better error
Thanks Ella Couch.
-rw-r--r--026call.cc8
-rw-r--r--035lookup.cc31
2 files changed, 32 insertions, 7 deletions
diff --git a/026call.cc b/026call.cc
index 3ae636b8..c6077cd9 100644
--- a/026call.cc
+++ b/026call.cc
@@ -133,6 +133,14 @@ routine::routine(recipe_ordinal r) {
 //?   return get(Recipe, call.running_recipe).steps.at(call.running_step_index);
 //? }
 
+:(code)
+void dump_callstack() {
+  if (!Current_routine) return;
+  if (Current_routine->calls.size() <= 1) return;
+  for (call_stack::const_iterator p = ++Current_routine->calls.begin();  p != Current_routine->calls.end();  ++p)
+    raise << "  called from " << get(Recipe, p->running_recipe).name << ": " << to_original_string(to_instruction(*p)) << '\n' << end();
+}
+
 :(after "Defined Recipe Checks")
 // not a primitive; check that it's present in the book of recipes
 if (!contains_key(Recipe, inst.operation)) {
diff --git a/035lookup.cc b/035lookup.cc
index c72a2938..557dd936 100644
--- a/035lookup.cc
+++ b/035lookup.cc
@@ -44,7 +44,19 @@ def main [
   1:address:num <- copy 0
   2:num <- copy 1:address:num/lookup
 ]
-+error: main: tried to /lookup 0 in '2:num <- copy 1:address:num/lookup'
++error: main: tried to lookup 0 in '2:num <- copy 1:address:num/lookup'
+
+:(scenario lookup_0_dumps_callstack)
+% Hide_errors = true;
+def main [
+  foo 0
+]
+def foo [
+  1:address:num <- next-input
+  2:num <- copy 1:address:num/lookup
+]
++error: foo: tried to lookup 0 in '2:num <- copy 1:address:num/lookup'
++error:   called from main: foo 0
 
 :(code)
 void canonize(reagent& x) {
@@ -56,12 +68,14 @@ void canonize(reagent& x) {
 
 void lookup_memory(reagent& x) {
   if (!x.type || x.type->atom || x.type->left->value != get(Type_ordinal, "address")) {
-    raise << maybe(current_recipe_name()) << "tried to /lookup '" << x.original_string << "' but it isn't an address\n" << end();
+    raise << maybe(current_recipe_name()) << "tried to lookup '" << x.original_string << "' but it isn't an address\n" << end();
+    dump_callstack();
     return;
   }
   // compute value
   if (x.value == 0) {
-    raise << maybe(current_recipe_name()) << "tried to /lookup 0\n" << end();
+    raise << maybe(current_recipe_name()) << "tried to lookup 0\n" << end();
+    dump_callstack();
     return;
   }
   lookup_memory_core(x, /*check_for_null*/true);
@@ -73,10 +87,13 @@ void lookup_memory_core(reagent& x, bool check_for_null) {
   x.set_value(get_or_insert(Memory, x.value));
   drop_from_type(x, "address");
   if (check_for_null && x.value == 0) {
-    if (Current_routine)
-      raise << maybe(current_recipe_name()) << "tried to /lookup 0 in '" << to_original_string(current_instruction()) << "'\n" << end();
-    else
-      raise << "tried to /lookup 0\n" << end();
+    if (Current_routine) {
+      raise << maybe(current_recipe_name()) << "tried to lookup 0 in '" << to_original_string(current_instruction()) << "'\n" << end();
+      dump_callstack();
+    }
+    else {
+      raise << "tried to lookup 0\n" << end();
+    }
   }
   drop_one_lookup(x);
 }