51 var_map_[
"double[]"] =
53 var_map_[
"string[]"] =
60 unordered_set<string> registered;
61 (*factory_it)->CollectRegistered(registered);
62 string base_name = (*factory_it)->BaseName();
65 VarMapBase *obj_var_map = (*factory_it)->CreateVarMap(
this);
66 var_map_[obj_var_map->
Name()] = obj_var_map;
69 cerr <<
"Environment: created VarMap for " << obj_var_map->
Name()
74 VarMapBase *obj_vector_var_map = (*factory_it)->CreateVectorVarMap(
this);
75 var_map_[obj_vector_var_map->
Name()] = obj_vector_var_map;
78 cerr <<
"Environment: created VarMap for " << obj_vector_var_map->
Name()
82 for (unordered_set<string>::const_iterator it = registered.begin();
83 it != registered.end(); ++it) {
84 const string &concrete_type_name = *it;
86 unordered_map<string, string>::const_iterator concrete_to_factory_it =
87 concrete_to_factory_type_.find(concrete_type_name);
88 if (concrete_to_factory_it != concrete_to_factory_type_.end()) {
91 cerr <<
"Environment: WARNING: trying to override existing "
92 <<
"concrete-to-factory type mapping ["
93 << concrete_type_name <<
" --> " << concrete_to_factory_it->second
94 <<
"] with [" << concrete_type_name <<
" --> " << base_name
97 concrete_to_factory_type_[concrete_type_name] = base_name;
100 cerr <<
"Environment: associating concrete typename "
101 << concrete_type_name
102 <<
" with factory for " << base_name << endl;
120 st.
Peek() !=
"true" && st.
Peek() !=
"false" &&
121 st.
Peek() !=
"nullptr" && st.
Peek() !=
"NULL")) {
122 ostringstream err_ss;
123 err_ss <<
"Environment: error: expected literal or Factory-constructible "
124 <<
"type but found token \"" << st.
Peek() <<
"\" of type "
129 string next_tok = st.
Peek();
130 bool is_object_type =
false;
132 string inferred_type = InferType(varname, st, is_vector, &is_object_type);
136 next_tok = st.
Peek();
140 cerr <<
"Environment::ReadAndSet: next_tok=\"" << next_tok
141 <<
"\"; explicit type=\"" << type <<
"\"; "
142 <<
"inferred_type=\"" << inferred_type <<
"\"" << endl;
145 if (type ==
"" && inferred_type ==
"") {
146 ostringstream err_ss;
147 err_ss <<
"Environment: error: no explicit type specifier and could not "
148 <<
"infer type for variable " << varname;
151 if (type !=
"" && inferred_type !=
"" && type != inferred_type) {
152 ostringstream err_ss;
153 err_ss <<
"Environment: error: explicit type " << type
154 <<
" and inferred type " << inferred_type
155 <<
" disagree for variable " << varname;
160 string varmap_type = type ==
"" ? inferred_type : type;
163 var_map_[varmap_type]->ReadAndSet(varname, st);
164 types_[varname] = varmap_type;
168 EnvironmentImpl::InferType(
const string &varname,
170 bool *is_object_type) {
171 *is_object_type =
false;
172 string next_tok = st.
Peek();
175 if (next_tok ==
"true" || next_tok ==
"false") {
176 return is_vector ?
"bool[]" :
"bool";
182 return is_vector ?
"string[]" :
"string";
188 size_t dot_pos = next_tok.find(
'.');
189 if (dot_pos != string::npos) {
190 return is_vector ?
"double[]" :
"double";
192 return is_vector ?
"int[]" :
"int";
201 unordered_map<string, string>::const_iterator factory_type_it =
202 concrete_to_factory_type_.find(next_tok);
203 unordered_map<string, string>::const_iterator var_type_it =
204 types_.find(next_tok);
205 if (factory_type_it != concrete_to_factory_type_.end()) {
208 cerr <<
"Environment::InferType: concrete type is " << next_tok
209 <<
"; mapping to abstract Factory type "
210 << factory_type_it->second << endl;
212 type = factory_type_it->second;
213 *is_object_type =
true;
214 type = is_vector ? type +
"[]" : type;
217 cerr <<
"Environment::InferType: type "
218 << (is_vector ?
"is" :
"isn't")
219 <<
" a vector, so final inferred type is " << type << endl;
221 }
else if (var_type_it != types_.end()) {
225 string append = is_vector ?
"[]" :
"";
226 type = var_type_it->second + append;
228 cerr <<
"Environment::InferType: found variable "
229 << var_type_it->first <<
" of type " << var_type_it->second
230 <<
"; type is " << type << endl;
233 ostringstream err_ss;
234 err_ss <<
"Environment: error: token " << next_tok
235 <<
" is neither a variable nor a concrete object typename";
vector< FactoryBase * >::iterator iterator
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.
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...
EnvironmentImpl(int debug=0)
Constructs a new, empty environment.
A container to hold the mapping between named variables of a specific type and their values...
TokenType PeekTokenType() const
Returns the type of the next token, or EOF_TYPE if there is no next token.
void Putback()
A synonym for Rewind(1).
virtual const string & Name() const
Returns the type name of the variables of this instance.
Provides a generic dynamic object factory.
A simple class for tokenizing a stream of tokens for the formally specified language used to construc...
static const char * TypeName(TokenType token_type)
Returns a string type name for the specified TokenType constant.
virtual void PrintFactories(ostream &os) const
Prints out a human-readable string with the names of all abstract base types and their concrete imple...
void Error(const std::string &message)
Reports an error encountered during parsing and/or construction of an object.
string Peek() const
Returns the next token that would be returned by the Next method.
Provides an environment for variables and their values, either primitive or Factory-constructible obj...
A base class for a mapping from variables of a specific type to their values.