// 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 ) ); }