The Active Expressions Library
by Mauricio de Simone and Gregory V. Wilson

Listing One
struct MandelTile
{
    float xLo, yLo, xHi, yHi;   // boundary coordinates of tile
    int xPixels, yPixels;       // number of pixels in tile
};

Listing Two
struct PixelBlock
{
    int xPixels, yPixels;       // number of pixels in tile
    Array<color> pixels;        // 24-bit color, xPixels*yPixels
long
};

Listing Three
class Producer : public O_Ac<MandelTile>
{
    virtual void run(){
        while (tiles to generate){
            generate and output tiles
        }
    }
};
class Worker : public IO_Ac<MandelTile, PixelBlock>
{
    virtual void run(){
        MandelTile tile;
        PixelBlock block;
        while (input stream open){
            read a job spec into tile
            calculate and output block
        }
    }
};
class Consumer : public IO_Ac<MandelTile, PixelBlock>
{
    virtual void run(){
        PixelBlock block;
        while (input stream open){
            read pixels into block
            display
        }
    }
};


Listing Four
void Worker::run(){
    MandelTile tile;
    PixelBlock block;
    while (! pin.eos()){        // eos() is the end-of-stream test
        pin >> tile;
        calculate
        pout << block;
    }
}

Listing Five
(a)
Skinner operator+(Mulder a, Scully b)
{
    ...implementation...
    return instance of Skinner;
}

(b)
Mulder fox;
Scully dana;
Skinner walter;
 ...
walter = fox + dana;

(c)
walter = operator+(fox, dana);


Listing Six
(a) 
AeNode & operator| (const AeNode& lhs, const AeNode& rhs)
{
    return *(new AeNode(lhs, rhs));
}

(b)
class AeNode
{
    public :
        AeNode(const AeNode& lhs, const AeNode& rhs)
        : _left(&lhs), _right(&rhs)
        {}
    protected :
        AeNode * _left, * _right;
}

Listing Seven
(a)
C_AeNode & operator|(const O_AeNode & lhs, const I_AeNode & rhs)
{
    return *new C_AeNode(lhs, rhs);
}

(b) 
O_AeNode& operator|(const O_AeNode& lhs, const IO_AeNode& rhs)
{
    return *new O_AeNode(lhs, rhs);
}
I_AeNode& operator|(const IO_AeNode& lhs, const I_AeNode& rhs)
{
    return *new I_AeNode(lhs, rhs);
}
IO_AeNode& operator|(const IO_AeNode& lhs, const IO_AeNode& rhs)
{
    return *new IO_AeNode(lhs, rhs);
}

Listing Eight
template <class T>
C_AeNode&
operator | (const O_AeNode<T>& lhs, const I_AeNode<T>& rhs)
{
    return *new C_AeNode(lhs, rhs);
}
 ...other variations defined similarly...


Listing Nine
template <class T>
C_AeNode<T>&
operator | (const O_AeNode<T>& lhs, const I_AeNode<T>& rhs)
{
    return *new C_Pipe<T>(lhs, rhs);
}

Listing Ten
C_Ae mandelbrot;
mandelbrot = producer | (20 * worker) | consumer;

Listing Eleven
{
    // run first time
    C_Ae mandelbrot = producer | (20 * worker) | consumer;
    while ((mandelbrot == 0) && (user isn't bored)){
        get new parameters
        producer.reset(new parameters);
        mandelbrot.do();
    }
    // mandelbrot automatically destroyed here
}

Listing Twelve
template <class Job, class Result>
class IO_Ac<Job, Result> &
TaskFarm(
    O_Ac<Job>& producer,
    IO_Ac<Job,Result>& worker,
    I_Ac<Result>& consumer
){
  int n = 3 * number of processors in the system;
  return producer | (n*worker) | consumer;
}

Listing Thirteen
template<class T>
class Loop_Ae
{
public :
    // main-line ports
    I_Port<T> pin;
    O_Port<T> pout;
    // looping ports
    I_Port<T> loopIn;
    O_Port<T> loopOut;
    // run() pre-defined
    virtual void run(){
        while (! pin.eos()){
            T data;
            pin >> data;
            while (loop()){
                loopOut << data;
                loopIn  >> data;
            }
            pout << data;
        }
    }
    // user must override control
    virtual const bool loop() = 0;
};



1


