2283 - represent each /property as a tree
This commit is contained in:
parent
7bba6e7bb7
commit
ae256ea13e
143
010vm.cc
143
010vm.cc
|
@ -48,7 +48,7 @@ struct instruction {
|
|||
// properties besides types, but we're getting ahead of ourselves.
|
||||
struct reagent {
|
||||
string original_string;
|
||||
vector<pair<string, vector<string> > > properties;
|
||||
vector<pair<string, string_tree*> > 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<long long int, double> 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<string> values;
|
||||
while (!row.eof())
|
||||
values.push_back(slurp_until(row, ':'));
|
||||
properties.push_back(pair<string, vector<string> >(name, values));
|
||||
string key = slurp_until(row, ':');
|
||||
string_tree* value = parse_property_list(row);
|
||||
properties.push_back(pair<string, string_tree*>(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<string, string_tree*>(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<string, string_tree*>(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<string, vector<string> >("", vector<string>()));
|
||||
properties.push_back(pair<string, string_tree*>("", 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<string> 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<string>();
|
||||
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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -112,8 +112,7 @@ if (s.at(0) == '[') {
|
|||
strip_last(s);
|
||||
name = s;
|
||||
type = new type_tree(0);
|
||||
properties.push_back(pair<string, vector<string> >(name, vector<string>()));
|
||||
properties.back().second.push_back("literal-string");
|
||||
properties.push_back(pair<string, string_tree*>(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
|
||||
|
||||
|
|
|
@ -11,8 +11,7 @@ recipe main [
|
|||
if (is_noninteger(s)) {
|
||||
name = s;
|
||||
type = new type_tree(0);
|
||||
properties.push_back(pair<string, vector<string> >(name, vector<string>()));
|
||||
properties.back().second.push_back("literal-number");
|
||||
properties.push_back(pair<string, string_tree*>(name, new string_tree("literal-number")));
|
||||
set_value(to_double(s));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ void drop_address_from_type(reagent& r) {
|
|||
}
|
||||
|
||||
void drop_one_lookup(reagent& r) {
|
||||
for (vector<pair<string, vector<string> > >::iterator p = r.properties.begin(); p != r.properties.end(); ++p) {
|
||||
for (vector<pair<string, string_tree*> >::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<string, vector<string> >("lookup", vector<string>()));
|
||||
properties.push_back(pair<string, string_tree*>("lookup", NULL));
|
||||
}
|
||||
if (name.empty())
|
||||
raise_error << "illegal name " << original_string << '\n' << end();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<string> 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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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<string, vector<string> >("raw", vector<string>()));
|
||||
x.properties.push_back(pair<string, string_tree*>("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<string, vector<string> >("raw", vector<string>()));
|
||||
tmp.properties.push_back(pair<string, string_tree*>("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<string, vector<string> >("raw", vector<string>()));
|
||||
tmp.properties.push_back(pair<string, string_tree*>("raw", NULL));
|
||||
|
||||
//:: convenience operation to automatically deduce the amount of space to
|
||||
//:: allocate in a default space with names
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<string> 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<string> 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<recipe_ordinal> 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<string, long long int>& names)")
|
||||
bool already_transformed(const reagent& r, const map<string, long long int>& names) {
|
||||
if (has_property(r, "space")) {
|
||||
vector<string> 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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -56,8 +56,8 @@ void deduce_missing_type(map<string, type_tree*>& 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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -119,7 +119,7 @@ void append_fragment(vector<instruction>& base, const vector<instruction>& 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);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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<string> values;
|
||||
values.push_back(value);
|
||||
properties.push_back(pair<string, vector<string> >(key, values));
|
||||
properties.push_back(pair<string, string_tree*>(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++;
|
||||
|
|
Loading…
Reference in New Issue