:(before "End Globals")
map<recipe_ordinal, recipe> Recipe;
map<string, recipe_ordinal> Recipe_ordinal;
recipe_ordinal Next_recipe_ordinal = 1;
:(after "Types")
typedef long long int recipe_ordinal;
:(before "End Types")
struct recipe {
string name;
vector<instruction> steps;
};
:(before "struct recipe")
struct instruction {
bool is_label;
string label;
string name;
recipe_ordinal operation;
vector<reagent> ingredients;
vector<reagent> products;
instruction();
void clear();
string to_string() const;
};
:(before "struct instruction")
struct reagent {
string original_string;
vector<pair<string, vector<string> > > properties;
string name;
double value;
bool initialized;
vector<type_ordinal> types;
reagent(string s);
reagent();
void set_value(double v) { value = v; initialized = true; }
string to_string() const;
};
:(before "struct reagent")
struct property {
vector<string> values;
};
:(before "End Globals")
map<long long int, double> Memory;
:(before "End Setup")
Memory.clear();
:(after "Types")
typedef long long int type_ordinal;
:(before "End Globals")
map<string, type_ordinal> Type_ordinal;
map<type_ordinal, type_info> Type;
type_ordinal Next_type_ordinal = 1;
:(code)
void setup_types() {
Type.clear(); Type_ordinal.clear();
Type_ordinal["literal"] = 0;
Next_type_ordinal = 1;
type_ordinal number = Type_ordinal["number"] = Next_type_ordinal++;
Type_ordinal["location"] = Type_ordinal["number"];
Type[number].name = "number";
type_ordinal address = Type_ordinal["address"] = Next_type_ordinal++;
Type[address].name = "address";
type_ordinal boolean = Type_ordinal["boolean"] = Next_type_ordinal++;
Type[boolean].name = "boolean";
type_ordinal character = Type_ordinal["character"] = Next_type_ordinal++;
Type[character].name = "character";
type_ordinal array = Type_ordinal["array"] = Next_type_ordinal++;
Type[array].name = "array";
}
:(before "End One-time Setup")
setup_types();
:(before "End Types")
enum kind_of_type {
primitive,
container,
exclusive_container
};
struct type_info {
string name;
kind_of_type kind;
long long int size;
vector<vector<type_ordinal> > elements;
vector<string> element_names;
type_info() :kind(primitive), size(0) {}
};
enum primitive_recipes {
IDLE = 0,
COPY,
MAX_PRIMITIVE_RECIPES,
};
:(code)
void setup_recipes() {
Recipe.clear(); Recipe_ordinal.clear();
Recipe_ordinal["idle"] = IDLE;
Recipe_ordinal["copy"] = COPY;
}
:(before "End One-time Setup")
setup_recipes();
assert(MAX_PRIMITIVE_RECIPES < 200);
Next_recipe_ordinal = 200;
:(before "End Test Run Initialization")
assert(Next_recipe_ordinal < 1000);
:(before "End Setup")
Next_recipe_ordinal = 1000;
^L
:(code)
instruction::instruction() :is_label(false), operation(IDLE) {
}
void instruction::clear() { is_label=false; label.clear(); operation=IDLE; ingredients.clear(); products.clear(); }
reagent::reagent(string s) :original_string(s), value(0), initialized(false) {
istringstream in(s);
in >> std::noskipws;
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));
}
name = properties.at(0).first;
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()) {
Type_ordinal[type] = Next_type_ordinal++;
}
types.push_back(Type_ordinal[type]);
}
if (is_integer(name) && types.empty()) {
types.push_back(0);
properties.at(0).second.push_back("literal");
}
if (name == "_" && types.empty()) {
types.push_back(0);
properties.at(0).second.push_back("dummy");
}
}
reagent::reagent() :value(0), initialized(false) {
properties.push_back(pair<string, vector<string> >("", vector<string>()));
}
string reagent::to_string() const {
ostringstream out;
out << "{name: \"" << name << "\"";
if (!properties.empty()) {
out << ", properties: [";
for (long long int i = 0; i < SIZE(properties); ++i) {
out << "\"" << properties.at(i).first << "\": ";
for (long long int j = 0; j < SIZE(properties.at(i).second); ++j) {
if (j > 0) out << ':';
out << "\"" << properties.at(i).second.at(j) << "\"";
}
if (i < SIZE(properties)-1) out << ", ";
else out << "]";
}
}
out << "}";
return out.str();
}
string instruction::to_string() const {
if (is_label) return label;
ostringstream out;
for (long long int i = 0; i < SIZE(products); ++i) {
if (i > 0) out << ", ";
out << products.at(i).original_string;
}
if (!products.empty()) out << " <- ";
out << name << ' ';
for (long long int i = 0; i < SIZE(ingredients); ++i) {
if (i > 0) out << ", ";
out << ingredients.at(i).original_string;
}
return out.str();
}
string slurp_until(istream& in, char delim) {
ostringstream out;
char c;
while (in >> c) {
if (c == delim) {
break;
}
out << c;
}
return out.str();
}
bool has_property(reagent x, string name) {
for (long long int i = 1; i < SIZE(x.properties); ++i) {
if (x.properties.at(i).first == name) return true;
}
return false;
}
vector<string> property(const reagent& r, const string& name) {
for (long long int p = 1; p != SIZE(r.properties); ++p) {
if (r.properties.at(p).first == name)
return r.properties.at(p).second;
}
return vector<string>();
}
void dump_memory() {
for (map<long long int, double>::iterator p = Memory.begin(); p != Memory.end(); ++p) {
cout << p->first << ": " << p->second << '\n';
}
}
:(before "End Includes")
#include<utility>
using std::pair;