Click here to Skip to main content
15,887,683 members
Articles / Programming Languages / C#

An extensible math expression parser with plug-ins

Rate me:
Please Sign up or sign in to vote.
4.92/5 (147 votes)
13 Mar 2008CPOL51 min read 1.4M   29K   364  
Design and code for an extensible, maintainable, robust, and easy to use math parser.
#ifndef _PLUGINFUNC_INCLUDED
#define _PLUGINFUNC_INCLUDED

#include "..\MTParserLib\MTParserDef.h"
#include <math.h>


class SinFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::sin"); }

	virtual MTSTRING getHelpString(){ return _T("pl::sin(x)"); }
	virtual MTSTRING getDescription(){ return _T("Sine"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return sin(pArg[0]); }	

};


class ArcSinFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::asin"); }

	virtual MTSTRING getHelpString(){ return _T("pl::asin(x)"); }
	virtual MTSTRING getDescription(){ return _T("Arcsine"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return asin(pArg[0]); }

};

class SinhFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::sinh"); }

	virtual MTSTRING getHelpString(){ return _T("pl::sinh(x)"); }
	virtual MTSTRING getDescription(){ return _T("Hyperbolic sine"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return sinh(pArg[0]); }

};

class CosFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::cos"); }

	virtual MTSTRING getHelpString(){ return _T("pl::cos(x)"); }
	virtual MTSTRING getDescription(){ return _T("Cosine"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return cos(pArg[0]); }

};

class ArcCosFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::acos"); }

	virtual MTSTRING getHelpString(){ return _T("pl::acos(x)"); }
	virtual MTSTRING getDescription(){ return _T("Arccosine"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return acos(pArg[0]); }

};

class CoshFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::cosh"); }

	virtual MTSTRING getHelpString(){ return _T("pl::cosh(x)"); }
	virtual MTSTRING getDescription(){ return _T("Hyperbolic cosine"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return cosh(pArg[0]); }

};

class TanFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::tan"); }

	virtual MTSTRING getHelpString(){ return _T("pl::tan(x)"); }
	virtual MTSTRING getDescription(){ return _T("Tangent"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return tan(pArg[0]); }

};

class TanhFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::tanh"); }

	virtual MTSTRING getHelpString(){ return _T("pl::tanh(x)"); }
	virtual MTSTRING getDescription(){ return _T("Hyperbolic tangent"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return tanh(pArg[0]); }

};

class ArcTanFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::atan"); }

	virtual MTSTRING getHelpString(){ return _T("pl::atan(x)"); }
	virtual MTSTRING getDescription(){ return _T("Arctangent"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return atan(pArg[0]); }

};

class SqrtFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::sqrt"); }

	virtual MTSTRING getHelpString(){ return _T("pl::sqrt(x)"); }
	virtual MTSTRING getDescription(){ return _T("Square root"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 
		
		return sqrt(pArg[0]); 		
	}
};

class MinFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::min"); }

	virtual MTSTRING getHelpString(){ return _T("pl::min(x,y)"); }
	virtual MTSTRING getDescription(){ return _T("Return smaller of two values"); }	
	virtual int getNbArgs(){ return 2; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 
		return min(pArg[0],pArg[1]); 
	}

};

class Min3Fct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::min"); }

	virtual MTSTRING getHelpString(){ return _T("pl::min(x,y,z)"); }
	virtual MTSTRING getDescription(){ return _T("Return smaller of three values"); }	
	virtual int getNbArgs(){ return 3; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 
		return min(min(pArg[0],pArg[1]), pArg[2]); 
	}

};

class MinUndefFct : public IMathFunction
{		

	virtual MTSTRING getSymbol(){return _T("pl::min"); }

	virtual MTSTRING getHelpString(){ return _T("pl::min(v1,v2,v3,...)"); }
	virtual MTSTRING getDescription(){ return _T("Return smaller of a set of values"); }	
	virtual int getNbArgs(){ return c_NbArgUndefined; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{
		EXPR_VALTYPE min = pArg[0];
		
		for( int t=1; t<nbArgs; t++ )
		{
			if( pArg[t] < min )
			{
				min = pArg[t];
			}
		}

		return min;
	}
};

class MaxFct : public IMathFunction
{		

	virtual MTSTRING getSymbol(){return _T("pl::max"); }

	virtual MTSTRING getHelpString(){ return _T("pl::max(x,y)"); }
	virtual MTSTRING getDescription(){ return _T("Return larger of two values"); }	
	virtual int getNbArgs(){ return 2; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 		
		return max(pArg[0],pArg[1]); 
	}
};

class Max3Fct : public IMathFunction
{		

	virtual MTSTRING getSymbol(){return _T("pl::max"); }

	virtual MTSTRING getHelpString(){ return _T("pl::max(x,y,z)"); }
	virtual MTSTRING getDescription(){ return _T("Return larger of three values"); }	
	virtual int getNbArgs(){ return 3; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 		
		return max(max(pArg[0],pArg[1]), pArg[2]); 
	}
};

class MaxUndefFct : public IMathFunction
{		

	virtual MTSTRING getSymbol(){return _T("pl::max"); }

	virtual MTSTRING getHelpString(){ return _T("pl::max(v1,v2,v3,...)"); }
	virtual MTSTRING getDescription(){ return _T("Return larger of a set of values"); }	
	virtual int getNbArgs(){ return c_NbArgUndefined; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{
		EXPR_VALTYPE max = pArg[0];
		
		for( int t=1; t<nbArgs; t++ )
		{
			if( pArg[t] > max )
			{
				max = pArg[t];
			}
		}

		return max;
	}
};

class AbsFct : public IMathFunction
{		

	virtual MTSTRING getSymbol(){return _T("pl::abs"); }

	virtual MTSTRING getHelpString(){ return _T("pl::abs(x)"); }
	virtual MTSTRING getDescription(){ return _T("Absolute value"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 
		
		return fabs(pArg[0]); 
	}
};

class RandFct : public IMathFunction
{		

	virtual MTSTRING getSymbol(){return _T("pl::rand"); }

	virtual MTSTRING getHelpString(){ return _T("pl::rand()"); }
	virtual MTSTRING getDescription(){ return _T("Random value between 0 and 1"); }	
	virtual int getNbArgs(){ return 0; }

	virtual bool isConstant(){ return false; }

	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 				
		return rand()/(double)RAND_MAX; 
	}
};

class RandMinMaxFct : public IMathFunction
{		

	virtual MTSTRING getSymbol(){return _T("pl::rand"); }

	virtual MTSTRING getHelpString(){ return _T("pl::rand(min, max)"); }
	virtual MTSTRING getDescription(){ return _T("Random value between min and max"); }	
	virtual int getNbArgs(){ return 2; }

	virtual bool isConstant(){ return false; }

	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 				
		return pArg[0]+(rand()/(double)RAND_MAX)*(pArg[1]-pArg[0]); 
	}
};

class LogFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::log"); }

	virtual MTSTRING getHelpString(){ return _T("pl::log(x)"); }
	virtual MTSTRING getDescription(){ return _T("Natural logarithm"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return log(pArg[0]); }

};

class Log10Fct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::log10"); }

	virtual MTSTRING getHelpString(){ return _T("pl::log10(x)"); }
	virtual MTSTRING getDescription(){ return _T("Base-10 logarithm"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return log(pArg[0]); }

};

class CeilFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::ceil"); }

	virtual MTSTRING getHelpString(){ return _T("pl::ceil(x)"); }
	virtual MTSTRING getDescription(){ return _T("Ceiling"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return ceil(pArg[0]); }

};

class FloorFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::floor"); }

	virtual MTSTRING getHelpString(){ return _T("pl::floor(x)"); }
	virtual MTSTRING getDescription(){ return _T("Floor"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg){ return floor(pArg[0]); }

};

class AvgFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::avg"); }

	virtual MTSTRING getHelpString(){ return _T("pl::avg(v1,v2,v3,...)"); }
	virtual MTSTRING getDescription(){ return _T("Return the average of a set of values"); }	
	virtual int getNbArgs(){ return c_NbArgUndefined; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 
		EXPR_VALTYPE val = 0;

		for( int t=0; t<nbArgs; t++ )
		{
			val += pArg[t];

		}
		return val / nbArgs; 
	}

};


class SumFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::sum"); }

	virtual MTSTRING getHelpString(){ return _T("pl::sum(v1,v2,v3,...)"); }
	virtual MTSTRING getDescription(){ return _T("Return the sum of a set of values"); }	
	virtual int getNbArgs(){ return c_NbArgUndefined; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 
		EXPR_VALTYPE val = 0;

		for( int t=0; t<nbArgs; t++ )
		{
			val += pArg[t];

		}
		return val; 
	}

};

class FactorialFct : public IMathFunction
{		
	
	virtual MTSTRING getSymbol(){return _T("pl::fact"); }

	virtual MTSTRING getHelpString(){ return _T("pl::fact(x)"); }
	virtual MTSTRING getDescription(){ return _T("Return the factorial of x: x*(x-1)*(x-2)*...(x-x+1)"); }	
	virtual int getNbArgs(){ return 1; }
	virtual EXPR_VALTYPE evaluate(unsigned int nbArgs, const EXPR_VALTYPE *pArg)
	{ 
		int val = pArg[0];
		int res = val;

		if( val <= 0 )
		{
			return 0;
		}	

		val--;
		for( ; val>1; val-- )
		{
			res *= val;
		}
		
		return res; 
	}

};

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Canada Canada
Software Engineer working at a fun and smart startup company

Comments and Discussions