Open dead-claudia opened 5 years ago
BTW, to clarify, the intent isn't to extend, but just to simplify and compress. There's only two things I added:
let
/const
. This specifically ends the TDZ for its assignee(s) and assigns the value to the target pattern.void expr
and the new "initialize" node (let foo
without initializers), but it also provides a plugin point for minifiers to produce a better engine hint.These two added could really be considered replacements for let
/const
and void
, respectively, and don't really add anything that wouldn't have existed before.
I'm reflecting back on the AST and the overzealous #37 and thinking I could probably narrow it down a bit further. JS has a lot of cases where there's multiple ways to do things and it semantically makes no difference even in the general case:
function foo() { ... }
vsvar foo
+foo = function foo() { ... }
at the top of the enclosing block's scopeexport class Foo { ... }
vsexport {Foo}; class Foo { ... }
and similarimport foo, * as Foo from "mod"
vsimport foo from "mod"; import * as Foo from "mod"
import foo from "mod"
vsimport {default as foo} from "mod"
export {foo, bar}
vsexport {foo}; export {bar}
export {foo}
vsexport {foo as foo}
var foo = ...
vslet foo
at the top of the enclosing function's scope +foo = ...
void expr
vs(expr, void 0)
undefined
,Infinity
,NaN
, and similar), they could be converted to literalseval
expressions can't possibly be broken or continued from. These might as well be nixed, and you could always create synthetic blocks as necessary.{foo: foo}
vs{foo}
- Gzip can remove the redundancy if we let it.{foo: 1}
vs{"foo": 1}
,{1: foo}
vs{"1": foo}
, etc.x => result
vsx => { return result }
There's also a few cases where the spec ends up complicating encoding if followed to the letter.
export default 1
in the spec is desugared tovar *default*; *default* = 1; export {*default* as default}
, where*default*
is a spec-internal production. You could get away with replacing this withdefault
and simplify it some -default
is still a reserved keyword.void 0
.import ... from "mod"
andexport ... from "mod"
.So I'm thinking the AST could be reduced to a smaller, significantly more easily parsed and consumed subset so engines can realize parsing gains much quicker.
Directives would just be strings. The node type isn't used anywhere as far as I can tell.
The only things that can carry labels are block statements and loops. Labeled statements that contain
eval
or ado
expression should just emit a synthetic block.Modules would be reduced to this:
import "mod"
orexport ... from "mod"
)*
forexport * from "mod"
, or empty string if no named importFunction bodies would be reduced to this:
this
as applicableGetter/setter bodies would be reduced to this:
this
as applicableStatement lists would be reduced to this:
eval
Declared variables would be unified to either
let
orconst
, with novar
s permitted.void expr
is represented identically to(expr, undefined)
, but using theundefined
literal production rather than theundefined
value.Unlabeled
break
/continue
statements could just have their "label" set to the impossible empty string.To simplify/streamline initialization, it'd have its own node type, mirroring assignment functionally. A node can't be assigned more than once.
And to simplify the spec, statement lists should be generally unified.
Of course there's ways to further reduce this (reducing block labels to
break depth
), but most of that's beyond the scope of this bug. I'm just looking at stuff that still mirrors JS while removing the duplication.