about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-02-06 16:47:10 -0800
committerKartik K. Agaram <vc@akkartik.com>2016-02-07 02:16:37 -0800
commit715806ca3198fdb5d222bf5eb158d8690b0a1e1f (patch)
tree45a9edf010aecdcb90a8052f7e307a8f12a47120
parent8b3b97e848a3db3c8542c86c7c03fd65f38865a3 (diff)
downloadmu-715806ca3198fdb5d222bf5eb158d8690b0a1e1f.tar.gz
2637 - save type names for container elements
-rw-r--r--010vm.cc4
-rw-r--r--030container.cc44
-rw-r--r--058shape_shifting_container.cc8
3 files changed, 36 insertions, 20 deletions
diff --git a/010vm.cc b/010vm.cc
index 6fb897d0..758d8d26 100644
--- a/010vm.cc
+++ b/010vm.cc
@@ -148,8 +148,10 @@ void setup_types() {
 }
 void teardown_types() {
   for (map<type_ordinal, type_info>::iterator p = Type.begin(); p != Type.end(); ++p) {
-    for (long long int i = 0; i < SIZE(p->second.elements); ++i)
+    for (long long int i = 0; i < SIZE(p->second.elements); ++i) {
       delete p->second.elements.at(i);
+      delete p->second.element_type_names.at(i);
+    }
   }
   Type_ordinal.clear();
 }
diff --git a/030container.cc b/030container.cc
index c8b2134f..9cbb5c69 100644
--- a/030container.cc
+++ b/030container.cc
@@ -203,7 +203,10 @@ const reagent element_type(const reagent& canonized_base, long long int offset_v
   const type_info& info = get(Type, canonized_base.type->value);
   assert(info.kind == CONTAINER);
   reagent element;
+  element.name = info.element_names.at(offset_value);
   element.type = new type_tree(*info.elements.at(offset_value));
+  element.properties.resize(1);
+  element.properties.at(0).second = new string_tree(*info.element_type_names.at(offset_value));
   // End element_type Special-cases
   return element;
 }
@@ -426,28 +429,40 @@ 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;
-    // End insert_container Special Definitions(element)
     istringstream inner(element);
     info.element_names.push_back(slurp_until(inner, ':'));
     trace(9993, "parse") << "  element name: " << info.element_names.back() << end();
-    type_tree* new_type = NULL;
-    for (type_tree** curr_type = &new_type; has_data(inner); curr_type = &(*curr_type)->right) {
-      string type_name = slurp_until(inner, ':');
-      // End insert_container Special Uses(type_name)
-      if (!contains_key(Type_ordinal, type_name)
-          // types can contain integers, like for array sizes
-          && !is_integer(type_name)) {
-        put(Type_ordinal, type_name, Next_type_ordinal++);
-      }
-      *curr_type = new type_tree(get(Type_ordinal, type_name));
-      trace(9993, "parse") << "  type: " << get(Type_ordinal, type_name) << end();
-    }
-    info.elements.push_back(new_type);
+    info.element_type_names.push_back(parse_property_list(inner));
+    info.elements.push_back(new_type_tree_with_new_types_for_unknown(info.element_type_names.back(), info));
+    for (long long int i = 0; i < SIZE(info.elements); ++i)
+      trace(9993, "parse") << "  type: " << info.elements.at(i)->value << end();
   }
   assert(SIZE(info.elements) == SIZE(info.element_names));
   info.size = SIZE(info.elements);
 }
 
+type_tree* new_type_tree_with_new_types_for_unknown(const string_tree* properties, const type_info& info) {
+  if (!properties) return NULL;
+  type_tree* result = new type_tree(0);
+  if (!properties->value.empty()) {
+    const string& type_name = properties->value;
+    if (contains_key(Type_ordinal, type_name)) {
+      result->value = get(Type_ordinal, type_name);
+    }
+    else if (is_integer(type_name)) {  // sometimes types will contain non-type tags, like numbers for the size of an array
+      result->value = 0;
+    }
+    // End insert_container Special-cases
+    else if (properties->value != "->") {  // used in recipe types
+      put(Type_ordinal, type_name, Next_type_ordinal++);
+      result->value = get(Type_ordinal, type_name);
+    }
+  }
+  result->left = new_type_tree_with_new_types_for_unknown(properties->left, info);
+  result->right = new_type_tree_with_new_types_for_unknown(properties->right, info);
+  return result;
+}
+
 void skip_bracket(istream& in, string message) {
   skip_whitespace_and_comments(in);
   if (in.get() != '[')
@@ -485,6 +500,7 @@ for (long long int i = 0; i < SIZE(Recently_added_types); ++i) {
   // todo: why do I explicitly need to provide this?
   for (long long int j = 0; j < SIZE(Type.at(Recently_added_types.at(i)).elements); ++j) {
     delete Type.at(Recently_added_types.at(i)).elements.at(j);
+    delete Type.at(Recently_added_types.at(i)).element_type_names.at(j);
   }
   Type.erase(Recently_added_types.at(i));
 }
diff --git a/058shape_shifting_container.cc b/058shape_shifting_container.cc
index 6416aca1..c9975b44 100644
--- a/058shape_shifting_container.cc
+++ b/058shape_shifting_container.cc
@@ -59,12 +59,10 @@ void read_type_ingredients(string& name) {
   }
 }
 
-:(before "End insert_container Special Uses(type_name)")
+:(before "End insert_container Special-cases")
 // check for use of type ingredients
-if (type_name.at(0) == '_') {
-  *curr_type = new type_tree(get(info.type_ingredient_names, type_name));
-  trace(9999, "parse") << "  type: " << get(info.type_ingredient_names, type_name) << end();
-  continue;
+else if (!properties->value.empty() && properties->value.at(0) == '_') {
+  result->value = get(info.type_ingredient_names, properties->value);
 }
 
 :(before "End Container Type Checks")