statement values

  • Thread starter florian.loitsch
  • Start date
F

florian.loitsch

According to the spec Section 14 the production
SourceElements:SourceElements SourceElement is evaluated as follows:
1. Evaluate SourceElements.
2. If Result(1) is an abrupt completion, return Result(1)
3. Evaluate SourceElement.
4. Return Result(3).

If I understood correctly the following program should alert
'undefined':
alert(eval('3;;'));
The last source-element would be ";" (the empty statement), and this
statement returns 'empty' as value (12.3) which is then transformed to
'undefined' by the eval (15.1.2.1).
All engines I tried (Rhino, FF and Konqueror) however return '3', as
if the the evaled body was in a block. (According to 12.1 inside a
block the last statement not returning 'empty' is used as return
value).
Is this a bug in these engines, or did I misinterpret the spec?

Another question for VariableDeclarations:
Why does the production 'VariableDeclaration: Identifier' and the
production
'VariableDeclaration: Identifier Initialiser' return a sequence of
characters? I can't find how these strings could be used.

mfg,
// florian loitsch
 
D

Doug Gunnoe

According to the spec Section 14 the production
SourceElements:SourceElements SourceElement is evaluated as follows:

Could you elaborate a little more on what you are talking about? What
'spec' do you mean? JavaScript specification?
If I understood correctly the following program should alert
'undefined':
alert(eval('3;;'));
The last source-element would be ";" (the empty statement), and this
statement returns 'empty' as value (12.3) which is then transformed to
'undefined' by the eval (15.1.2.1).
All engines I tried (Rhino, FF and Konqueror) however return '3', as
if the the evaled body was in a block. (According to 12.1 inside a
block the last statement not returning 'empty' is used as return
value).

So you are talking about how various JavaScript implementations parse
the script in an instances such as this? And I suppose in particular
how it deals with ';'?
 
D

Doug Gunnoe

According to the spec Section 14 the production
SourceElements:SourceElements SourceElement is evaluated as follows:
1. Evaluate SourceElements.
2. If Result(1) is an abrupt completion, return Result(1)
3. Evaluate SourceElement.
4. Return Result(3).

If I understood correctly the following program should alert
'undefined':
alert(eval('3;;'));
The last source-element would be ";" (the empty statement), and this
statement returns 'empty' as value (12.3) which is then transformed to
'undefined' by the eval (15.1.2.1).
All engines I tried (Rhino, FF and Konqueror) however return '3', as
if the the evaled body was in a block. (According to 12.1 inside a
block the last statement not returning 'empty' is used as return
value).
Is this a bug in these engines, or did I misinterpret the spec?

Another question for VariableDeclarations:
Why does the production 'VariableDeclaration: Identifier' and the
production
'VariableDeclaration: Identifier Initialiser' return a sequence of
characters? I can't find how these strings could be used.

mfg,
// florian loitsch

alert(eval('')); returns undefined as does alert(eval(';'));

I suppose all of this may have something to do with the fact that ';'
are not needed in javascript.

But alert(eval('3\n\n')) returns three also.

Humm.
 
T

Thomas 'PointedEars' Lahn

Doug said:
Could you elaborate a little more on what you are talking about? What
'spec' do you mean? JavaScript specification?

(Sometimes when you don't have a single clue what the other person is
talking about, it is better not to reply at all.) There is no JavaScript
specification. The OP is referring to the ECMAScript Specification, of
which Netscape/Mozilla.org's JavaScript is one implementation.

http://jibbering.com/faq/


PointedEars
 
T

Thomas 'PointedEars' Lahn

Doug said:
According to the spec Section 14 the production
SourceElements:SourceElements SourceElement is evaluated as follows:
1. Evaluate SourceElements.
2. If Result(1) is an abrupt completion, return Result(1)
3. Evaluate SourceElement.
4. Return Result(3).

If I understood correctly the following program should alert
'undefined':
alert(eval('3;;'));
The last source-element would be ";" (the empty statement), and this
statement returns 'empty' as value (12.3) which is then transformed to
'undefined' by the eval (15.1.2.1).
All engines I tried (Rhino, FF and Konqueror) however return '3', as
if the the evaled body was in a block. (According to 12.1 inside a
block the last statement not returning 'empty' is used as return
value).
Is this a bug in these engines, or did I misinterpret the spec?
[...]

alert(eval('')); returns undefined as does alert(eval(';'));

I suppose all of this may have something to do with the fact that ';'
are not needed in javascript.

But alert(eval('3\n\n')) returns three also.

You miss the point, which is the evaluation of the program "3;;".

Please trim your quotes.


PointedEars
 
D

Doug Gunnoe

(Sometimes when you don't have a single clue what the other person is
talking about, it is better not to reply at all.) There is no JavaScript
specification.

Sometimes when all you have to say is some smart ass comment, it is
probably best not to reply at all. Of course, in your case that would
mean you would never have anything to say.
The OP is referring to the ECMAScript Specification, of
which Netscape/Mozilla.org's JavaScript is one implementation.

You must be proud of being so smart.

I wish I was as smart as you.

But until I'm as smart as you, I'm going to refer to it as the
JavaScript specification. Because, in my lesser mind, even though
ECMAScript is the standard, it would be the JavaScript specification.
And it is also the JScript specification. And any other
implementation.
You miss the point, which is the evaluation of the program "3;;".

No. I'm right at the crux of the question, which in this case really
comes down to this part of the OP's question
The last source-element would be ";" (the empty statement), and this
statement returns 'empty' as value (12.3) which is then transformed to
'undefined' by the eval (15.1.2.1).

his question comes down to, why is this ";" not treated like an empty
statement and if this is an error in the implementations. In many
languages, like C++ or Java, having just this ";" is a perfectly legal
but 'empty statement', however, it does not appear to be an 'empty
statement' for JavaScript. My answer was:
I suppose all of this may have something to do with the fact that ';'
are not needed in javascript.

So, in C++ I could have:

some code blah blah blah;
;

And the second ";" is a legal but empty statement and does not cause a
compile error. And the ';' is required to demarcate the end of the
statement.

In JavaScript I can do

some code blah blah blah
some more code
some more code

or,
some code blah blah blah;
some more code;
some more code;

The ';' is optional.

Care to take a stab at answering the OP's question, or would you
prefer just to make a few more Ad Homs toward me?

Specifically, what demarcates a complete legal statement in JavaScript
and what would be an empty statement in JavaScript?

I suspect that an empty line would be the equivalent of an empty
statement in JavaScript, but I am not sure.
 
V

VK

According to the spec Section 14 the production
SourceElements:SourceElements SourceElement is evaluated as follows:
1. Evaluate SourceElements.
2. If Result(1) is an abrupt completion, return Result(1)
3. Evaluate SourceElement.
4. Return Result(3).

If I understood correctly the following program should alert
'undefined':
alert(eval('3;;'));
The last source-element would be ";" (the empty statement), and this
statement returns 'empty' as value (12.3) which is then transformed to
'undefined' by the eval (15.1.2.1).
All engines I tried (Rhino, FF and Konqueror) however return '3', as
if the the evaled body was in a block. (According to 12.1 inside a
block the last statement not returning 'empty' is used as return
value).
Is this a bug in these engines, or did I misinterpret the spec?

The specs are kind of OK, you are just mixing the runtime code
execution and source text parsing. Semicolons do not constitute
expressions in JavaScript: they are just "parsing helpers" for the
parser when it analysis the source code and extracting separate tokens
to be further executed, so their usage comes prior any actual
execution (the syntax errors stage, other words).

This way a set of statements like:
3;;2;;1;;
first being parsed and valid tokens extracted:
[evaluate 3] [evaluate 2] [evaluate 1]
and this set of tokens is being executed on demands. Semicolons do not
exist on the execution stage: nor they add any extra tokens per se no
matter how many of them you may place one by one in the row.

To get the effect you were expecting you should write something like:

alert(eval('3;;2;;1;;undefined;')||'undefined');
 
T

Thomas 'PointedEars' Lahn

VK said:
According to the spec Section 14 the production
SourceElements:SourceElements SourceElement is evaluated as follows:
1. Evaluate SourceElements.
2. If Result(1) is an abrupt completion, return Result(1)
3. Evaluate SourceElement.
4. Return Result(3).

If I understood correctly the following program should alert
'undefined':
alert(eval('3;;'));
The last source-element would be ";" (the empty statement), and this
statement returns 'empty' as value (12.3) which is then transformed to
'undefined' by the eval (15.1.2.1).
All engines I tried (Rhino, FF and Konqueror) however return '3', as
if the the evaled body was in a block. (According to 12.1 inside a
block the last statement not returning 'empty' is used as return
value).
Is this a bug in these engines, or did I misinterpret the spec?

The specs are kind of OK, you are just mixing the runtime code
execution and source text parsing. Semicolons do not constitute
expressions in JavaScript: they are just "parsing helpers" for the
parser [...]

Wrong. The first semicolon is part of the StatementExpression that consists
of the NumericLiteral followed by the semicolon. The second semicolon does
indeed constitute what is produced by the EmptyStatement production.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Doug said:
[...] I'm going to refer to [the ECMAScript Specification] as the
JavaScript specification. Because, in my lesser mind, even though
ECMAScript is the standard, it would be the JavaScript specification.
And it is also the JScript specification. And any other
implementation.

You have yet to understand what it means when something is called an
ECMAScript implementation. But as you insist, I am not going to prevent
you making a fool out of yourself.


Score adjusted

PointedEars
 
V

VK

The specs are kind of OK, you are just mixing the runtime code
execution and source text parsing. Semicolons do not constitute
expressions in JavaScript: they are just "parsing helpers" for the
parser [...]

Wrong. The first semicolon is part of the StatementExpression that consists
of the NumericLiteral followed by the semicolon. The second semicolon does
indeed constitute what is produced by the EmptyStatement production.

If you are referring to "12.3 Empty Statement" then this is plain bs
to disregard: it shows nothing but poor understanding by authors the
subject they had to write on. Obviously they considered the semicolon
as some kind of "statement" or "statement formant", other words
something that exists or leaves some signs *at runtime* so to be
"evaluated".

Again: the JavaScript production is semi-similar - in the most generic
sense of course - to Java. In Java we have raw source as .java file
and .class bytecode parsed out of the raw source to be served to the
client. Client-side this intermediary bytecode finally gets converted
to the machine execution code.
JavaScript is served as raw source right away to client and
"bytecode" (sequence of tokens) is being made client-side right on
arrival. No attempt to execute this code is made on this stage, the
parser is only cares if a valid sequence of valid tokens can be made
from the received source. If any error on this stage then one gets one
of syntax errors. Semicolons do participate in this stage by helping
to extract tokens from the source but they do not go into resulting
execution code - lets keep calling it "bytecode" though formally it is
not a correct term. This way there is not any EmptyExpression to be
"evaluated". Other words source code like:
function foo() {
;;;;;;;;;;;;;;;;;;;;;;;;;
return true;
}
and
function foo() {
return true;
}
after being parsed are giving byte-exact the same block to be
executed.

It also mean btw that
alert(eval('3\n2\n\n'));
and
alert(eval('3;2;;'));
eval operates with exactly the same block received from the parser
which is byte-exact is we would simply use:
alert(eval('3;2'));
 
D

Doug Gunnoe

You have yet to understand what it means when something is called an
ECMAScript implementation.  But as you insist, I am not going to prevent
you making a fool out of yourself.

Score adjusted

I understand exactly what it means Thomas. Do you spend your whole day
being a presumptuous ass, are do you have other tricks?
 
D

Doug Gunnoe

but they do not go into resulting execution code

Which would explain the behavior of the eval function in this case.
Thanks VK for your insightful and knowledgeable post and for actually
addressing the OP's question.
 
D

Doug Gunnoe

You have yet to understand what it means when something is called an
ECMAScript implementation. But as you insist, I am not going to prevent
you making a fool out of yourself.
Score adjusted

I understand exactly what it means Thomas. Do you spend your whole
day
being a presumptuous ass, or do you have other tricks?
 
T

Thomas 'PointedEars' Lahn

Doug said:
I understand exactly what it means Thomas.

No, you don't. If you did, you would not only have recognized section 2 of
the ECMAScript Specification but also the number of differences between the
implementations that result from that, which we have discussed here ad
nauseam before.

http://PointedEars.de/scripts/es-matrix
Do you spend your whole day being a presumptuous ass, [...]

I leave that to people who are more skilled in it.


Please provide an attribution line as also recommended in the FAQ.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Doug said:
Which would explain the behavior of the eval function in this case.
Thanks VK for your insightful and knowledgeable post and for actually
addressing the OP's question.

ROTFL. YMMD.


PointedEars
 
D

Doug Gunnoe

No, you don't.

Sure I do.
If you did, you would not only have recognized section 2 of
the ECMAScript Specification

Why is that? Your statement was
You have yet to understand what it means when something is called an
ECMAScript implementation.

Yeah, a 'specification' is such a very difficult concept to grasp.
Congratulations on being smart.
but also the number of differences between the
implementations that result from that,

In the context of the question from the OP, there was no difference in
the results he was getting from the implementations he tested. From
the OP:
All engines I tried (Rhino, FF and Konqueror) however return '3', as
if the the evaled body was in a block. (According to 12.1 inside a
block the last statement not returning 'empty' is used as return
value).
Thomas
I leave that to people who are more skilled in it.

Oh, you are skilled at it.

And thanks for contributing nothing to the discussion.
 
J

John G Harris

According to the spec Section 14 the production
SourceElements:SourceElements SourceElement is evaluated as follows:
1. Evaluate SourceElements.
2. If Result(1) is an abrupt completion, return Result(1)
3. Evaluate SourceElement.
4. Return Result(3).

If I understood correctly the following program should alert
'undefined':
alert(eval('3;;'));
The last source-element would be ";" (the empty statement), and this
statement returns 'empty' as value (12.3) which is then transformed to
'undefined' by the eval (15.1.2.1).
All engines I tried (Rhino, FF and Konqueror) however return '3', as
if the the evaled body was in a block. (According to 12.1 inside a
block the last statement not returning 'empty' is used as return
value).
Is this a bug in these engines, or did I misinterpret the spec?
<snip>

It looks like a bug, somewhere.

You're using statements indirectly as arguments in a function call. This
is sufficiently peculiar that you should expect either an unexpected
result, or a bug in the engine, or a bug in the specification. I think
it best to suspect the last of these. It's another example of eval being
evil.

John
 
J

John G Harris

On Thu, 3 Jan 2008 at 14:01:20, in comp.lang.javascript, wrote:

Another question for VariableDeclarations:
Why does the production 'VariableDeclaration: Identifier' and the
production
'VariableDeclaration: Identifier Initialiser' return a sequence of
characters? I can't find how these strings could be used.

I suspect the answer is that well known reason "It seemed a good idea at
the time".

There is some slight excuse. The code that sets up an execution scope
needs to know the names of the variables it must create. The rule for
executing a VariableDeclaration : Identifier statement during
execution gives the name that was needed. It's a pretty feeble excuse.

John
 
J

John G Harris

On Sat, 5 Jan 2008 at 10:52:40, in comp.lang.javascript, VK wrote:

If you are referring to "12.3 Empty Statement" then this is plain bs
to disregard: it shows nothing but poor understanding by authors the
subject they had to write on. Obviously they considered the semicolon
as some kind of "statement" or "statement formant", other words
something that exists or leaves some signs *at runtime* so to be
"evaluated".

Again: the JavaScript production is semi-similar - in the most generic
sense of course - to Java. In Java we have raw source as .java file
and .class bytecode parsed out of the raw source to be served to the
client. Client-side this intermediary bytecode finally gets converted
to the machine execution code.
JavaScript is served as raw source right away to client and
"bytecode" (sequence of tokens) is being made client-side right on
arrival. No attempt to execute this code is made on this stage, the
parser is only cares if a valid sequence of valid tokens can be made
from the received source. If any error on this stage then one gets one
of syntax errors. Semicolons do participate in this stage by helping
to extract tokens from the source but they do not go into resulting
execution code - lets keep calling it "bytecode" though formally it is
not a correct term. This way there is not any EmptyExpression to be
"evaluated".
<snip>

Here's an example that destroys VK's argument :

if (x)
;
else
x = 3;

The lonely semicolon must be translated into code that jumps over the
'else' part. It can't be thrown away by the parser and forgotten.

Incidentally, that semicolon can't be left out. If you want to do
nothing you have to write the semicolon to show you really mean it.

John
 
V

VK

Here's an example that destroys VK's argument :

if (x)
;
else
x = 3;

The lonely semicolon must be translated into code that jumps over the
'else' part. It can't be thrown away by the parser and forgotten.

Right the opposite, it makes my case even stronger (about some free-
lancers filling some - but not all - specs templates back in 90's).

First of all you are getting _syntax_ error. If you are getting
_syntax_ error we are by definition not dealing with the _execution_
problems.

Secondly try this code instead:

<script>
if (false) \u000A else true
alert('Parser is happy');
</script>

Thirdly make yourself a memory dump at runtime (or ask someone to
prepare it for you) to make sure that:

1) if (false) \u000A else true

2) if (false)
;
else
true

3) if (false) {} else {true}

on the execution stage are being resulted into byte-to-byte exactly
the same scavengers.

The major problem of ECMAScript specs is that starting from the first
page and till the last line they couldn't take a decision what are
they writing: a description of a standard-compliant engine, language
syntax description or a programmer's guide. As the result we are
having now a very esoteric book there the narration goes from internal
parsing to if-else usage, then to suggested var naming, then back to
the internal engine mechanics and so on. It doesn't make it wrong: it
just make it a very confusing source to learn the language itself. My
suggestion would be for anyone studying the language to pretend for
the first year at least that there is not ECMA specs at all.

P.S.
Incidentally, that semicolon can't be left out. If you want to do
nothing you have to write the semicolon to show you really mean it.

I don't really like to torture the syntax like that :) To do nothing
simply use brackets:

if (something) {} else {do_this();}

or better yet use assembly style, that makes your code more readable
and easier to alter in the future:

if (something) {
/* NOP */
}
else {
do_this();
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,602
Members
45,182
Latest member
BettinaPol

Latest Threads

Top