// rpimpl_oper.cpp
// Copyright (c) Menno Rubingh 2016. Web: [http://rubinghsoftware.de]
//
// MR Mar 2016.
//
// Implementation of the OperationXxx member functions.
//
//---
// Implementation notes:
// - Floating-point errors:
// This implementation internally does NO checking for floating-point errors
// at the point where the math operations are executed.
// Rationale: to maximize processing speed of the RPInterpreter::evaluate().
// Further explanation and rationale is given in the text file
// 'rpinterpreter_doc_floatingPointErrors.txt' which should be contained among the
// sources.
// - The execute() member functions are not implemented as inline functions,
// because in this software the member functions of the OperationXxx derived
// classes are called exclusively via pointers to the base class OperationBase.
// In such a case, inlining is impossible.
//
#include "rpimpl_oper.h" //OperationXxx.
#include <stdio.h>
#include <math.h> //pow().
//------------------------------------------------------------------------------------
// The print() member functions.
//------------------------------------------------------------------------------------
void OperationSemicolon:: print( FILE * oF ) const
{
fprintf( oF, "semicol" );
}
void OperationPushVar:: print( FILE * oF ) const
{
fprintf( oF, "pushV[%c]", VarTable::indexToName(cm_varIndex) );
}
void OperationPopVar:: print( FILE * oF ) const
{
fprintf( oF, "popV[%c]", VarTable::indexToName(cm_varIndex) );
}
void OperationPushConst:: print( FILE * oF ) const
{
fprintf( oF, "pushC[%g]", cm_value );
}
void OperationBinAdd :: print( FILE * oF ) const
{
fprintf( oF, "binAdd" );
}
void OperationBinSub:: print( FILE * oF ) const
{
fprintf( oF, "binSub" );
}
void OperationBinMul :: print( FILE * oF ) const
{
fprintf( oF, "binMul" );
}
void OperationBinDiv :: print( FILE * oF ) const
{
fprintf( oF, "binDiv" );
}
void OperationBinPow :: print( FILE * oF ) const
{
fprintf( oF, "binPow" );
}
//------------------------------------------------------------------------------------
// The execute() member functions.
//------------------------------------------------------------------------------------
void OperationSemicolon:: execute(
StackDbl * uStack,
VarTable * uVars ) const
{
if ( uStack->getN() != 0 )
{
throw Ex( &cm_cxt, "stacksize != 0 at semicolon" );
}
}
void OperationPushVar:: execute(
StackDbl * uStack,
VarTable * uVars ) const
{
double val = uVars->getByIndex( cm_varIndex );
uStack->push( &cm_cxt, val );
}
void OperationPopVar:: execute(
StackDbl * uStack,
VarTable * uVars ) const
{
double val = uStack->pop( &cm_cxt );
uVars->putByIndex( cm_varIndex, val );
}
void OperationPushConst:: execute(
StackDbl * uStack,
VarTable * uVars ) const
{
uStack->push( &cm_cxt, cm_value );
}
void OperationBinAdd:: execute(
StackDbl * uStack,
VarTable * uVars ) const
{
double valR = uStack->pop( &cm_cxt );
double valL = uStack->pop( &cm_cxt );
uStack->push( &cm_cxt, valL + valR );
}
void OperationBinSub:: execute(
StackDbl * uStack,
VarTable * uVars ) const
{
double valR = uStack->pop( &cm_cxt );
double valL = uStack->pop( &cm_cxt );
uStack->push( &cm_cxt, valL - valR );
}
void OperationBinMul:: execute(
StackDbl * uStack,
VarTable * uVars ) const
{
double valR = uStack->pop( &cm_cxt );
double valL = uStack->pop( &cm_cxt );
uStack->push( &cm_cxt, valL * valR );
}
void OperationBinDiv:: execute(
StackDbl * uStack,
VarTable * uVars ) const
{
double valR = uStack->pop( &cm_cxt );
double valL = uStack->pop( &cm_cxt );
uStack->push( &cm_cxt, valL / valR );
}
void OperationBinPow:: execute(
StackDbl * uStack,
VarTable * uVars ) const
{
double valR = uStack->pop( &cm_cxt );
double valL = uStack->pop( &cm_cxt );
uStack->push( &cm_cxt, pow( valL, valR ) );
}