context.defineVariable(varName, rightValue);  /* * Return value of assignment is the assigned value.
if (t.mLeftBranch.mIsLeaf) {  String varName = t.mLeftBranch.mLeafArg.getVariableName(); context.defineVariable(varName, rightValue); } else {  String hashMapName = t.mLeftBranch.mLeftBranch.mLeafArg.getVariableName(); Argument key = traverse(t.mLeftBranch.mRightBranch, context, interpreterFilename); if (key.getType() != Argument.NUMERIC && key.getType() != Argument.STRING) { throw new MapyrusException(MapyrusMessages.get(MapyrusMessages.INVALID_HASHMAP_KEY)); } context.defineHashMapEntry(hashMapName, key.getStringValue(), rightValue); }  /* * Return value assigned.
		private Argument traverse(ExpressionTreeNode t, ContextStack context,			String interpreterFilename) throws MapyrusException		{			Argument retval;			Argument leftValue, rightValue;			int returnType = Argument.NUMERIC;			double l, r, d = 0.0;			String s = null;			if (t.mIsLeaf)			{				/*				 * Evaluate any variable name.  Variables that are not assigned				 * are given the value of an empty string (which converts to the				 * numeric value 0), like in awk(1) and Perl.				 */				if (t.mLeafArg.getType() == Argument.VARIABLE)				{					retval = context.getVariableValue(t.mLeafArg.getVariableName(), interpreterFilename);					if (retval == null)						retval = Argument.emptyString;				}				else				{					retval = t.mLeafArg;				}			}			else if (t.mIsFunction)			{				retval = t.evaluateFunction(context, interpreterFilename);			}			else if (t.mOperation == NOT_OPERATION)			{				/*				 * Negation operates on a single expression.				 */				leftValue = traverse(t.mLeftBranch, context, interpreterFilename);				if (leftValue.getType() == Argument.NUMERIC)				{					l = leftValue.getNumericValue();					retval = NumericalAnalysis.equals(l, 0.0) ?						Argument.numericOne : Argument.numericZero;				}				else				{					retval = (leftValue.getStringValue().length() == 0) ?						Argument.numericOne : Argument.numericZero;				}			}			else if (t.mOperation == ASSIGN_OPERATION)			{				String varName = t.mLeftBranch.mLeafArg.getVariableName();				rightValue = traverse(t.mRightBranch, context, interpreterFilename);				context.defineVariable(varName, rightValue);				/*				 * Return value of assignment is the assigned value.				 */				retval = rightValue;			}			else			{				/*				 * Either expression can be a number or a string.				 */				leftValue = traverse(t.mLeftBranch, context, interpreterFilename);				rightValue = traverse(t.mRightBranch, context, interpreterFilename);				switch (t.mOperation)				{				case PLUS_OPERATION:					d = leftValue.getNumericValue() + rightValue.getNumericValue();					returnType = Argument.NUMERIC;					break;				case CONCAT_OPERATION:					s = leftValue.toString() + rightValue.toString();					returnType = Argument.STRING;					break;				case MINUS_OPERATION:					d = leftValue.getNumericValue() - rightValue.getNumericValue();					returnType = Argument.NUMERIC;					break;				case MULTIPLY_OPERATION:					d = leftValue.getNumericValue() * rightValue.getNumericValue();					returnType = Argument.NUMERIC;					break;				case REPEAT_OPERATION:					/*					 * Repeat string N times.					 */					StringBuffer sb = new StringBuffer();					int repeatCount = (int)(Math.floor(rightValue.getNumericValue()));					for (int i = 0; i < repeatCount; i++)					{						sb.append(leftValue.toString());					}					s = sb.toString();					returnType = Argument.STRING;					break;				case DIVIDE_OPERATION:					d = leftValue.getNumericValue() / rightValue.getNumericValue();					returnType = Argument.NUMERIC;					break;				case MODULO_OPERATION:					d = NumericalAnalysis.fmod(leftValue.getNumericValue(),						rightValue.getNumericValue());					returnType = Argument.NUMERIC;					break;				case NUMERIC_EQUALS_OPERATION:					l = leftValue.getNumericValue();					r = rightValue.getNumericValue();					d = NumericalAnalysis.equals(l, r) ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case NUMERIC_NOT_EQUALS_OPERATION:					l = leftValue.getNumericValue();					r = rightValue.getNumericValue();					d = NumericalAnalysis.equals(l, r) ? 0 : 1;					returnType = Argument.NUMERIC;					break;				case NUMERIC_GREATER_THAN_OPERATION:					l = leftValue.getNumericValue();					r = rightValue.getNumericValue();					d = (l > r && (!NumericalAnalysis.equals(l, r))) ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case NUMERIC_GREATER_EQUAL_OPERATION:					l = leftValue.getNumericValue();					r = rightValue.getNumericValue();					d = (l > r || NumericalAnalysis.equals(l, r)) ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case NUMERIC_LESS_THAN_OPERATION:					l = leftValue.getNumericValue();					r = rightValue.getNumericValue();					d = (l < r && (!NumericalAnalysis.equals(l, r))) ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case NUMERIC_LESS_EQUAL_OPERATION:					l = leftValue.getNumericValue();					r = rightValue.getNumericValue();					d = (l < r || NumericalAnalysis.equals(l, r)) ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case AND_OPERATION:					d = (leftValue.getNumericValue() != 0 &&						rightValue.getNumericValue() != 0) ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case OR_OPERATION:					d = (leftValue.getNumericValue() != 0 ||						rightValue.getNumericValue() != 0) ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case LEXICAL_EQUALS_OPERATION:					d = leftValue.toString().equals(rightValue.toString()) ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case LEXICAL_NOT_EQUALS_OPERATION:					d = leftValue.toString().equals(rightValue.toString()) ? 0 : 1;					returnType = Argument.NUMERIC;					break;				case LEXICAL_GREATER_THAN_OPERATION:					d = leftValue.toString().compareTo(rightValue.toString()) > 0 ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case LEXICAL_GREATER_EQUAL_OPERATION:					d = leftValue.toString().compareTo(rightValue.toString()) >= 0 ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case LEXICAL_LESS_THAN_OPERATION:					d = leftValue.toString().compareTo(rightValue.toString()) < 0 ? 1 : 0;					returnType = Argument.NUMERIC;					break;				case LEXICAL_LESS_EQUAL_OPERATION:					d = leftValue.toString().compareTo(rightValue.toString()) <= 0 ? 1 : 0;					returnType = Argument.NUMERIC;					break;				}				if (returnType == Argument.NUMERIC)				{					/*					 * Fail on numeric overflow and divide by zero.					 */					if (Double.isInfinite(d) || Double.isNaN(d))						throw new MapyrusException(MapyrusMessages.get(MapyrusMessages.NUMERIC_OVERFLOW));					if (d == 0.0)						retval = Argument.numericZero;					else if (d == 1.0)						retval = Argument.numericOne;					else						retval = new Argument(d);				}				else				{					if (s.length() == 0)						retval = Argument.emptyString;					else						retval = new Argument(Argument.STRING, s);				}			}			return(retval);		}