Clarification of Operand in Variable Assignment - javascript

I am doing this for the benefit of Javascript but the knowledge and terms cross all languages I would imagine. This is why I included JAVA and C as programmers knowledge on the subject from these fields are generally higher level.
If the question has been posed and answered, kindly just let me know.
I understand the basics of operators and operands.
1 + 2 = 3
1 and 2 are the operands and + is the operator. Solutions to the expression are not considered operands as they are the returned value.
If I am wrong with this summary please let me know
My question is that in assigning a value to variable
var x = 1
Is the variable considered to be the operand in this instance? My guess would be yes, as x is being assigned via an operator the value 1. But is it not, or are both x and 1 the operands with = being the assignment operator as the solution is x is now 1.

= is a simple assignment operator that assigns values from right side operands to the variable on the left side.
Example: x = y + z will assign value of y + z into x
So it is clear that = is an operator having left and right sides as operands.

The java spec tells us the following about the assignment operator:
The result of the first operand of an assignment operator must be a variable
So yes, the left hand side of the assignment operator is an operand.
A little further on we can read:
Next, the right hand operand is evaluated.
So the right hand side is an operand too!
Although i don't know why it would be important to know if the java developers call the left/right hand side of an assignment an 'operand' or not!

Related

How to make a chained comparison in Jison (or Bison)

I'm working on a expression parser made in Jison, which supports basic things like arithmetics, comparisons etc. I want to allow chained comparisons like 1 < a < 10 and x == y != z. I've already implemented the logic needed to compare multiple values, but I'm strugling with the grammar – Jison keeps grouping the comparisons like (1 < a) < 10 or x == (y != z) and I can't make it recognize the whole thing as one relation.
This is roughly the grammar I have:
expressions = e EOF
e = Number
| e + e
| e - e
| Relation %prec '=='
| ...
Relation = e RelationalOperator Relation %prec 'CHAINED'
| e RelationalOperator Relation %prec 'NONCHAINED'
RelationalOperator = '==' | '!=' | ...
(Sorry, I don't know the actual Bison syntax, I use JSON. Here's the entire source.)
The operator precedence is roughly: NONCHAINED, ==, CHAINED, + and -.
I have an action set up on e → Relation, so I need that Relation to match the whole chained comparison, not only a part of it. I tried many things, including tweaking the precedence and changing the right-recursive e RelationalOperator Relation to a left-recursive Relation RelationalOperator e, but nothing worked so far. Either the parser matches only the smallest Relation possible, or it warns me that the grammar is ambiguous.
If you decided to experiment with the program, cloning it and running these commands will get you started:
git checkout develop
yarn
yarn test
There are basically two relatively easy solutions to this problem:
Use a cascading grammar instead of precedence declarations.
This makes it relatively easy to write a grammar for chained comparison, and does not really complicate the grammar for binary operators nor for tight-binding unary operators.
You'll find examples of cascading grammars all over the place, including most programming languages. A reasonably complete example is seen in this grammar for C expressions (just look at the grammar up to constant_expression:).
One of the advantages of cascading grammars is that they let you group operators at the same precedence level into a single non-terminal, as you try to do with comparison operators and as the linked C grammar does with assignment operators. That doesn't work with precedence declarations because precedence can't "see through" a unit production; the actual token has to be visibly part of the rule with declared precedence.
Another advantage is that if you have specific parsing needs for chained operators, you can just write the rule for the chained operators accordingly; you don't have to worry about it interfering with the rest of the grammar.
However, cascading grammars don't really get unary operators right, unless the unary operators are all at the top of the precedence hierarchy. This can be seen in Python, which uses a cascading grammar and has several unary operators low in the precedence hierarchy, such as the not operator, leading to the following oddity:
>>> if False == not True: print("All is well")
File "<stdin>", line 1
if False == not True: print("All is well")
^
SyntaxError: invalid syntax
That's a syntax error because == has higher precedence than not. The cascading grammar only allows an expression to appear as the operand of an operator with lower precedence than any operator in the expression, which means that the expression not True cannot be the operand of ==. (The precedence ordering allows not a == b to be grouped as not (a == b).) That prohibition is arguably ridiculous, since there is no other possible interpretation of False == not True other than False == (not True), and the fact that the precedence ordering forbids the only possible interpretation makes the only possible interpretation a syntax error. This doesn't happen with precedence declarations, because the precedence declaration is only used if there is more than one possible parse (that is, if there is really an ambiguity).
Your grammar puts not at the top of the precedence hierarchy, although it should really share that level with unary minus rather than being above unary minus [Note 1]. So that's not an impediment to using a cascading grammar. However, I see that you also want to implement an if … then … else operator, which is syntactically a low-precedence prefix operator. So if you wanted 4 + if x then 0 else 1 to have the value 5 when x is false (rather than being a syntax error), the cascading grammar would be problematic. You might not care about this, and if you don't, that's probably the way to go.
Stick with precedence declarations and handle the chained comparison as an exception in the semantic action.
This will allow the simplest possible grammar, but it will complicate your actions a bit. To implement it, you'll want to implement the comparison operators as left-associative, and then you'll need to be able to distinguish in the semantic actions between a comparison (which is a list of expressions and comparison operators) from any other expression (which is a string). The semantic action for a comparison operator needs to either extend or create the list, depending on whether the left-hand operand is a list or a string. The semantic action for any other operator (including parenthetic grouping) and for the right-hand operand in a comparison needs to check if it has received a list, and if so compile it into a string.
Whichever of those two options you choose, you'll probably want to fix the various precedence errors in the existing grammar, some of which were already present in your upstream source (like the unary minus / not confusion mentioned above). These include:
Exponentiation is configured as left-associative, whereas it is almost universally considered a right-associative operator. Many languages also make it higher precedence than unary minus, as well, since -a2 is pretty well always read as the negative of a squared rather than the square of minus a (which would just be a squared).
I suppose you are going to ditch the ternary operator ?: in favour of your if … then … else operator. But if you leave ?: in the grammar, you should make it right associative, as it is in every language other than PHP. (And the associativity in PHP is generally recognised as a design error. See this summary.)
The not in operator is actually two token, not and in, and not has quite high precedence. And that's how it will be parsed by your grammar, with the result that 4 + 3 in (7, 8) evaluates to true (because it was grouped as (4 + 3) in (7, 8)), while 4 + 3 not in (7, 8) evaluates rather surprisingly to 5, having been grouped as 4 + (3 not in (7, 8)).
Notes
If you used a cascading precedence grammar, you'd see that only one of - not 0 and not - 0 is parseable. Of course, both are probably type violations, but that's not something the syntax should concern itself with.

POSTFIX and PREFIX increment/decrement precedence in JavaScript

I've been coding for years and suddenly stuck to some simple thing about operators precedence in case of increment/decrement operators.
According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
the postfix increment/decrement has higher priority than the prefix one.
So, I expect that in expression
x = --a + a++;
the increment will be calculated first and only after that the decrement.
But, in tests this expression calculates left-to-right like that operators have the same priority. And as result
a=1;x = --a + a++ equals to 0 instead of 2.
Ok. Assuming that prefix/postfix operators have the same precedence, I try to reorder it with parentheses:
a=1;x = --a + ( a++ )
But again, the result will be 0 and not 2 as I expected.
Can someone explain that please? why parentheses here do not affect anything? How can I see that postfix has higher precedence than prefix?
In the expression, evaluation proceeds like this:
--a is evaluated. The variable a is decremented, and the value of --a is therefore 0.
a++ is evaluated. The value of a is obtained, and then a is incremented. The value of a++ is therefore 0.
The + operation is performed, and the result is 0.
The final value of a is 1.
Because --a and a++ are on either side of the lower-precedence + operator, the difference in precedence between pre-decrement and post-increment doesn't matter; the + operator evaluates the left-hand subexpression before it evaluates the right-hand subexpression.
Operator precedence is not the same thing as evaluation order.
Operator precedence tells you that
f() + g() * h()
is parsed as
f() + (g() * h())
(because * has higher precedence than +), but not which function is called first. That is controlled by evaluation order, which in JavaScript is always left-to-right.
Parentheses only override precedence (i.e. they affect how subexpressions are grouped), not order of evaluation:
(f() + g()) * h()
performs addition before multiplication, but in all cases f is called first and h last.
In your example
--a + a++
the relative precedence of prefix -- and postfix ++ doesn't matter because they're not attached to the same operand. Infix + has much lower precedence, so this expression parses as
(--a) + (a++)
As always, JS expressions are evaluated from left to right, so --a is done first.
If you had written
--a++
that would have been parsed as
--(a++)
(and not (--a)++) because postfix ++ has higher precedence, but the difference doesn't matter here because either version is an error: You can't increment/decrement the result of another increment/decrement operation.
However, in the operator precedence table you can see that all prefix operators have the same precedence, so we can show an alternative:
// ! has the same precedence as prefix ++
!a++
is valid code because it parses as !(a++) due to postfix ++ having higher precedence than !. If it didn't, it would be interpreted as (!a)++, which is an error.
Well, it strange, but looks like increment/decrement behaves in expressions like a function call, not like an operator.
I could not find any documentation regarding order of function evaluations in expression, but looks like it ignores any precedence rules. So strange expression like that:
console.log(1) + console.log(2)* ( console.log(3) + console.log(4))
will show 1234 in console. That the only explanation I could found why parentheses do not affect to order of evaluation of dec/inc in expressions

Javascript operator ||0? [duplicate]

This question already has answers here:
JavaScript OR (||) variable assignment explanation
(12 answers)
Closed 5 years ago.
I'm trying to translate a Javascript function to C# when I encountered something I've never seen before:
return (a / (b - (c * G * (d || 0)))) || 0;
C# is complaining about the d || 0 portion being applied to floating point number, and I have no idea what that Javascript operator does. (in C#, it's a logical OR)
Edit: all variables are floating point numbers.
The || operator returns the expression on the left side if that expression is truthy, otherwise it returns the expression on the right side. It's commonly used like this to specify default/fallback values, for instance, when a number is expected but the provided variable might contain undefined or null. It's also commonly used when optional arguments can be passed to a function and the function want's to simply use the first one that's truthy.
|| is the "short-circuited" OR operator and in order for it to work, both operands must first be evaluated as Booleans. From left to right, the value of the first expression that can be converted to true is returned (the original value, not the converted Boolean).
JavaScript will perform an implicit conversion to determine the "truthiness" of each operand if necessary, but C# will not. A float in C# is invalid with this operator because C# is a strongly-typed language and implicit conversions do not occur. You would have to explicitly cast your float to a Boolean to be able to use this operator in C#.
In C#, you'd need:
((bool) d || 0)
|| (OR)operator works when both the operands are Boolean. If not then JavaScript tries to implicitly convert it and perform the OR operation.
You need to explicitly cast in C#.

Javascript: concatenation with "," doesn't work

<button onclick="rzut()" />
<div id="wynik" />
<script type="text/javascript">
function rzut() {
document.getElementById("wynik").innerHTML = "Wynik to",Math.floor(Math.random()*6)+1;
}
</script>
For an unknown reason my script show only "Wynik to" and it skips the next part (math.floor etc)
Okay, let's go over some basics.
The first thing I would like to bring up is the concept of an Overloaded Operator. An overloaded operator, in short, is an operator that has different behaviour for different operands. An example of an overloaded operator in Javascript is +. For example:
var x = 4 + 4;
// x = 8
As you can see, adding two numeric values has the effect of summing the fields. But what about..
var x = "4" + "4";
// x = "44";
Well, because the types are strings, it behaves differently, hence it has an overloaded behaviour.
The + symbol will summate numeric values, but concatenate string values.
Bringing this forward to your example, you want to end up with a string value like..
"Wynik to,3"
Where 3 can vary. So let's look at it like this..
"Wynik to,X"
where X is some variable. Well.. this means you've got to build the string on the fly.. So following your approach (and not using some of the nice ES6 features that have been introduced), you can use our friendly overloaded + to accomplish this..
"Wynik to," + X
Where X is some random number between 1 and 6 therefore..
"Wynik to " + (Math.floor(Math.random()*6)+1);
So you'll see here, we've got a numeric value on the right hand side and a string value on the left hand side.
What Javascript does in this situation is what's known as arithmetic promotion, where all operands are promoted to the precision of the highest operand.
In this case, the right hand side of the equation is promoted to a string. Then, as we've seen above, our overloaded operator knows what to do with two strings.

What is the purpose for multiple comma-separated expressions in a WHILE condition?

I stumbled over the following JavaScript:
Code:
var x="", i=0;
while (i<4, i<7, i<5, i<6)
{
x=x + "The number is " + i + "<br>";
i++;
}
document.write(x);
I never know that it is possible to use multiple comma-separated expression in one WHILE statement.
Result:
The number is 0
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
What is the reason for this and what is the behavior (only the last expression is evaluated for the while-exit)?
Is the behavior standardize in all Javascript/C/Java languages?
Only the last result is kept in result of the comma operator, so
while (i<4, i<7, i<5, i<6)
is really equivalent to
while (i<6)
That's the reason why you don't see this more often : it's useless if your comparisons don't have side effects.
This is a special operator in JavaScript which is called comma operator;
so when JavaScript comes across this line
(i<4, i<7, i<5, i<6)
it will evaluate one by one all the operands in the parenthesis and will return the evaluation of the last item i.e. i < 6
It is rarely used; One occasion that I remember to have used it was for indirect call to eval.
(0, eval)(src)
But again in you example the use of it is redundant.

Categories

Resources