about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-06-17 17:22:15 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-06-17 17:22:15 -0700
commit5c0e5492e9d067f9a535186e00c083be328d4d1b (patch)
tree8afaf347f4aa9dc70f516b72294d6aac79b35673
parent3c163ef7bd53a0bd22e3376a5472622633b88107 (diff)
downloadmu-5c0e5492e9d067f9a535186e00c083be328d4d1b.tar.gz
3061
-rw-r--r--030container.cc19
-rw-r--r--031merge.cc1
-rw-r--r--032array.cc1
3 files changed, 20 insertions, 1 deletions
diff --git a/030container.cc b/030container.cc
index e2cd857e..14964a14 100644
--- a/030container.cc
+++ b/030container.cc
@@ -327,6 +327,7 @@ const reagent element_type(const type_tree* type, int offset_value) {
   assert(!get(Type, type->value).name.empty());
   const type_info& info = get(Type, type->value);
   assert(info.kind == CONTAINER);
+  if (offset_value >= SIZE(info.elements)) return reagent();  // error handled elsewhere
   reagent/*copy*/ element = info.elements.at(offset_value);
   // End element_type Special-cases
   return element;
@@ -550,7 +551,7 @@ void insert_container(const string& command, kind_of_type kind, istream& in) {
     put(Type_ordinal, name, Next_type_ordinal++);
   }
   trace(9999, "parse") << "type number: " << get(Type_ordinal, name) << end();
-  skip_bracket(in, "'container' must begin with '['");
+  skip_bracket(in, "'"+command+"' must begin with '['");
   type_info& info = get_or_insert(Type, get(Type_ordinal, name));
   if (info.Num_calls_to_transform_all_at_first_definition == -1) {
     // initial definition of this container
@@ -567,6 +568,15 @@ void insert_container(const string& command, kind_of_type kind, istream& in) {
     skip_whitespace_and_comments(in);
     string element = next_word(in);
     if (element == "]") break;
+    if (in.peek() != '\n') {
+      raise << command << " '" << name << "' contains multiple elements on a single line. Containers and exclusive containers must only contain elements, one to a line, no code.\n" << end();
+      // skip rest of container declaration
+      while (has_data(in)) {
+        skip_whitespace_and_comments(in);
+        if (next_word(in) == "]") break;
+      }
+      break;
+    }
     info.elements.push_back(reagent(element));
     replace_unknown_types_with_unique_ordinals(info.elements.back().type, info);
     trace(9993, "parse") << "  element: " << to_string(info.elements.back()) << end();
@@ -599,6 +609,13 @@ void skip_bracket(istream& in, string message) {
     raise << message << '\n' << end();
 }
 
+:(scenario multi_word_line_in_container_declaration)
+% Hide_errors = true;
+container foo [
+  x:number y:number
+]
++error: container 'foo' contains multiple elements on a single line. Containers and exclusive containers must only contain elements, one to a line, no code.
+
 //: ensure scenarios are consistent by always starting them at the same type
 //: number.
 :(before "End Setup")  //: for tests
diff --git a/031merge.cc b/031merge.cc
index c6e08027..034a62da 100644
--- a/031merge.cc
+++ b/031merge.cc
@@ -151,6 +151,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
       return;
     }
     reagent& container = state.data.top().container;
+    if (!container.type) return;  // error handled elsewhere
     type_info& container_info = get(Type, container.type->value);
     switch (container_info.kind) {
       case CONTAINER: {
diff --git a/032array.cc b/032array.cc
index 6e583e6d..0f8ea6fe 100644
--- a/032array.cc
+++ b/032array.cc
@@ -141,6 +141,7 @@ container foo [
 }
 
 :(scenario code_inside_container)
+% Hide_errors = true;
 container card [
   rank:number <- next-ingredient
 ]