InFact
Interpreter and factory for easily creating C++ objects at run-time
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
stream-init.h
Go to the documentation of this file.
1 // Copyright 2014, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 // -----------------------------------------------------------------------------
30 //
31 //
35 
36 #ifndef INFACT_STREAM_INIT_H_
37 #define INFACT_STREAM_INIT_H_
38 
39 #include <cstdlib>
40 #include <iostream>
41 #include <sstream>
42 #include <memory>
43 #include <unordered_map>
44 #include <unordered_set>
45 #include <vector>
46 #include <stdexcept>
47 
48 #include "error.h"
49 #include "stream-tokenizer.h"
50 
51 namespace infact {
52 
53 using std::ostringstream;
54 using std::shared_ptr;
55 using std::unordered_map;
56 using std::vector;
57 
58 class Environment;
59 
69  public:
71  virtual ~StreamInitializer() { }
72  virtual void Init(StreamTokenizer &st, Environment *env = nullptr) = 0;
73 };
74 
75 template <typename T> class Factory;
76 
83 template <typename T>
85  public:
86  Initializer(T *member) : member_(member) { }
87  virtual ~Initializer() { }
88  virtual void Init(StreamTokenizer &st, Environment *env = nullptr) {
89  StreamTokenizer::TokenType token_type = st.PeekTokenType();
90  bool is_null =
91  token_type == StreamTokenizer::RESERVED_WORD &&
92  (st.Peek() == "nullptr" || st.Peek() == "nullptr");
93  if (!(is_null || token_type == StreamTokenizer::IDENTIFIER)) {
94  ostringstream err_ss;
95  err_ss << "FactoryInitializer: expected \"nullptr\", \"nullptr\" or "
96  << "IDENTIFIER token at stream "
97  << "position " << st.PeekTokenStart() << " but found "
98  << StreamTokenizer::TypeName(token_type) << " token: \""
99  << st.Peek() << "\"";
100  Error(err_ss.str());
101  }
103  (*member_) = factory.CreateOrDie(st, env);
104  }
105  private:
106  T *member_;
107 };
108 
111 template<>
112 class Initializer<int> : public StreamInitializer {
113  public:
114  Initializer(int *member) : member_(member) { }
115  virtual ~Initializer() { }
116  virtual void Init(StreamTokenizer &st, Environment *env = nullptr) {
117  StreamTokenizer::TokenType token_type = st.PeekTokenType();
118  if (token_type != StreamTokenizer::NUMBER) {
119  ostringstream err_ss;
120  err_ss << "IntInitializer: expected NUMBER token at stream "
121  << "position " << st.PeekTokenStart() << " but found "
122  << StreamTokenizer::TypeName(token_type) << " token: \""
123  << st.Peek() << "\"";
124  Error(err_ss.str());
125  }
126  (*member_) = atoi(st.Next().c_str());
127  }
128  private:
129  int *member_;
130 };
131 
133 template<>
134 class Initializer<double> : public StreamInitializer {
135  public:
136  Initializer(double *member) : member_(member) { }
137  virtual ~Initializer() { }
138  virtual void Init(StreamTokenizer &st, Environment *env = nullptr) {
139  StreamTokenizer::TokenType token_type = st.PeekTokenType();
140  if (token_type != StreamTokenizer::NUMBER) {
141  ostringstream err_ss;
142  err_ss << "DoubleInitializer: expected NUMBER token at stream "
143  << "position " << st.PeekTokenStart() << " but found "
144  << StreamTokenizer::TypeName(token_type) << " token: \""
145  << st.Peek() << "\"";
146  Error(err_ss.str());
147  }
148  (*member_) = atof(st.Next().c_str());
149  }
150  private:
151  double *member_;
152 };
153 
155 template<>
156 class Initializer<bool> : public StreamInitializer {
157  public:
158  Initializer(bool *member) : member_(member) { }
159  virtual ~Initializer() { }
160  virtual void Init(StreamTokenizer &st, Environment *env = nullptr) {
161  StreamTokenizer::TokenType token_type = st.PeekTokenType();
162  if (token_type != StreamTokenizer::RESERVED_WORD) {
163  ostringstream err_ss;
164  err_ss << "BoolInitializer: expected RESERVED_WORD token at stream "
165  << "position " << st.PeekTokenStart() << " but found "
166  << StreamTokenizer::TypeName(token_type) << " token: \""
167  << st.Peek() << "\"";
168  Error(err_ss.str());
169  }
170  size_t next_tok_start = st.PeekTokenStart();
171  string next_tok = st.Next();
172  if (next_tok == "false") {
173  (*member_) = false;
174  } else if (next_tok == "true") {
175  (*member_) = true;
176  } else {
177  ostringstream err_ss;
178  err_ss << "Initializer<bool>: expected either \"true\" or \"false\" "
179  << "token at stream position " << next_tok_start << " but found "
180  << "token: \"" << next_tok << "\"";
181  Error(err_ss.str());
182  }
183  }
184  private:
185  bool *member_;
186 };
187 
189 template<>
190 class Initializer<string> : public StreamInitializer {
191  public:
192  Initializer(string *member) : member_(member) { }
193  virtual ~Initializer() { }
194  virtual void Init(StreamTokenizer &st, Environment *env = nullptr) {
195  StreamTokenizer::TokenType token_type = st.PeekTokenType();
196  if (token_type != StreamTokenizer::STRING) {
197  ostringstream err_ss;
198  err_ss << "StringInitializer: expected STRING token at stream "
199  << "position " << st.PeekTokenStart() << " but found "
200  << StreamTokenizer::TypeName(token_type) << " token: \""
201  << st.Peek() << "\"";
202  Error(err_ss.str());
203  }
204  (*member_) = st.Next();
205  }
206  private:
207  string *member_;
208 };
209 
210 } // namespace infact
211 
212 #endif
virtual void Init(StreamTokenizer &st, Environment *env=nullptr)
Definition: stream-init.h:116
virtual void Init(StreamTokenizer &st, Environment *env=nullptr)
Definition: stream-init.h:88
virtual ~Initializer()
Definition: stream-init.h:87
string Next()
Returns the next token in the token stream.
virtual void Init(StreamTokenizer &st, Environment *env=nullptr)
Definition: stream-init.h:194
Provides an error handling function that optionally throws an exception.
Initializer(T *member)
Definition: stream-init.h:86
Factory for dynamically created instance of the specified type.
Definition: factory.h:593
TokenType PeekTokenType() const
Returns the type of the next token, or EOF_TYPE if there is no next token.
virtual void Init(StreamTokenizer &st, Environment *env=nullptr)
Definition: stream-init.h:160
An interface that allows for a primitive, Factory-constructible object or vector thereof to be initia...
Definition: stream-init.h:68
virtual void Init(StreamTokenizer &st, Environment *env=nullptr)
Definition: stream-init.h:138
A simple class for tokenizing a stream of tokens for the formally specified language used to construc...
Provides the StreamTokenizer class.
A class to initialize a Factory-constructible object.
Definition: stream-init.h:84
An interface for an environment in which variables of various types are mapped to their values...
Definition: environment.h:126
static const char * TypeName(TokenType token_type)
Returns a string type name for the specified TokenType constant.
size_t PeekTokenStart() const
Returns the next token’s start position, or the byte position of the underlying byte stream if there ...
void Error(const std::string &message)
Reports an error encountered during parsing and/or construction of an object.
Definition: error.cc:47
string Peek() const
Returns the next token that would be returned by the Next method.
shared_ptr< T > CreateOrDie(StreamTokenizer &st, Environment *env=nullptr)
Dynamically creates an object, whose type and initialization are contained in a specification string...
Definition: factory.h:766
virtual void Init(StreamTokenizer &st, Environment *env=nullptr)=0
TokenType
The set of types of tokens read by this stream tokenizer.