Skip to content

Commit

Permalink
implement for-in with ES6 for-of loop
Browse files Browse the repository at this point in the history
  • Loading branch information
alongubkin committed Nov 26, 2014
1 parent 5b88b1b commit a21a5ba
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 143 deletions.
47 changes: 23 additions & 24 deletions lib/ast/expressions/ForInExpression.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/ast/statements/BreakStatement.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 38 additions & 39 deletions lib/ast/statements/ForInStatement.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/ast/statements/ReturnStatement.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 27 additions & 27 deletions src/ast/expressions/ForInExpression.spider
Original file line number Diff line number Diff line change
Expand Up @@ -79,40 +79,40 @@ ForInExpression.prototype.codegen = () -> {

var forInStatement = new ForInStatement(this.item, this.index, this.array,
new BlockStatement([pushStatement]));

forInStatement.parent = this;

var fnBlock = new BlockStatement([
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": id,
"init": {
"type": "ArrayExpression",
"elements": []
}
}
],
"kind": "let",
"codeGenerated": true
},
forInStatement,
{
"type": "ReturnStatement",
"codeGenerated": true,
"argument": id
}
]);

forInStatement.parent = fnBlock;

this.type = "CallExpression";
this.callee = {
"type": "FunctionExpression",
"id": null,
"params": [],
"defaults": [],
"body": {
"type": "BlockStatement",
"body": [
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": id,
"init": {
"type": "ArrayExpression",
"elements": []
}
}
],
"kind": "let",
"codeGenerated": true
},
forInStatement.codegen(false),
{
"type": "ReturnStatement",
"argument": id
}
]
}
"body": fnBlock.codegen()
};

::Object.defineProperty(this, 'arguments', {
Expand Down
2 changes: 1 addition & 1 deletion src/ast/statements/BreakStatement.spider
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ BreakStatement.prototype.codegen = () -> {
}

var parent = this.parent;
while parent? and parent.type != "ForInStatement" and parent.type != "ForOfStatement" {
while parent? and parent.type != "ForOfStatement" {
parent = parent.parent;
}

Expand Down
82 changes: 44 additions & 38 deletions src/ast/statements/ForInStatement.spider
Original file line number Diff line number Diff line change
Expand Up @@ -22,62 +22,68 @@ func ForInStatement(item, index, array, body)
this.body.parent = this;
}

ForInStatement.prototype.codegen = (every = true) -> {
ForInStatement.prototype.codegen = () -> {
if !super.codegen() {
return;
}

this.item = this.item.codegen(false);

var params = [this.item];
this.defineIdentifier(this.item);

if this.index? {
var context = this.getContext();
this.index = this.index.codegen(false);
params.push(this.index);

this.defineIdentifier(this.index);
context.node.body.splice(context.position, 0, {
"type": "VariableDeclaration",
"declarations": [{
"type": "VariableDeclarator",
"id": this.index,
"init": {
"type": "Literal",
"value": 0
}
}],
"kind": "let"
});
}

this.array = this.array.codegen();
this.body = this.body.blockWrap().codegen();

if every and (this.body.body.length == 0 or
this.body.body[this.body.body.length - 1].type != "ReturnStatement") {

this.body = this.body.blockWrap();
this.body.defineIdentifier(this.item);

if this.index? {
this.body.defineIdentifier(this.index);
}

this.body = this.body.codegen();

if this.index? {
this.body.body.push({
"type": "ReturnStatement",
"type": "ExpressionStatement",
"codeGenerated": true,
"argument": {
"type": "Literal",
"value": true
"expression": {
"type": "UpdateExpression",
"operator": "++",
"argument": this.index,
"prefix": false
}
});
}

this.type = "ExpressionStatement";
this.expression = {
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"computed": false,
"object": this.array,
"property": {
"type": "Identifier",
"name": "every" if every else "forEach"
}
},
"arguments": [{
"type": "FunctionExpression",
"id": null,
"params": params,
"defaults": [],
"body": this.body,
"rest": null,
"generator": false,
"expression": false
}, { "type": "ThisExpression" }]
};

this.type = "ForOfStatement";
this.right = this.array;
this.left = {
"type": "VariableDeclaration",
"declarations": [{
"type": "VariableDeclarator",
"id": this.item,
"init": null
}],
"kind": "let"
};
this.each = false;

return this;
};

Expand Down
2 changes: 1 addition & 1 deletion src/ast/statements/ReturnStatement.spider
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ReturnStatement.prototype.codegen = () -> {
}

var parent = this.parent;
while parent? and parent.type != "ForInStatement" and parent.type != "ForOfStatement" {
while parent? and parent.type != "ForOfStatement" {
parent = parent.parent;
}

Expand Down
Loading

0 comments on commit a21a5ba

Please sign in to comment.