InFact
Interpreter and factory for easily creating C++ objects at run-time
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Public Member Functions | List of all members
infact::Interpreter Class Reference

Provides an interpreter for assigning primitives and Factory-constructible objects to named variables, as well as vectors thereof. More...

#include <interpreter.h>

Public Member Functions

 Interpreter (int debug=0)
 Constructs a new instance with the specified debug level. More...
 
 Interpreter (unique_ptr< IStreamBuilder > istream_builder, int debug=0)
 Constructs a new instance with the specified IStreamBuilder and debug level. More...
 
virtual ~Interpreter ()=default
 Destroys this interpreter. More...
 
void SetIStreamBuilder (unique_ptr< IStreamBuilder > istream_builder)
 Sets the IStreamBuilder object, to be owned by this object. More...
 
void Eval (const string &filename)
 Evaluates the statements in the specified text file. More...
 
void EvalString (const string &input)
 Evaluates the statements in the specified string. More...
 
void Eval (istream &is)
 Evaluates the statements in the specified stream. More...
 
void PrintEnv (ostream &os) const
 
void PrintFactories (ostream &os) const
 
bool GetMany ()
 The base case for the variadic template method GetMany defined below. More...
 
template<typename T , typename... Args>
bool GetMany (const string &varname, T *var, Args &&...rest)
 Retrieves values for many variables, specified as a sequence of pairs of arguments. More...
 
template<typename T >
bool Get (const string &varname, T *value) const
 Retrieves the value of the specified variable. More...
 
EnvironmentImplenv ()
 Returns a pointer to the environment of this interpreter. More...
 

Detailed Description

Provides an interpreter for assigning primitives and Factory-constructible objects to named variables, as well as vectors thereof.

The interpreter maintains an internal environment whereby previously defined variables may be used in the definition of subsequent ones. The syntax of this language extends the syntax of the Factory class, described in the documentation of the Factory::CreateOrDie method.

Statements in this language look like the following:

// This is a comment.
bool b = true; // assigns the value true to the boolean variable "b"
int f = 1; // assigns the int value 1 to the variable "f"
double g = 2.4; // assigns the double value 2.4 to the variable "g"
string n = "foo" // assigns the string value "foo" to the variable "n"
bool[] b_vec = {true, false, true}; // assigns a vector of bool to "b_vec"
// Constructs an object of abstract type Model and assigns it to "m1"
Model m1 = PerceptronModel(name("foo"));
// Constructs an object of type Model and assigns it to "m2", crucially
// using the previously defined string variable "n" as the value for
// the PerceptronModel's name parameter.
Model m2 = PerceptronModel(name(n));
// Constructs a vector of Model objects and assigns it to "m_vec".
Model[] m_vec = {m2, PerceptronModel(name("bar"))};

Additionally, the interpreter can do type inference, so all the type specifiers in the previous examples are optional. For example, one may write the following statements:

b = true; // assigns the value true to the boolean variable "b"
// Constructs an object of abstract type Model and assigns it to "m1"
m1 = PerceptronModel(name("foo"));
// Constructs a vector of Model objects and assigns it to "m_vec".
m_vec = {m1, PerceptronModel(name("bar"))};

Here's an example of using the interpreter after it has read the three statements from the previous example from a file called "example.infact":

#include "interpreter.h"
// ...
i.Eval("example.infact");
shared_ptr<Model> model;
vector<shared_ptr<Model> > model_vector;
bool b;
// The next statement only assigns a value to b if a variable "b"
// exists in the interpreter's environment.
i.Get("b", &b);
i.Get("m1", &model);
i.Get("m_vec", &model_vector);

More formally, a statement in this language must conform to the following grammar, defined on top of the BNF syntax in the documentation of the Factory::CreateOrDie method:

<statement_list> ::= [ <import_or_statement> ]*
<import_or_statement> ::= [ <import> | <statement> ]
<import> ::= 'import' <string_literal> ';'
<statement> ::= [ <type_specifier> ] <variable_name> '=' <value> ';'
<type_specifier> ::=
"bool" | "int" | "string" | "double" | "bool[]" | "int[]" "string[]" | "double[]" | T | T[]
where T is any Factory-constructible type.
<variable_name> ::= any valid C++ identifier
<value> ::= <literal> | '{' <literal_list> '}' |
<spec_or_null> | '{' <spec_list> '}'

The above grammar doesn’t contain rules covering C++ style line comments, but they have the same behavior in this language as they do in C++, i.e., everything after the // to the end of the current line is treated as a comment and ignored. There are no C-style comments in this language.

There are very simple rules for finding the files specified by imports: if a path is absolute, the Interpreter tries the path as-is. If it is relative, the Interpreter tries the path relative to the directory of the file with the import statement. If that does not succeed, the system simply tries the relative path as-is.

An imported file is evaluated in situ, meaning it is evaluated in the current Environment; it is just as though you pasted the contents of the imported file right at the import statement. As such, an imported file can refer to variables that might be set prior to the import being evaluated. As a corollary, if an imported file uses the name of an unset variable, it is an error.

Definition at line 212 of file interpreter.h.

Constructor & Destructor Documentation

infact::Interpreter::Interpreter ( int  debug = 0)
inline

Constructs a new instance with the specified debug level.

The wrapped Environment will also have the specified debug level.

Definition at line 217 of file interpreter.h.

infact::Interpreter::Interpreter ( unique_ptr< IStreamBuilder istream_builder,
int  debug = 0 
)
inline

Constructs a new instance with the specified IStreamBuilder and debug level.

The wrapped Environment will also have the specified debug level.

Definition at line 224 of file interpreter.h.

virtual infact::Interpreter::~Interpreter ( )
virtualdefault

Destroys this interpreter.

Member Function Documentation

EnvironmentImpl* infact::Interpreter::env ( )
inline

Returns a pointer to the environment of this interpreter.

Crucially, this method returns a pointer to the Environment implementation class, EnvironmentImpl, so that its templated EnvironmentImpl::Get method may be invoked.

Definition at line 327 of file interpreter.h.

void infact::Interpreter::Eval ( const string &  filename)

Evaluates the statements in the specified text file.

Definition at line 91 of file interpreter.cc.

void infact::Interpreter::Eval ( istream &  is)
inline

Evaluates the statements in the specified stream.

Definition at line 247 of file interpreter.h.

void infact::Interpreter::EvalString ( const string &  input)
inline

Evaluates the statements in the specified string.

Definition at line 241 of file interpreter.h.

template<typename T >
bool infact::Interpreter::Get ( const string &  varname,
T *  value 
) const
inline

Retrieves the value of the specified variable.

It is an error if the type of the specified pointer to a value object is different from the specified variable in this interpreter’s environment.

Template Parameters
thetype of value object being set by this method
Parameters
varnamethe name of the variable for which to retrieve the value
valuea pointer to the object whose value to be set by this method

Definition at line 317 of file interpreter.h.

bool infact::Interpreter::GetMany ( )
inline

The base case for the variadic template method GetMany defined below.

Definition at line 261 of file interpreter.h.

template<typename T , typename... Args>
bool infact::Interpreter::GetMany ( const string &  varname,
T *  var,
Args &&...  rest 
)
inline

Retrieves values for many variables, specified as a sequence of pairs of arguments.

It is an error to invoke this method with an odd number of arguments.

Example:

// Evaluate a short string defining two variables.
i.EvalString("i = 6; f = \"foo\";");
int my_int;
string my_string;
i.GetMany("i", &my_int, "f", &my_string);
Parameters
[in]varnamethe name of a variable to be retrieved
[out]vara pointer to a value for the variable named by varname
restthe remaining arguments
Template Parameters
Tthe type of value to be assigned; the value of varname, if it has a binding in the Environment, must be assignable to T
Argsa variadic list of arguments, where each successive pair of arguments must be a variable name of type const string & and a pointer to an arbitrary type T to which the value of the variable may be assigned
Returns
whether this method has succeeded in assigning values to all named variables

Definition at line 294 of file interpreter.h.

void infact::Interpreter::PrintEnv ( ostream &  os) const
inline

Definition at line 252 of file interpreter.h.

void infact::Interpreter::PrintFactories ( ostream &  os) const
inline

Definition at line 256 of file interpreter.h.

void infact::Interpreter::SetIStreamBuilder ( unique_ptr< IStreamBuilder istream_builder)
inline

Sets the IStreamBuilder object, to be owned by this object.

Definition at line 233 of file interpreter.h.


The documentation for this class was generated from the following files: