Skip to content

Commit

Permalink
Make enhancedComprehension the default
Browse files Browse the repository at this point in the history
  • Loading branch information
wcjohnson committed Oct 3, 2017
1 parent 787f2d7 commit 0510d65
Show file tree
Hide file tree
Showing 15 changed files with 78 additions and 21 deletions.
43 changes: 38 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ This is a **breaking change** to language semantics! Most user code should not b
#### 2. Syntax and other changes
The JS optional chaining proposal is still in rapid flux despite its position at Stage 1 in the standards process. There is considerable uncertainty on the final syntax. For that reason, we are delaying introducing any syntax changes at this time. Also, for the time being, `{safeCall: true}` is still required to enable safe calls.
The JS optional chaining proposal is still in rapid flux despite its position at Stage 1 in the standards process. There appears to be considerable uncertainty on the final syntax. For that reason, we are delaying introducing any syntax changes at this time. Also, for the time being, `{safeCall: true}` is still required to enable safe calls.
### Rationale:
Expand All @@ -87,9 +87,9 @@ LightScript upstream has indicated they will be accepting this feature, so it is
## Comprehensions
### Change
### Changes
When `{enhancedComprehension: true}` is enabled, comprehensions have a new syntax:
#### 1. Comprehensions have a new syntax:
```js
x = [
Expand All @@ -114,7 +114,11 @@ x = [
]
```

Object comprehensions no longer use tuples to represent object elements. Instead, an object expression that is effectively merged into the underlying object is provided:
The `case` keyword is no longer used.

#### 2. Object comprehensions no longer use tuples to represent object elements.

Instead, an object expression that is effectively merged into the underlying object is provided:

```js
reverse(obj) -> ({
Expand All @@ -124,7 +128,11 @@ reverse(obj) -> ({
})
```

The `case` keyword is no longer used.
#### 3. `{ enhancedComprehension: false }` enables the old syntax.

The new syntax is enabled by default in order to mesh with the new block parsing strategy. For enhanced backward compatibility with 0.5.9, passing `{ enhancedComprehension: false }` disables the new syntax and reverts to the old comprehension syntax.

This flag will be removed completely once LightScript upstream adopts the syntax.

### Rationale

Expand Down Expand Up @@ -187,6 +195,19 @@ unknown: Unexpected token (2:4)
}
```
#### 2. Labeled expressions are illegal
Applying a label to an expression will now result in an error:
```js
{
thisIsABlock()
label: expr
}
```
```js
Labeled expressions are illegal. (3:2)
```
### Rationale
It is easy for new LightScript users to get burned by the distinctions between objects and blocks of code in the LightScript grammar:
Expand All @@ -202,6 +223,8 @@ y = g()
The general intent of these changes is to eliminate these sorts of traps and edge cases. Ideally the output of the compiler should "just makes sense" and it is not necessary to remember the specific rules about how braces are parsed.
Labeled expressions increase the number of scenarios where objects and blocks can be confused with each other, and don't make much sense on their own, so they have been outlawed.
(In terms of the parser unit test suite, this change eliminated around 20 situations where LightScript was parsing vanilla JavaScript incorrectly, as well as four parsing situations labeled as `unfortunate` in the test suite itself.)
## `whiteblock` compiler option added.
Expand Down Expand Up @@ -236,3 +259,13 @@ In the simplest possible terms, `whiteblock` makes the compiler behave as if you
### Rationale
The context-sensitive brace parser is implemented using speculative branching, which can essentially double the amount of work the parser has to do in a lot of situations. This flag will greatly speed up the LightScript parser for those who use whitespace-sensitive syntax, as it is no longer necessary for the parser to speculate when encountering `{ }`.
##
### Change
### Rationale
This change
9 changes: 7 additions & 2 deletions src/config.lsc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ export getParserOpts(pluginOpts, initialParserOpts) ->
plugins = parserOpts.plugins

plugins.unshift("lightscript")
plugins.push("objectRestSpread", "asyncFunctions", "asyncGenerators", "classProperties", "classConstructorCall", "decorators", "dynamicImport", "doExpressions", "seqExprRequiresParen")
plugins.push(
"objectRestSpread", "asyncFunctions", "asyncGenerators"
"classProperties", "classConstructorCall", "decorators"
"dynamicImport", "doExpressions", "seqExprRequiresParen"
"noLabeledExpressionStatements"
)

if pluginOpts?.whiteblock:
if pluginOpts.whiteblock != "compat":
Expand All @@ -100,7 +105,7 @@ export getParserOpts(pluginOpts, initialParserOpts) ->
if pluginOpts?.bangCall != false: plugins.push("bangCall")
if not pluginOpts?.noEnforcedSubscriptIndentation: plugins.push("enforceSubscriptIndentation")
if pluginOpts?.flippedImports: plugins.push("flippedImports")
if pluginOpts?.enhancedComprehension: plugins.push("splatComprehension")
if pluginOpts?.enhancedComprehension != false: plugins.push("splatComprehension")
if pluginOpts?.placeholderArgs: plugins.push("syntacticPlaceholder")
if pluginOpts?.placeholder:
parserOpts.placeholder = pluginOpts.placeholder
Expand Down
4 changes: 2 additions & 2 deletions src/index.lsc
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ Lightscript(babel) ->
transformForInObjectStatement(path);

ArrayComprehension(path): void ->
if opts.enhancedComprehension:
if opts.enhancedComprehension != false:
comprehension.transformArrayComprehension(path)
else:
comprehension.transformPlainArrayComprehension(path)

ObjectComprehension(path): void ->
if opts.enhancedComprehension:
if opts.enhancedComprehension != false:
comprehension.transformObjectComprehension(path)
else:
comprehension.transformPlainObjectComprehension(path)
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/await-arrow/await-array/actual.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn() -/>
x <- [p1, p2]
const y = await [p1, p2]
<- [for const p of ps: p]
<- [...for const p of ps: p]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
for (let _i = 0, _len = arr.length; _i < _len; _i++) {
const x = arr[_i];1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
for (let _i = 0, _len = arr.length; _i < _len; _i++) {
const x = arr[_i];a, b, c;
}
}
3 changes: 3 additions & 0 deletions test/fixtures/comprehensions/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": [["lightscript", { "enhancedComprehension": false }]]
}
3 changes: 0 additions & 3 deletions test/fixtures/enhanced-comprehensions/options.json

This file was deleted.

6 changes: 3 additions & 3 deletions test/fixtures/examples/fizzbuzz.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fizzBuzz(n = 100) ->
arr

fizzBuzzComp(n = 100) ->
[for let i = 1; i < n+1; i++:
[...for let i = 1; i < n+1; i++:
if i % 3 == 0 and i % 5 == 0:
"fizzbuzz"
elif i % 3 == 0:
Expand All @@ -42,7 +42,7 @@ fizzBuzzMap(n = 100) ->
)

fizzBuzzMap2(n = 100) ->
[for let i = 1; i < n+1; i++: i].map(x ->
[...for let i = 1; i < n+1; i++: i].map(x ->
if x % 3 == 0 and x % 5 == 0: "fizzbuzz"
elif x % 3 == 0: "fizz"
elif x % 5 == 0: "buzz"
Expand All @@ -64,4 +64,4 @@ assert.deepEqual(fizzBuzz(), [1, 2, "fizz", 4, "buzz", "fizz", 7, 8, "fizz", "bu
assert.deepEqual(fizzBuzzComp(), [1, 2, "fizz", 4, "buzz", "fizz", 7, 8, "fizz", "buzz", 11, "fizz", 13, 14, "fizzbuzz", 16, 17, "fizz", 19, "buzz", "fizz", 22, 23, "fizz", "buzz", 26, "fizz", 28, 29, "fizzbuzz", 31, 32, "fizz", 34, "buzz", "fizz", 37, 38, "fizz", "buzz", 41, "fizz", 43, 44, "fizzbuzz", 46, 47, "fizz", 49, "buzz", "fizz", 52, 53, "fizz", "buzz", 56, "fizz", 58, 59, "fizzbuzz", 61, 62, "fizz", 64, "buzz", "fizz", 67, 68, "fizz", "buzz", 71, "fizz", 73, 74, "fizzbuzz", 76, 77, "fizz", 79, "buzz", "fizz", 82, 83, "fizz", "buzz", 86, "fizz", 88, 89, "fizzbuzz", 91, 92, "fizz", 94, "buzz", "fizz", 97, 98, "fizz", "buzz"]);
assert.deepEqual(fizzBuzzMap(), [1, 2, "fizz", 4, "buzz", "fizz", 7, 8, "fizz", "buzz", 11, "fizz", 13, 14, "fizzbuzz", 16, 17, "fizz", 19, "buzz", "fizz", 22, 23, "fizz", "buzz", 26, "fizz", 28, 29, "fizzbuzz", 31, 32, "fizz", 34, "buzz", "fizz", 37, 38, "fizz", "buzz", 41, "fizz", 43, 44, "fizzbuzz", 46, 47, "fizz", 49, "buzz", "fizz", 52, 53, "fizz", "buzz", 56, "fizz", 58, 59, "fizzbuzz", 61, 62, "fizz", 64, "buzz", "fizz", 67, 68, "fizz", "buzz", 71, "fizz", 73, 74, "fizzbuzz", 76, 77, "fizz", 79, "buzz", "fizz", 82, 83, "fizz", "buzz", 86, "fizz", 88, 89, "fizzbuzz", 91, 92, "fizz", 94, "buzz", "fizz", 97, 98, "fizz", "buzz"]);
assert.deepEqual(fizzBuzzMap(), [1, 2, "fizz", 4, "buzz", "fizz", 7, 8, "fizz", "buzz", 11, "fizz", 13, 14, "fizzbuzz", 16, 17, "fizz", 19, "buzz", "fizz", 22, 23, "fizz", "buzz", 26, "fizz", 28, 29, "fizzbuzz", 31, 32, "fizz", 34, "buzz", "fizz", 37, 38, "fizz", "buzz", 41, "fizz", 43, 44, "fizzbuzz", 46, 47, "fizz", 49, "buzz", "fizz", 52, 53, "fizz", "buzz", 56, "fizz", 58, 59, "fizzbuzz", 61, 62, "fizz", 64, "buzz", "fizz", 67, 68, "fizz", "buzz", 71, "fizz", 73, 74, "fizzbuzz", 76, 77, "fizz", 79, "buzz", "fizz", 82, 83, "fizz", "buzz", 86, "fizz", 88, 89, "fizzbuzz", 91, 92, "fizz", 94, "buzz", "fizz", 97, 98, "fizz", "buzz"]);
assert.deepEqual([for const x of fizzBuzzGen(): x], [1, 2, "fizz", 4, "buzz", "fizz", 7, 8, "fizz", "buzz", 11, "fizz", 13, 14, "fizzbuzz", 16, 17, "fizz", 19, "buzz", "fizz", 22, 23, "fizz", "buzz", 26, "fizz", 28, 29, "fizzbuzz", 31, 32, "fizz", 34, "buzz", "fizz", 37, 38, "fizz", "buzz", 41, "fizz", 43, 44, "fizzbuzz", 46, 47, "fizz", 49, "buzz", "fizz", 52, 53, "fizz", "buzz", 56, "fizz", 58, 59, "fizzbuzz", 61, 62, "fizz", 64, "buzz", "fizz", 67, 68, "fizz", "buzz", 71, "fizz", 73, 74, "fizzbuzz", 76, 77, "fizz", 79, "buzz", "fizz", 82, 83, "fizz", "buzz", 86, "fizz", 88, 89, "fizzbuzz", 91, 92, "fizz", 94, "buzz", "fizz", 97, 98, "fizz", "buzz"]);
assert.deepEqual([...for const x of fizzBuzzGen(): x], [1, 2, "fizz", 4, "buzz", "fizz", 7, 8, "fizz", "buzz", 11, "fizz", 13, 14, "fizzbuzz", 16, 17, "fizz", 19, "buzz", "fizz", 22, 23, "fizz", "buzz", 26, "fizz", 28, 29, "fizzbuzz", 31, 32, "fizz", 34, "buzz", "fizz", 37, 38, "fizz", "buzz", 41, "fizz", 43, 44, "fizzbuzz", 46, 47, "fizz", 49, "buzz", "fizz", 52, 53, "fizz", "buzz", 56, "fizz", 58, 59, "fizzbuzz", 61, 62, "fizz", 64, "buzz", "fizz", 67, 68, "fizz", "buzz", 71, "fizz", 73, 74, "fizzbuzz", 76, 77, "fizz", 79, "buzz", "fizz", 82, 83, "fizz", "buzz", 86, "fizz", 88, 89, "fizzbuzz", 91, 92, "fizz", 94, "buzz", "fizz", 97, 98, "fizz", "buzz"]);
4 changes: 2 additions & 2 deletions test/fixtures/examples/jsx/actual.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ otherCondition() -> true

ThingsList1({ things, selectedId }) =>
<ul>
{[for const thing of things:
{[...for const thing of things:
if thing.id == selectedId and otherCondition():
<SpecialThing thing={thing} />
else:
Expand All @@ -24,7 +24,7 @@ ThingsList2({ things, selectedId }) =>
ThingsList3({ things, selectedId }) =>
<ul>
{[
for elem thing in things {
...for elem thing in things {
if thing.id == selectedId and otherCondition() {
<SpecialThing thing={thing} />
} else {
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/for-in/nested-semantic.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ objExpr2() -> ({ key: "key" })
arrExpr3() -> [2,3]
obj4 = { key1: "value1", key2: "value2" }

result = [for elem i in arr1: for key k in objExpr2(): for idx j in arrExpr3(): for val l in obj4: [i,j,k,l]]
result = [...for elem i in arr1: for key k in objExpr2(): for idx j in arrExpr3(): for val l in obj4: [i,j,k,l]]

assert.deepEqual(result, [
[0, 0, "key", "value1"],
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/for-in/object-own-properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Constructor.prototype = { shouldntSee: 'me' }
obj = new Constructor
obj.shouldSee = 'this'

keys = [for const k in obj: k]
keys = [...for const k in obj: k]
assert.deepEqual(keys, ['shouldSee', 'shouldntSee'])

for key k in obj:
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/match/inside-comprehension/actual.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[for idx i in Array(10):
[...for idx i in Array(10):
match i:
| 1: 1
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
x
a: a + 1
c
if true: 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected , (5:5)"
}

0 comments on commit 0510d65

Please sign in to comment.