// rpimpl_oper.h
// Copyright (c) Menno Rubingh 2016. Web: [http://rubinghsoftware.de]
//
// MR Mar 2016.
//
// OperationXxx classes:
// Used internally by the RPInterpreter implementation.
// Instance executes a specific operation (changing stack and variables)
// during the evaluation of a RP expression.
//
//---
// Implementation notes:
// - All member variables are constants, set via the constructors.
// - All member functions are 'const', since they do not change the member variables.
// - Member variable cm_cxt:
// This is common to all classes (therefore in Base class).
// It is passed to the exception thrown on execution error.
// It is stored not as a pointer but as a whole instance of the class struct, since
// we must store the contents of this struct. So the constructor makes a COPY if the
// struct passed as an input parameter.
// - The different binary operations are all coded out as individual OperationBinXxx
// subclasses, instead of one combined OperationBinary subclass parameterized by an
// instance of another pure virtual class hierarchy implementing the various low-level
// oerations. The rationale for coding each binary operation out as an individual
// OperationBinXxx subclass is to achieve the fastest possible processing speed.
//
#ifndef _RPIMPL_OPER_H_
#define _RPIMPL_OPER_H_
#include "rpimpl_ex.h" //SContext, Ex.
#include "rpimpl_stack.h" //StackDbl.
#include "rpimpl_var.h" //VarTable.
#include <stdio.h> //FILE.
#include <math.h> //pow().
//--------------------------------------------------------------------------------
// The OperationXxx classes.
//--------------------------------------------------------------------------------
class OperationBase
{
protected:
SContext const cm_cxt; //Character nr in input string where this lexical element begins.
public:
OperationBase( SContext const * iCxt )
:
cm_cxt( *iCxt ) //Copy struct contents.
{ }
virtual ~OperationBase( void ) { }
virtual void print( FILE * oF ) const = 0;
virtual void execute(
StackDbl * uStack,
VarTable * uVars )
const = 0;
};
//
// The ';' operator:
// Check that stacksize == 0, and do nothing else.
//
class OperationSemicolon : public OperationBase
{
public:
OperationSemicolon( SContext const * iCxt ) :
OperationBase( iCxt ) { }
void print ( FILE * oF ) const;
void execute( StackDbl * uStack, VarTable * uVars ) const;
};
//
// Push the value of a variable onto stack.
//
class OperationPushVar : public OperationBase
{
int const cm_varIndex; //Index in VarTable of the variable to push.
public:
OperationPushVar( SContext const * iCxt, int iVarIndex ) :
OperationBase( iCxt ), cm_varIndex( iVarIndex ) { }
void print ( FILE * oF ) const;
void execute( StackDbl * uStack, VarTable * uVars ) const;
};
//
// Pop a value off stack, copy it into a variable.
//
class OperationPopVar : public OperationBase
{
int const cm_varIndex; //Index in VarTable of the variable to push.
public:
OperationPopVar( SContext const * iCxt, int iVarIndex ) :
OperationBase( iCxt ), cm_varIndex( iVarIndex ) { }
void print ( FILE * oF ) const;
void execute( StackDbl * uStack, VarTable * uVars ) const;
};
//
// Push a constant value onto stack.
//
class OperationPushConst : public OperationBase
{
double const cm_value;
public:
OperationPushConst( SContext const * iCxt, double iVal ) :
OperationBase( iCxt ), cm_value(iVal) { }
void print ( FILE * oF ) const;
void execute( StackDbl * uStack, VarTable * uVars ) const;
};
//
// Binary operations:
// Pop two operands, execute binary operation, push result.
//
class OperationBinAdd : public OperationBase
{
public:
OperationBinAdd( SContext const * iCxt ) : OperationBase( iCxt ) { }
void print ( FILE * oF ) const;
void execute( StackDbl * uStack, VarTable * uVars ) const;
};
class OperationBinSub : public OperationBase
{
public:
OperationBinSub( SContext const * iCxt ) : OperationBase( iCxt ) { }
void print ( FILE * oF ) const;
void execute( StackDbl * uStack, VarTable * uVars ) const;
};
class OperationBinMul : public OperationBase
{
public:
OperationBinMul( SContext const * iCxt ) : OperationBase( iCxt ) { }
void print ( FILE * oF ) const;
void execute( StackDbl * uStack, VarTable * uVars ) const;
};
class OperationBinDiv : public OperationBase
{
public:
OperationBinDiv( SContext const * iCxt ) : OperationBase( iCxt ) { }
void print ( FILE * oF ) const;
void execute( StackDbl * uStack, VarTable * uVars ) const;
};
class OperationBinPow : public OperationBase
{
public:
OperationBinPow( SContext const * iCxt ) : OperationBase( iCxt ) { }
void print ( FILE * oF ) const;
void execute( StackDbl * uStack, VarTable * uVars ) const;
};
#endif //_RPIMPL_OPER_H_