Bug - Not A Bug Implicit conversion bug or Incorrect User Expectation

fronobulax

Developer
Staff member
Code:
> ashq int a =1; int b = 2; print("ans "+ b - a);

Operator '-' applied to string operands ()

I would have expected "ans 1" which is what is returned if the concatenation with "ans " is removed.

also

Code:
> ashq int a =1; int b = 2; print("ans "+ (b - a));

ans 1

which makes me think the args are being converted to strings before evaluating the arithmetic operator. Could be an error in my expectations.
 

fredg1

Member
they are. the first datatype of the group (string + int - int) is seen to be a string, and so the following ints are converted to strings, AFAIK.
 

fredg1

Member
Code:
> ashq int a =1; int b = 2; print(b - a + " = ans " + a - b);

[COLOR="#FF0000"]Operator '-' applied to string operands ()[/COLOR]

Anything after a string is converted to a string
 

Veracity

Developer
Staff member
The "+" operator can be used arithmetically or for string concatenation.
The "-" operator can be used only arithmetically.

"+" and "-" have the same operator strength. That means that when we are parsing an expression, we evaluate operands from left to right and apply the respective operators in order.

1 + 2 - 3 + 4 - 5
=> ( ( (1 + 2 ) - 3 ) + 4 ) - 5
NOT 1 + ( 2 - ( 3 + ( 4 - 5 ) ) )

Code:
[color=green]> ashq print( 1 + 2 - 3 + 4 - 5 )[/color]

-1
does what you expect because the whole expression is arithmetic and is coerced to a string at the end. But as soon as you put in a string, you are starting the string concatenation immediately.

Here is Java'a operator precedence table .

Notice that at level 11, there are + and - (additive) and also + (string concatenation) and operands are evaluated left to right.

Here is ASH's operator precedence table.

ASH's operator precedence is coded in Operator.java:

Code:
	private int operStrength()
	{
		if (this.operator.equals(Parser.POST_INCREMENT) ||
				this.operator.equals(Parser.POST_DECREMENT))
		{
			return 14;
		}

		if ( this.operator.equals( "!" ) ||
		     this.operator.equals( "~" ) ||
		     this.operator.equals( "contains" ) ||
		     this.operator.equals( "remove" ) ||
				this.operator.equals(Parser.PRE_INCREMENT) ||
				this.operator.equals(Parser.PRE_DECREMENT))
		{
			return 13;
		}

		if ( this.operator.equals( "**" ) )
		{
			return 12;
		}

		if ( this.operator.equals( "*" ) ||
		     this.operator.equals( "/" ) ||
		     this.operator.equals( "%" ) )
		{
			return 11;
		}

		if ( this.operator.equals( "+" ) ||
		     this.operator.equals( "-" ) )
		{
			return 10;
		}

		if ( this.operator.equals( "<<" ) ||
		     this.operator.equals( ">>" ) ||
		     this.operator.equals( ">>>" ) )
		{
			return 9;
		}

		if ( this.operator.equals( "<" ) ||
		     this.operator.equals( ">" ) ||
		     this.operator.equals( "<=" ) ||
		     this.operator.equals( ">=" ) )
		{
			return 8;
		}

		if ( this.operator.equals( "==" ) ||
		     this.operator.equals( Parser.APPROX ) ||
		     this.operator.equals( "!=" ) )
		{
			return 7;
		}

		if ( this.operator.equals( "&" ) )
		{
			return 6;
		}

		if ( this.operator.equals( "^" ) )
		{
			return 5;
		}

		if ( this.operator.equals( "|" ) )
		{
			return 4;
		}

		if ( this.operator.equals( "&&" ) )
		{
			return 3;
		}

		if ( this.operator.equals( "||" ) )
		{
			return 2;
		}

		if ( this.operator.equals( "?" ) ||
		     this.operator.equals( ":" ) )
		{
			return 1;
		}

		return -1;
	}
As I said, "+" and "-" are at the same level. We do not distinguish in this method between "arithmetic +" and and "concatenation +".

I also notice that the Wiki's table has a number of "reserved for" levels which are now implemented. :)
I think your expectations are incorrect.

That said, if we wanted, we could presumably define Parser.CONCAT and use that operator when we see "+" and the lhs is a string. But I don't want to do that; if you are famliar with Java expressions, ASH expressions should be familiar to you. Let's not create an exception.
 
Top