58 unordered_set<string> registered;
59 (*factory_it)->CollectRegistered(registered);
60 string base_name = (*factory_it)->BaseName();
63 VarMapBase *obj_var_map = (*factory_it)->CreateVarMap(
this);
64 var_map_[obj_var_map->
Name()] = obj_var_map;
67 cerr <<
"Environment: created VarMap for " << obj_var_map->
Name()
72 VarMapBase *obj_vector_var_map = (*factory_it)->CreateVectorVarMap(
this);
73 var_map_[obj_vector_var_map->
Name()] = obj_vector_var_map;
76 cerr <<
"Environment: created VarMap for " << obj_vector_var_map->
Name()
80 for (unordered_set<string>::const_iterator it = registered.begin();
81 it != registered.end(); ++it) {
82 const string &concrete_type_name = *it;
84 unordered_map<string, string>::const_iterator concrete_to_factory_it =
85 concrete_to_factory_type_.find(concrete_type_name);
86 if (concrete_to_factory_it != concrete_to_factory_type_.end()) {
89 cerr <<
"Environment: WARNING: trying to override existing "
90 <<
"concrete-to-factory type mapping ["
91 << concrete_type_name <<
" --> " << concrete_to_factory_it->second
92 <<
"] with [" << concrete_type_name <<
" --> " << base_name
95 concrete_to_factory_type_[concrete_type_name] = base_name;
98 cerr <<
"Environment: associating concrete typename "
100 <<
" with factory for " << base_name << endl;
118 st.
Peek() !=
"true" && st.
Peek() !=
"false" &&
119 st.
Peek() !=
"nullptr" && st.
Peek() !=
"NULL")) {
120 ostringstream err_ss;
121 err_ss <<
"Environment: error: expected literal or Factory-constructible "
122 <<
"type but found token \"" << st.
Peek() <<
"\" of type "
124 throw std::runtime_error(err_ss.str());
127 string next_tok = st.
Peek();
128 bool is_object_type =
false;
130 string inferred_type = InferType(varname, st, is_vector, &is_object_type);
133 cerr <<
"Environment::ReadAndSet: next_tok=\"" << next_tok
134 <<
"\"; explicit type=\"" << type <<
"\"; "
135 <<
"inferred_type=\"" << inferred_type <<
"\"" << endl;
138 if (type ==
"" && inferred_type ==
"") {
139 ostringstream err_ss;
140 err_ss <<
"Environment: error: no explicit type specifier and could not "
141 <<
"infer type for variable " << varname;
142 throw std::runtime_error(err_ss.str());
144 if (type !=
"" && inferred_type !=
"" && type != inferred_type) {
145 ostringstream err_ss;
146 err_ss <<
"Environment: error: explicit type " << type
147 <<
" and inferred type " << inferred_type
148 <<
" disagree for variable " << varname;
149 throw std::runtime_error(err_ss.str());
153 string varmap_type = type ==
"" ? inferred_type : type;
156 var_map_[varmap_type]->ReadAndSet(varname, st);
157 types_[varname] = varmap_type;
161 EnvironmentImpl::InferType(
const string &varname,
163 bool *is_object_type) {
164 *is_object_type =
false;
165 string next_tok = st.
Peek();
168 if (next_tok ==
"true" || next_tok ==
"false") {
169 return is_vector ?
"bool[]" :
"bool";
175 return is_vector ?
"string[]" :
"string";
181 size_t dot_pos = next_tok.find(
'.');
182 if (dot_pos != string::npos) {
183 return is_vector ?
"double[]" :
"double";
185 return is_vector ?
"int[]" :
"int";
194 unordered_map<string, string>::const_iterator factory_type_it =
195 concrete_to_factory_type_.find(next_tok);
196 unordered_map<string, string>::const_iterator var_type_it =
197 types_.find(next_tok);
198 if (factory_type_it != concrete_to_factory_type_.end()) {
201 cerr <<
"Environment::InferType: concrete type is " << next_tok
202 <<
"; mapping to abstract Factory type "
203 << factory_type_it->second << endl;
205 type = factory_type_it->second;
206 *is_object_type =
true;
207 type = is_vector ? type +
"[]" : type;
210 cerr <<
"Environment::InferType: type "
211 << (is_vector ?
"is" :
"isn't")
212 <<
" a vector, so final inferred type is " << type << endl;
214 }
else if (var_type_it != types_.end()) {
218 string append = is_vector ?
"[]" :
"";
219 type = var_type_it->second + append;
221 cerr <<
"Environment::InferType: found variable "
222 << var_type_it->first <<
" of type " << var_type_it->second
223 <<
"; type is " << type << endl;
226 ostringstream err_ss;
227 err_ss <<
"Environment: error: token " << next_tok
228 <<
" is neither a variable nor a concrete object typename";
229 throw std::runtime_error(err_ss.str());
A container to hold the mapping between named variables of a specific type and their values...
A simple class for tokenizing a stream of tokens for the formally specified language used to construc...
virtual void ReadAndSet(const string &varname, StreamTokenizer &st, const string type)
Sets the specified variable to the value obtained from the following tokens available from the specif...
A base class for a mapping from variables of a specific type to their values.
virtual void PrintFactories(ostream &os) const
Prints out a human-readable string with the names of all abstract base types and their concrete imple...
static const char * TypeName(TokenType token_type)
Returns a string type name for the specified TokenType constant.
static void Print(ostream &os)
Prints the base typenames for all factories along with a list of all concrete subtypes those factorie...
string Next()
Returns the next token in the token stream.
EnvironmentImpl(int debug=0)
Constructs a new, empty environment.
Provides an environment for variables and their values, either primitive or Factory-constructible obj...
vector< FactoryBase * >::iterator iterator
string Peek() const
Returns the next token that would be returned by the Next method.
virtual const string & Name() const
Returns the type name of the variables of this instance.
Provides a generic dynamic object factory.
TokenType PeekTokenType() const
Returns the type of the next token, or EOF_TYPE if there is no next token.