Spawn proposal strawman
Brendan Eich
brendan at mozilla.com
Sat May 9 11:57:03 PDT 2009
On May 9, 2009, at 9:19 AM, David-Sarah Hopwood wrote:
> kevin curtis wrote:
>> Re:
>> eval.hermetic(program :(string | AST), thisValue, optBindings) :any
>>
>> Is a 'canonical' AST part of the plans for ecmascript 6/harmony.
>
> I hope so; that would be extremely useful. I would like to see an
> ECMAScript source -> AST parser (as well as an AST evaluator) in the
> Harmony standard library.
We've wanted this since early in ES4 days. It would help many projects
and experimental extensions (type checkers, template systems, macro
processors, etc.) to have a standard AST, which could be serialized to
JSON.
The AST should not be lowered much, if at all. I believe users will
want to capture idioms and nuances in the source. As you've noted re:
+= and kin, the language has high-level compound semantics without a
low form that can express Reference (lvalue) computation, [[Put]], etc.
I am thinking of implementing support for a JSON-friendly AST in
SpiderMonkey to speed up Narcissus (hat tip: Blake Kaplan suggested
this). Thus Narcissus could use the host JS compiler to produce ASTs
it then interprets (as it currently produces trees, slowly, using its
own self-hosted regexp-based lexer and recursive-descent/operator-
precedence parser). I'll post a link to the bug so people can track
progress if they are interested.
With some successful experiments, perhaps we can converge quickly on a
standardizable high-level AST.
Suggestions welcome on any issues that crop up. Here's one: && and ||
want to group to the right, for short-circuiting evaluation, yet the
ES1-5 grammars use standard left-recursive bottom-up-style productions:
LogicalORExpression: See 11.11
LogicalANDExpression
LogicalORExpression || LogicalANDExpression
This will produce a tree for X || Y || Z shaped like this initializer
(skipping tedious quoting of property names):
{op: "||",
left: {op: "||",
left: {op: "Id", value: "X"},
right: {op: "Id", value: "Y"}},
right: {op: "Id", value: "Z"}}
A definitional interpreter the recursively evaluates nodes can handle
this easily enough, although the right-recursive AST alternative,
which is equivalent AFAIK, would be better for avoiding recursion. A
simple code generator, on the other hand, definitely wants the right-
recursive tree:
{op: "||",
left: {op: "Id", value: "Z"},
right: {op: "||",
left: {op: "Id", value: "X"},
right: {op: "Id", value: "Y"}}}
so that, at each recursion level, branches to the next bytecode after
the expression can be emitted and fixed up using local variables only.
Of course backpatching could be used (and must be used for other
control structures in the language), but all else equal, || and &&
want to be right-associated in the AST.
Users chain || and && with the same op, without parentheses. GCC-
nagged programmers know to parenthesize && against || even though &&
is higher precedence, to avoid a warning.
The issue here seems to be that the ES1-5 grammar over-specify the AST
in some cases. If we do standardize the AST, then we have to choose,
and I'm in favor of right association for these logical connective
ops, since they short-circuit evaluation based on truthiness (||) or
falsiness (&&) of the left operand. Thoughts?
/be
More information about the es-discuss
mailing list