LINUX.ORG.RU

[javascript] Результат выполнения блока

 


0

1

В ECMAScript Language Specification есть такое понятие, как Block (стр. 86):

Syntax
Block : { StatementList_opt }
StatementList : Statement StatementList Statement
Semantics

The production Block : { } is evaluated as follows:
1. Return (normal, empty, empty).

The production Block : { StatementList } is evaluated as follows:
1. Return the result of evaluating StatementList.

The production StatementList : Statement is evaluated as follows:
1. Let s be the result of evaluating Statement.
2. If an exception was thrown, return (throw, V, empty) where V is the exception. (Execution now proceeds as if no exception were thrown.)
3. Return s.

The production StatementList : StatementList Statement is evaluated as follows:
1. Let sl be the result of evaluating StatementList.
2. If sl is an abrupt completion, return sl.
3. Let s be the result of evaluating Statement.
4. If an exception was thrown, return (throw, V, empty) where V is the exception. (Execution now proceeds as if no exception were thrown.)
5. If s.value is empty, let V = sl.value, otherwise let V = s.value.
6. Return (s.type, V, s.target).

Насколько я понял этот текст, результатом интерпретации выражения { foo(); bar(); 10 } будет 10. Когда пишу такое выражение в REPL-е хромиума или фаербага, то в ответ получаю 10, что совпадает с моим пониманием спецификации.

Вопросы:

1. Почему результатом интерпретации { foo(); bar(); 10 } + 1 является 1?

2. Можно получить результат интерпретации блока через eval: eval('{ foo(); bar(); 10 }') + 1 == 11. Можно ли как-нибудь без eval-а обойтись?

Если интересно, для чего мне это нужно: хочу исправить баг в библиотеке clojurejs. Из (alert (if true (do (alert) «boom») «bam»)) она генерирует alert((true ? alert(); «boom»; : «bam»)), что неправильно. Если бы что-то типа этого alert((true ? { alert(); «boom» } : «bam»)) парсилось и работало, то фикс был бы тривиальным.


разве что оборачивать в

(function(){  return lastExpr})()
. А так это было бы сказкой чтобы то что ты пишешь работало :(

bga_ ★★★★
()

и все равно будут проблемы вроде

if(1) 2; else 4;

bga_ ★★★★
()
Ответ на: комментарий от bga_

> разве что оборачивать в (function(){ return lastExpr})()

Спасибо за идею, так и сделаю.

А так это было бы сказкой чтобы то что ты пишешь работало :(

С утра почитал спецификацию, и действительно, Block - это Statement, и никак его нельзя использовать там, где интерпретатор ждет Expression.

и все равно будут проблемы вроде if(1) 2; else 4;

Всмысле?

nozh
() автор топика
Ответ на: комментарий от nozh

Ну так в REPL результат будет или 2 или 4 в зависимости от ложности условия. Причем у eval тоже поведение.

bga_ ★★★★
()
Ответ на: комментарий от bga_

> Еще как более короткая альтернатива можно посмотерть на comma operator

Не подходит. Внутри формы do могут быть выражения, которые будут скомпилированы в Statement, например цикл. А оператор запятая определен только для Expression-ов.

nozh
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.