From ae256ea13efc77cc767a658c6f61b12cd7461e21 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Mon, 26 Oct 2015 20:00:38 -0700 Subject: 2283 - represent each /property as a tree --- 010vm.cc | 143 ++++++++++++++++++++++++++++++++++------------- 011load.cc | 9 +-- 013literal_string.cc | 7 +-- 014literal_noninteger.cc | 3 +- 021check_instruction.cc | 6 +- 031address.cc | 4 +- 032array.cc | 8 +-- 036call_reply.cc | 6 +- 037recipe.cc | 2 +- 043new.cc | 6 +- 044space.cc | 6 +- 045space_surround.cc | 4 +- 046closure_name.cc | 20 +++---- 047global.cc | 2 +- 048check_type_by_name.cc | 4 +- 050scenario.cc | 2 +- 052tangle.cc | 2 +- 053continuation.cc | 4 +- 054dilated_reagent.cc | 6 +- 19 files changed, 150 insertions(+), 94 deletions(-) diff --git a/010vm.cc b/010vm.cc index d0a5fee5..3b4dae26 100644 --- a/010vm.cc +++ b/010vm.cc @@ -48,7 +48,7 @@ struct instruction { // properties besides types, but we're getting ahead of ourselves. struct reagent { string original_string; - vector > > properties; + vector > properties; string name; double value; bool initialized; @@ -76,13 +76,27 @@ struct type_tree { ~type_tree(); type_tree(const type_tree& old); // simple: type ordinal - type_tree(type_ordinal v) :value(v), left(NULL), right(NULL) {} + explicit type_tree(type_ordinal v) :value(v), left(NULL), right(NULL) {} // intermediate: list of type ordinals type_tree(type_ordinal v, type_tree* r) :value(v), left(NULL), right(r) {} // advanced: tree containing type ordinals type_tree(type_tree* l, type_tree* r) :value(0), left(l), right(r) {} }; +struct string_tree { + string value; + string_tree* left; + string_tree* right; + ~string_tree(); + string_tree(const string_tree& old); + // simple: flat string + explicit string_tree(string v) :value(v), left(NULL), right(NULL) {} + // intermediate: list of strings + string_tree(string v, string_tree* r) :value(v), left(NULL), right(r) {} + // advanced: tree containing strings + string_tree(string_tree* l, string_tree* r) :left(l), right(r) {} +}; + :(before "End Globals") // Locations refer to a common 'memory'. Each location can store a number. map Memory; @@ -218,39 +232,59 @@ reagent::reagent(string s) :original_string(s), value(0), initialized(false), ty while (!in.eof()) { istringstream row(slurp_until(in, '/')); row >> std::noskipws; - string name = slurp_until(row, ':'); - vector values; - while (!row.eof()) - values.push_back(slurp_until(row, ':')); - properties.push_back(pair >(name, values)); + string key = slurp_until(row, ':'); + string_tree* value = parse_property_list(row); + properties.push_back(pair(key, value)); } // structures for the first row of properties: name and list of types name = properties.at(0).first; - type_tree** curr_type = &type; - for (long long int i = 0; i < SIZE(properties.at(0).second); ++i) { - string type = properties.at(0).second.at(i); - if (Type_ordinal.find(type) == Type_ordinal.end() - // types can contain integers, like for array sizes - && !is_integer(type)) { - Type_ordinal[type] = Next_type_ordinal++; - } - *curr_type = new type_tree(Type_ordinal[type]); - curr_type = &(*curr_type)->right; - } + type = new_type_tree(properties.at(0).second); if (is_integer(name) && type == NULL) { type = new type_tree(0); - properties.at(0).second.push_back("literal"); + assert(!properties.at(0).second); + properties.at(0).second = new string_tree("literal"); } if (name == "_" && type == NULL) { type = new type_tree(0); - properties.at(0).second.push_back("dummy"); + assert(!properties.at(0).second); + properties.at(0).second = new string_tree("dummy"); } // End Parsing reagent } +string_tree* parse_property_list(istream& in) { + skip_whitespace(in); + if (in.eof()) return NULL; + string_tree* result = new string_tree(slurp_until(in, ':')); + result->right = parse_property_list(in); + return result; +} + +type_tree* new_type_tree(const string_tree* properties) { + if (!properties) return NULL; + type_tree* result = new type_tree(0); + if (!properties->value.empty()) { + const string& type_name = properties->value; + if (Type_ordinal.find(type_name) == Type_ordinal.end() + // types can contain integers, like for array sizes + && !is_integer(type_name)) { + Type_ordinal[type_name] = Next_type_ordinal++; + } + result->value = Type_ordinal[type_name]; + } + result->left = new_type_tree(properties->left); + result->right = new_type_tree(properties->right); + return result; +} + //: avoid memory leaks for the type tree reagent::reagent(const reagent& old) :original_string(old.original_string), properties(old.properties), name(old.name), value(old.value), initialized(old.initialized) { + properties.clear(); + for (long long int i = 0; i < SIZE(old.properties); ++i) { + properties.push_back(pair(old.properties.at(i).first, + old.properties.at(i).second ? new string_tree(*old.properties.at(i).second) : NULL)); + } type = old.type ? new type_tree(*old.type) : NULL; } @@ -259,29 +293,45 @@ type_tree::type_tree(const type_tree& old) :value(old.value) { right = old.right ? new type_tree(*old.right) : NULL; } +string_tree::string_tree(const string_tree& old) { // :value(old.value) { + value = old.value; + left = old.left ? new string_tree(*old.left) : NULL; + right = old.right ? new string_tree(*old.right) : NULL; +} + reagent& reagent::operator=(const reagent& old) { original_string = old.original_string; - properties = old.properties; + properties.clear(); + for (long long int i = 0; i < SIZE(old.properties); ++i) { + properties.push_back(pair(old.properties.at(i).first, old.properties.at(i).second ? new string_tree(*old.properties.at(i).second) : NULL)); + } name = old.name; value = old.value; initialized = old.initialized; - type = old.type? new type_tree(*old.type) : NULL; + type = old.type ? new type_tree(*old.type) : NULL; return *this; } reagent::~reagent() { + for (long long int i = 0; i < SIZE(properties); ++i) { + if (properties.at(i).second) delete properties.at(i).second; + } delete type; } type_tree::~type_tree() { delete left; delete right; } +string_tree::~string_tree() { + delete left; + delete right; +} reagent::reagent() :value(0), initialized(false), type(NULL) { // The first property is special, so ensure we always have it. // Other properties can be pushed back, but the first must always be // assigned to. - properties.push_back(pair >("", vector())); + properties.push_back(pair("", NULL)); } string reagent::to_string() const { @@ -291,26 +341,35 @@ string reagent::to_string() const { for (long long int i = 0; i < SIZE(properties); ++i) { if (i > 0) out << ", "; out << "\"" << properties.at(i).first << "\": "; - if (properties.at(i).second.empty()) { - out << "\"\""; - continue; - } - if (SIZE(properties.at(i).second) == 1) { - out << "\"" << properties.at(i).second.at(0) << "\""; - continue; - } - out << "<"; - for (long long int j = 0; j < SIZE(properties.at(i).second); ++j) { - if (j > 0) out << " : "; - out << "\"" << properties.at(i).second.at(j) << "\""; - } - out << ">"; + dump_property(properties.at(i).second, out); } out << "}"; } return out.str(); } +void dump_property(const string_tree* property, ostringstream& out) { + if (!property) { + out << "<>"; + return; + } + if (!property->left && !property->right) { + out << '"' << property->value << '"'; + return; + } + out << "<"; + if (property->left) + dump_property(property->left, out); + else + out << '"' << property->value << '"'; + out << " : "; + if (property->right) + dump_property(property->right, out); + else + out << " : <>"; + out << ">"; +} + string dump_types(const reagent& x) { ostringstream out; dump_types(x.type, out); @@ -371,12 +430,12 @@ bool has_property(reagent x, string name) { return false; } -vector property(const reagent& r, const string& name) { +string_tree* property(const reagent& r, const string& name) { for (long long int p = /*skip name:type*/1; p != SIZE(r.properties); ++p) { if (r.properties.at(p).first == name) return r.properties.at(p).second; } - return vector(); + return NULL; } void dump_memory() { @@ -394,6 +453,12 @@ void dump_recipe(const string& recipe_name) { cout << "]\n"; } +void skip_whitespace(istream& in) { + while (!in.eof() && isspace(in.peek()) && in.peek() != '\n') { + in.get(); + } +} + :(before "End Types") struct no_scientific { double x; diff --git a/011load.cc b/011load.cc index 19756fc1..620d6f40 100644 --- a/011load.cc +++ b/011load.cc @@ -186,12 +186,6 @@ void slurp_word(istream& in, ostream& out) { } } -void skip_whitespace(istream& in) { - while (!in.eof() && isspace(in.peek()) && in.peek() != '\n') { - in.get(); - } -} - void skip_whitespace_and_comments(istream& in) { while (true) { if (in.eof()) break; @@ -246,6 +240,7 @@ for (long long int i = 0; i < SIZE(recently_added_recipes); ++i) { // Clear Other State For recently_added_recipes recently_added_recipes.clear(); +:(code) :(scenario parse_comment_outside_recipe) # this comment will be dropped by the tangler, so we need a dummy recipe to stop that recipe f1 [ ] @@ -350,7 +345,7 @@ recipe main [ recipe main [ 1:number:address/lookup <- copy 23 ] -+parse: product: {"1": <"number" : "address">, "lookup": ""} ++parse: product: {"1": <"number" : "address">, "lookup": <>} //: this test we can't represent with a scenario :(code) diff --git a/013literal_string.cc b/013literal_string.cc index 9f5d003e..53654e5b 100644 --- a/013literal_string.cc +++ b/013literal_string.cc @@ -112,8 +112,7 @@ if (s.at(0) == '[') { strip_last(s); name = s; type = new type_tree(0); - properties.push_back(pair >(name, vector())); - properties.back().second.push_back("literal-string"); + properties.push_back(pair(name, new string_tree("literal-string"))); return; } @@ -126,7 +125,7 @@ if (s.at(0) == '[') { :(code) bool is_literal_string(const reagent& x) { - return !x.properties.at(0).second.empty() && x.properties.at(0).second.at(0) == "literal-string"; + return x.properties.at(0).second && x.properties.at(0).second->value == "literal-string"; } string emit_literal_string(string name) { @@ -172,7 +171,7 @@ recipe main [ ] +parse: instruction: copy +parse: ingredient: {"abc": "literal-string"} -+parse: product: {"1": <"address" : "array" : "character">} ++parse: product: {"1": <"address" : <"array" : "character">>} # no other ingredients $parse: 3 diff --git a/014literal_noninteger.cc b/014literal_noninteger.cc index 17a3e895..497b4676 100644 --- a/014literal_noninteger.cc +++ b/014literal_noninteger.cc @@ -11,8 +11,7 @@ recipe main [ if (is_noninteger(s)) { name = s; type = new type_tree(0); - properties.push_back(pair >(name, vector())); - properties.back().second.push_back("literal-number"); + properties.push_back(pair(name, new string_tree("literal-number"))); set_value(to_double(s)); return; } diff --git a/021check_instruction.cc b/021check_instruction.cc index e51424f2..2fdaad60 100644 --- a/021check_instruction.cc +++ b/021check_instruction.cc @@ -111,8 +111,8 @@ bool is_mu_address(reagent r) { bool is_mu_number(reagent r) { if (!r.type) return false; if (is_literal(r)) - return r.properties.at(0).second.at(0) == "literal-number" - || r.properties.at(0).second.at(0) == "literal"; + return r.properties.at(0).second->value == "literal-number" + || r.properties.at(0).second->value == "literal"; if (r.type->value == Type_ordinal["character"]) return true; // permit arithmetic on unicode code points return r.type->value == Type_ordinal["number"]; } @@ -120,7 +120,7 @@ bool is_mu_number(reagent r) { bool is_mu_scalar(reagent r) { if (!r.type) return false; if (is_literal(r)) - return r.properties.at(0).second.empty() || r.properties.at(0).second.at(0) != "literal-string"; + return !r.properties.at(0).second || r.properties.at(0).second->value != "literal-string"; if (is_mu_array(r)) return false; return size_of(r) == 1; } diff --git a/031address.cc b/031address.cc index 7be3b54d..27d7fb43 100644 --- a/031address.cc +++ b/031address.cc @@ -95,7 +95,7 @@ void drop_address_from_type(reagent& r) { } void drop_one_lookup(reagent& r) { - for (vector > >::iterator p = r.properties.begin(); p != r.properties.end(); ++p) { + for (vector >::iterator p = r.properties.begin(); p != r.properties.end(); ++p) { if (p->first == "lookup") { r.properties.erase(p); return; @@ -161,7 +161,7 @@ recipe main [ { while (!name.empty() && name.at(0) == '*') { name.erase(0, 1); - properties.push_back(pair >("lookup", vector())); + properties.push_back(pair("lookup", NULL)); } if (name.empty()) raise_error << "illegal name " << original_string << '\n' << end(); diff --git a/032array.cc b/032array.cc index 9a8a0115..b544df38 100644 --- a/032array.cc +++ b/032array.cc @@ -34,12 +34,12 @@ case CREATE_ARRAY: { break; } // 'create-array' will need to check properties rather than types - if (SIZE(product.properties.at(0).second) <= 2) { + if (!product.properties.at(0).second || !product.properties.at(0).second->right || !product.properties.at(0).second->right->right) { raise_error << maybe(Recipe[r].name) << "create array of what size? " << inst.to_string() << '\n' << end(); break; } - if (!is_integer(product.properties.at(0).second.at(2))) { - raise_error << maybe(Recipe[r].name) << "'create-array' product should specify size of array after its element type, but got " << product.properties.at(0).second.at(2) << '\n' << end(); + if (!is_integer(product.properties.at(0).second->right->right->value)) { + raise_error << maybe(Recipe[r].name) << "'create-array' product should specify size of array after its element type, but got " << product.properties.at(0).second->right->right->value << '\n' << end(); break; } break; @@ -49,7 +49,7 @@ case CREATE_ARRAY: { reagent product = current_instruction().products.at(0); canonize(product); long long int base_address = product.value; - long long int array_size= to_integer(product.properties.at(0).second.at(2)); + long long int array_size = to_integer(product.properties.at(0).second->right->right->value); // initialize array size, so that size_of will work Memory[base_address] = array_size; // in array elements long long int size = size_of(product); // in locations diff --git a/036call_reply.cc b/036call_reply.cc index e2e34c06..98a1eb33 100644 --- a/036call_reply.cc +++ b/036call_reply.cc @@ -53,12 +53,12 @@ case REPLY: { for (long long int i = 0; i < SIZE(caller_instruction.products); ++i) { trace(Primitive_recipe_depth, "run") << "result " << i << " is " << to_string(ingredients.at(i)) << end(); if (has_property(reply_inst.ingredients.at(i), "same-as-ingredient")) { - vector tmp = property(reply_inst.ingredients.at(i), "same-as-ingredient"); - if (SIZE(tmp) != 1) { + string_tree* tmp = property(reply_inst.ingredients.at(i), "same-as-ingredient"); + if (!tmp || tmp->right) { raise_error << maybe(current_recipe_name()) << "'same-as-ingredient' metadata should take exactly one value in " << reply_inst.to_string() << '\n' << end(); goto finish_reply; } - long long int ingredient_index = to_integer(tmp.at(0)); + long long int ingredient_index = to_integer(tmp->value); if (ingredient_index >= SIZE(caller_instruction.ingredients)) raise_error << maybe(current_recipe_name()) << "'same-as-ingredient' metadata overflows ingredients in: " << caller_instruction.to_string() << '\n' << end(); if (!is_dummy(caller_instruction.products.at(i)) && caller_instruction.products.at(i).value != caller_instruction.ingredients.at(ingredient_index).value) diff --git a/037recipe.cc b/037recipe.cc index 23cfb5b2..b3f4d90f 100644 --- a/037recipe.cc +++ b/037recipe.cc @@ -31,7 +31,7 @@ type_ordinal recipe_ordinal = Type_ordinal["recipe-ordinal"] = Next_type_ordinal Type[recipe_ordinal].name = "recipe-ordinal"; :(before "End Reagent-parsing Exceptions") -if (!r.properties.at(0).second.empty() && r.properties.at(0).second.at(0) == "recipe") { +if (r.properties.at(0).second && r.properties.at(0).second->value == "recipe") { r.set_value(Recipe_ordinal[r.name]); return; } diff --git a/043new.cc b/043new.cc index d33d685a..34ccf18b 100644 --- a/043new.cc +++ b/043new.cc @@ -319,8 +319,8 @@ recipe main [ :(before "End NEW Transform Special-cases") if (!inst.ingredients.empty() && !inst.ingredients.at(0).properties.empty() - && !inst.ingredients.at(0).properties.at(0).second.empty() - && inst.ingredients.at(0).properties.at(0).second.at(0) == "literal-string") { + && inst.ingredients.at(0).properties.at(0).second + && inst.ingredients.at(0).properties.at(0).second->value == "literal-string") { // skip transform inst.ingredients.at(0).initialized = true; goto end_new_transform; @@ -437,5 +437,5 @@ string read_mu_string(long long int address) { } bool is_mu_type_literal(reagent r) { - return is_literal(r) && !r.properties.empty() && !r.properties.at(0).second.empty() && r.properties.at(0).second.at(0) == "type"; + return is_literal(r) && !r.properties.empty() && r.properties.at(0).second && r.properties.at(0).second->value == "type"; } diff --git a/044space.cc b/044space.cc index 53d9b802..598c8847 100644 --- a/044space.cc +++ b/044space.cc @@ -56,7 +56,7 @@ void absolutize(reagent& x) { raise_error << current_instruction().to_string() << ": reagent not initialized: " << x.original_string << '\n' << end(); } x.set_value(address(x.value, space_base(x))); - x.properties.push_back(pair >("raw", vector())); + x.properties.push_back(pair("raw", NULL)); assert(is_raw(x)); } @@ -77,7 +77,7 @@ recipe main [ +mem: storing 35 in location 9 :(after "reagent tmp" following "case GET:") -tmp.properties.push_back(pair >("raw", vector())); +tmp.properties.push_back(pair("raw", NULL)); //:: fix 'index' @@ -97,7 +97,7 @@ recipe main [ +mem: storing 35 in location 9 :(after "reagent tmp" following "case INDEX:") -tmp.properties.push_back(pair >("raw", vector())); +tmp.properties.push_back(pair("raw", NULL)); //:: convenience operation to automatically deduce the amount of space to //:: allocate in a default space with names diff --git a/045space_surround.cc b/045space_surround.cc index a29ad67c..b55c5e04 100644 --- a/045space_surround.cc +++ b/045space_surround.cc @@ -41,9 +41,9 @@ long long int space_base(const reagent& x, long long int space_index, long long long long int space_index(const reagent& x) { for (long long int i = /*skip name:type*/1; i < SIZE(x.properties); ++i) { if (x.properties.at(i).first == "space") { - if (SIZE(x.properties.at(i).second) != 1) + if (!x.properties.at(i).second || x.properties.at(i).second->right) raise_error << maybe(current_recipe_name()) << "/space metadata should take exactly one value in " << x.original_string << '\n' << end(); - return to_integer(x.properties.at(i).second.at(0)); + return to_integer(x.properties.at(i).second->value); } } return 0; diff --git a/046closure_name.cc b/046closure_name.cc index 80ef44e8..69847fd5 100644 --- a/046closure_name.cc +++ b/046closure_name.cc @@ -57,13 +57,13 @@ void collect_surrounding_spaces(const recipe_ordinal r) { raise_error << "slot 0 should always have type address:array:location, but is " << inst.products.at(j).to_string() << '\n' << end(); continue; } - vector s = property(inst.products.at(j), "names"); - if (s.empty()) { + string_tree* s = property(inst.products.at(j), "names"); + if (!s) { raise_error << "slot 0 requires a /names property in recipe " << Recipe[r].name << end(); continue; } - if (SIZE(s) > 1) raise_error << "slot 0 should have a single value in /names, but got " << inst.products.at(j).to_string() << '\n' << end(); - string surrounding_recipe_name = s.at(0); + if (s->right) raise_error << "slot 0 should have a single value in /names, but got " << inst.products.at(j).to_string() << '\n' << end(); + const string& surrounding_recipe_name = s->value; if (Surrounding_space.find(r) != Surrounding_space.end() && Surrounding_space[r] != Recipe_ordinal[surrounding_recipe_name]) { raise_error << "recipe " << Recipe[r].name << " can have only one 'surrounding' recipe but has " << Recipe[Surrounding_space[r]].name << " and " << surrounding_recipe_name << '\n' << end(); @@ -84,9 +84,9 @@ long long int lookup_name(const reagent& x, const recipe_ordinal default_recipe) if (Name[default_recipe].empty()) raise_error << "name not found: " << x.name << '\n' << end(); return Name[default_recipe][x.name]; } - vector p = property(x, "space"); - if (SIZE(p) != 1) raise_error << "/space property should have exactly one (non-negative integer) value\n" << end(); - long long int n = to_integer(p.at(0)); + string_tree* p = property(x, "space"); + if (!p || p->right) raise_error << "/space property should have exactly one (non-negative integer) value\n" << end(); + long long int n = to_integer(p->value); assert(n >= 0); recipe_ordinal surrounding_recipe = lookup_surrounding_recipe(default_recipe, n); set done; @@ -127,12 +127,12 @@ recipe_ordinal lookup_surrounding_recipe(const recipe_ordinal r, long long int n :(replace{} "bool already_transformed(const reagent& r, const map& names)") bool already_transformed(const reagent& r, const map& names) { if (has_property(r, "space")) { - vector p = property(r, "space"); - if (SIZE(p) != 1) { + string_tree* p = property(r, "space"); + if (!p || p->right) { raise_error << "/space property should have exactly one (non-negative integer) value in " << r.original_string << '\n' << end(); return false; } - if (p.at(0) != "0") return true; + if (p->value != "0") return true; } return names.find(r.name) != names.end(); } diff --git a/047global.cc b/047global.cc index 496a6f3e..b080b90d 100644 --- a/047global.cc +++ b/047global.cc @@ -77,7 +77,7 @@ $error: 0 bool is_global(const reagent& x) { for (long long int i = /*skip name:type*/1; i < SIZE(x.properties); ++i) { if (x.properties.at(i).first == "space") - return !x.properties.at(i).second.empty() && x.properties.at(i).second.at(0) == "global"; + return x.properties.at(i).second && x.properties.at(i).second->value == "global"; } return false; } diff --git a/048check_type_by_name.cc b/048check_type_by_name.cc index 7e5c478b..e6bedbc9 100644 --- a/048check_type_by_name.cc +++ b/048check_type_by_name.cc @@ -56,8 +56,8 @@ void deduce_missing_type(map& metadata, reagent& x) { if (x.type) return; if (metadata.find(x.name) == metadata.end()) return; x.type = new type_tree(*metadata[x.name]); - assert(x.properties.at(0).second.empty()); - x.properties.at(0).second.push_back("as-before"); + assert(!x.properties.at(0).second); + x.properties.at(0).second = new string_tree("as-before"); } :(scenario transform_fills_in_missing_types_in_product) diff --git a/050scenario.cc b/050scenario.cc index bf3b75e7..c2730274 100644 --- a/050scenario.cc +++ b/050scenario.cc @@ -305,7 +305,7 @@ void check_memory(const string& s) { void check_type(const string& lhs, istream& in) { reagent x(lhs); - if (x.properties.at(0).second.at(0) == "string") { + if (x.properties.at(0).second->value == "string") { x.set_value(to_integer(x.name)); skip_whitespace_and_comments(in); string _assign = next_word(in); diff --git a/052tangle.cc b/052tangle.cc index 08c5f790..2c393a31 100644 --- a/052tangle.cc +++ b/052tangle.cc @@ -119,7 +119,7 @@ void append_fragment(vector& base, const vector& patch for (long long int j = 0; j < SIZE(inst.ingredients); ++j) { reagent& x = inst.ingredients.at(j); if (!is_literal(x)) continue; - if (x.properties.at(0).second.at(0) == "label" && jump_targets.find(x.name) != jump_targets.end()) + if (x.properties.at(0).second->value == "label" && jump_targets.find(x.name) != jump_targets.end()) x.name = prefix+x.name; } base.push_back(inst); diff --git a/053continuation.cc b/053continuation.cc index a66e5401..080eb736 100644 --- a/053continuation.cc +++ b/053continuation.cc @@ -258,8 +258,8 @@ call_stack::iterator find_reset(call_stack& c) { //: overload 'call' for continuations :(after "Begin Call") if (!current_instruction().ingredients.at(0).properties.empty() - && !current_instruction().ingredients.at(0).properties.at(0).second.empty() - && current_instruction().ingredients.at(0).properties.at(0).second.at(0) == "continuation") { + && current_instruction().ingredients.at(0).properties.at(0).second + && current_instruction().ingredients.at(0).properties.at(0).second->value == "continuation") { // copy multiple calls on to current call stack assert(scalar(ingredients.at(0))); if (Delimited_continuation.find(ingredients.at(0).at(0)) == Delimited_continuation.end()) { diff --git a/054dilated_reagent.cc b/054dilated_reagent.cc index af7e5820..70217ee4 100644 --- a/054dilated_reagent.cc +++ b/054dilated_reagent.cc @@ -80,13 +80,11 @@ if (s.at(0) == '{') { string key = next_dilated_word(in); if (key.empty()) continue; string value = next_dilated_word(in); - vector values; - values.push_back(value); - properties.push_back(pair >(key, values)); + properties.push_back(pair(key, new string_tree(value))); } // structures for the first row of properties name = properties.at(0).first; - string type_name = properties.at(0).second.at(0); + string type_name = properties.at(0).second->value; if (Type_ordinal.find(type_name) == Type_ordinal.end()) { // this type can't be an integer Type_ordinal[type_name] = Next_type_ordinal++; -- cgit 1.4.1-2-gfad0