Skip to content

Commit

Permalink
feature: goldstein: add if let
Browse files Browse the repository at this point in the history
  • Loading branch information
coderaiser committed Oct 19, 2023
1 parent e574fb3 commit 0b4756a
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 16 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,12 +344,20 @@ Object.freeze({

You can omit parens. But you must use braces in this case.

```rust
```swift
if a > 3 {
hello();
}
```

Also you can use `if let` syntax:

```swift
if let x = a?.b {
print(x);
}
```

### `throw expression`

You can use [throw as expression](https://github.com/tc39/proposal-throw-expressions), just like that:
Expand Down
1 change: 1 addition & 0 deletions packages/convert/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ test('goldstein: convert: add-array', (t) => {
t.equal(result, expected);
t.end();
});

21 changes: 21 additions & 0 deletions packages/goldstein/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,27 @@ test('goldstein: parse: append array', (t) => {
t.end();
});

test('goldstein: parse: if let', (t) => {
const result = compile(montag`
if let a = b?.c {
log(a);
}
`);

const expected = montag`
{
let a = b?.c;
if (a) {
log(a);
}
}\n
`;

t.equal(result, expected);
t.end();
});

test('goldstein: parse: import', (t) => {
const result = compile(montag`
import hello from './hello.gs';
Expand Down
5 changes: 5 additions & 0 deletions packages/keyword-if/fixture/if-let.gs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
let a = 5;

if let x = john.info?.name {
print(x);
}
9 changes: 9 additions & 0 deletions packages/keyword-if/fixture/if-let.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let a = 5;

{
let x = john.info?.name;

if (x) {
print(x);
}
}
88 changes: 73 additions & 15 deletions packages/keyword-if/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,85 @@ import {setGoldsteinIf} from '../types/if.js';

export default function fn(Parser) {
return class extends Parser {
parseIfStatement(node) {
parseIfStatement() {
this.next();

const isParenL = this.eat(tt.parenL);

node.test = this.parseExpression();
const isParenR = this.eat(tt.parenR);

if (!isParenL && !isParenR && this.type !== tt.braceL)
this.raise(this.start, `Use braces ('{', '}') when omit parens ('(', ')')`);

if (isParenL !== isParenR)
this.raise(this.start, `Use both parens ('(', ')') or none`);
if (this.isContextual('let'))
return createIfLet.call(this, {
isParenL,
});

node.consequent = this.parseStatement('if');
node.alternate = this.eat(tt._else) ? this.parseStatement('if') : null;
const test = this.parseExpression();

setGoldsteinIf(node);

return this.finishNode(node, 'IfStatement');
return createIf.call(this, {
test,
isParenL,
});
}
};
}

function check({isParenL, isParenR}) {
if (!isParenL && !isParenR && this.type !== tt.braceL)
this.raise(this.start, `Use braces ('{', '}') when omit parens ('(', ')')`);

if (isParenL !== isParenR)
this.raise(this.start, `Use both parens ('(', ')') or none`);
}

function createIfLet({isParenL}) {
this.next();
this.eat(tt.assign);

const assignmentExpression = this.parseExpression();
const isParenR = this.eat(tt.parenR);

check.call(this, {
isParenL,
isParenR,
});

const ifNode = createIf.call(this, {
test: assignmentExpression.left,
isParenL,
});

const node = {
loc: {},
range: [],
body: [{
type: 'VariableDeclaration',
kind: 'let',
declarations: [{
type: 'VariableDeclarator',
id: assignmentExpression.left,
init: assignmentExpression.right,
}],
}, ifNode],
};

return this.finishNode(node, 'BlockStatement');
}

function createIf({test, isParenL}) {
const node = {
test,
};

const isParenR = this.eat(tt.parenR);

check.call(this, {
isParenL,
isParenR,
});

node.consequent = this.parseStatement('if');
node.alternate = this.eat(tt._else) ? this.parseStatement('if') : null;
node.loc = {};
node.range = [];

setGoldsteinIf(node);

return this.finishNode(node, 'IfStatement');
}
5 changes: 5 additions & 0 deletions packages/keyword-if/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ test('goldstein: keyword: if', (t) => {
t.end();
});

test('goldstein: keyword: if: let', (t) => {
t.compile('if-let');
t.end();
});

test('goldstein: keyword: if: no brace', (t) => {
t.raise('no-brace', `Use braces ('{', '}') when omit parens ('(', ')') (2:4)`);
t.end();
Expand Down

0 comments on commit 0b4756a

Please sign in to comment.