int eeeprintDotTree(antlr::RefAST tree, std::ostream& out, antlr::Parser& p) {
	int me = ++_dot_node;
	out << me << " [label=\"" << p.getTokenName(tree->getType())
		<< "\\n" << tree->getText() << "\"];" << std::endl;
	antlr::RefAST c = tree->getFirstChild();
	while (antlr::nullAST != c) {
		int child = printDotTree(c, out, p);
		out << me << " -> " << child << ";" << std::endl;
		c = c->getNextSibling();
	}
	return me;
}
double getValue( antlr::RefAST &refAST ) {

	switch( refAST->getType() ) {

		case MExprParserTokenTypes::ADD :
		case MExprParserTokenTypes::SUB :
		{
			std::string op = refAST->getText();

			antlr::RefAST child1 = refAST->getFirstChild();
			double value1 = getValue( child1 );
			if (  ISNAN( value1 )  ) return std::numeric_limits< double >::quiet_NaN();

			antlr::RefAST child2 = child1->getNextSibling();
			if ( child2 == antlr::nullAST ) {
				return op == "+" ? value1 : -value1;
			}
			double value2 = getValue( child2 );
			if (  ISNAN( value2 )  ) return std::numeric_limits< double >::quiet_NaN();

			return op == "+" ? value1 + value2 : value1 - value2;
		}

		case MExprParserTokenTypes::MUL :
		case MExprParserTokenTypes::DIV :
		case MExprParserTokenTypes::MOD :
		{
			std::string op = refAST->getText();
			antlr::RefAST child1 = refAST->getFirstChild();
			double value1 = getValue( child1 );
			if (  ISNAN( value1 )  ) return std::numeric_limits< double >::quiet_NaN();

			antlr::RefAST child2 = child1->getNextSibling();
			double value2 = getValue( child2 );
			if (  ISNAN( value2 )  ) return std::numeric_limits< double >::quiet_NaN();

			if ( op == "*" ) return value1 * value2;
			if ( op == "/" ) return value1 / value2;

			// MOD (%)
			if ( value2 == 0 ) return std::numeric_limits< double >::quiet_NaN();
			return static_cast< int >( value1 ) % static_cast< int >( value2 );
		}

		case MExprParserTokenTypes::VAR :
		{
			std::string op = refAST->getText();
			if ( op == "pi" ) return M_PI;
			if ( op == "e" ) return M_E;
			return std::numeric_limits< double >::quiet_NaN();
		}

		case MExprParserTokenTypes::NUM :
		{
			std::string num = refAST->getText();
			return atof( num.c_str() );
		}

	}

	return std::numeric_limits< double >::quiet_NaN();
}