An example of using eval

// Point.hpp
// An extremely simple point class.
class Point
      : _x(0), _y(0)

    Point(int x, int y)
      : _x(x), _y(y)

    int get_x() const
        return _x;

    int get_y() const
        return _y;

    void set_x(int x)
        _x = x;

    void set_y(int y)
        _y = y;

    void add_to_this(const Point& other)
        _x += other._x;
        _y += other._y;

    // A somewhat artificial overload; note the corresponding
    // eval header syntax.
    void add_to_this(int x, int y)
        _x += x;
        _y += y;

    int _x;
    int _y;

    friend Point add_points(Point& a, Point& b);

inline Point add_points(Point& a, Point& b)
    return Point(a._x + b._x, a._y + b._y);

// A somewhat artificial inheritance structure; note the corresponding
// eval header syntax.
class ThreeDimPoint : public Point
    ThreeDimPoint(int x, int y, int z)
      : Point(x, y), _z(z)

      : Point(), _z(0)

    int get_z() const
        return _z;

    void set_z(int z)
        _z = z;

    int _z;

// eval_example_header.ehpp

// Defines the basic types (e.g. int, double, ...)
#include "eval_headers/basic_types.ehpp"

// These headers are nowhere near complete.
#include "eval_headers/string.ehpp"
#include "eval_headers/ostream.ehpp"

    EVAL_REGISTER_CONSTRUCTOR(())          // default constructor
    EVAL_REGISTER_CONSTRUCTOR((Point))     // copy constructor
    EVAL_REGISTER_METHOD_OVERLOADED(void, (const Point&), add_to_this)
    EVAL_REGISTER_METHOD_OVERLOADED(void, (int, int), add_to_this)


    // Note: EVAL_INHERIT_FROM semantically really means "implements".
    // Inheritance hierarchy is irrelevant; however, this class must
    // implement/inherit all the methods (excluding constructors) in Point, or
    // compilation will fail (in C++ it is possible to create a subclass which
    // does not implemented all the methods of its superclass exactly).
    // If this class overwrites methods from the base class, you can list
    // them explicitly, but that's not necessary.

    EVAL_REGISTER_CONSTRUCTOR((int, int, int))

// Note that it is possible to register functions/methods/types
// with a different name than in their C++ source (so that the
// scripts would be able to refer to an alias name).
// eval_example_script.epp

// std::cout, point1 and point2 come in as arguments

// call operator<< function
std::cout << "Hello world from an eval script" << "\n";

val point3; // Declare new variable (accessible from calling program).
            // All variables have type val; declarations go on their own line.
point3 = Point(point1.get_x(), point2.get_y());

// modify an argument passed in
point2.add_to_this(1, 2);

val point_rv;
point_rv = add_points(point1, ThreeDimPoint(8, 9, 6)); // adding in 2D only!

// Note:
val temp;
temp = 3;      // const int
temp = int(3); // int

// eval_example.cpp

#include <string>
#include <iostream>
#include <assert.h>

// The eval header defines 2 functions, eval_file and eval (takes const char *)
#include "eval.hpp"

// The val class is a generic class for wrapping arbitary instances/primitives.
#include "val.hpp"

// A plain old c++ class, serving as an example.
#include "Point.hpp"

// The EVAL_INCLUDE_FILE1 is the eval header that determines which
// functions/methods/constructors the scripts have access to.
#define EVAL_INCLUDE_FILE1 "eval_example_header.ehpp"

// Some preprocessor magic happens at this point. Suffices to say that
// you now have a class deriving from eval::execution_context, called
// MyExecContext. This custom excecution context knows about
// functions/methods/constructors as per EVAL_INCLUDE_FILE1.
// (You can create more than 1 execution context.)
#include "create_execution_context_definition.hpp"

int main()
    MyExecContext e;   // Create our custom execution context.
    e.register_all();  // Register all functions/methods/constructors. In some
                       // circumstances, the execution context can be used
                       // without this call.
    // Make std::cout available to the script (in future library versions,
    // this may be done in the appropriate eval standard header).
    e["std::cout"] = eval::val(&std::cout, eval::UNMANAGED_PTR);

    // make some Points available to the script
    e["point1"] = eval::val(new Point(4, 5), eval::TRANSFER_OWNERSHIP);
    Point point2(6, 7);
    e["point2"] = eval::val(&point2, eval::UNMANAGED_PTR);

    // execute our example script (the script is in the same directory;
    // specifying a more complete path just helps the automated testing system)
    eval_file(e, "../examples/eval_example_script.epp");
    // We have access to variables defined in the script.
    Point *point_rv = e.extended_val_cast_ptr<Point>(e["point_rv"]);
    assert(point_rv->get_x() == 12);
    assert(point_rv->get_y() == 14);

    // The script also modified existing objects (arguments)
    assert(point2.get_x() == 11);
    assert(point2.get_y() == 16);

    // Note that various casting methods exist, allowing you to attempt
    // to convert return values to a particular type (or just get a string
    // or int representation, if possible).

    return 0;

Generated on Sat Sep 20 20:02:34 2008 for eval by  doxygen 1.5.6