mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
adding conditional while loops with while ... when
This commit is contained in:
parent
4d146bacb1
commit
4eeb8c4bd2
7 changed files with 90 additions and 65 deletions
|
@ -414,13 +414,20 @@
|
|||
return new ParentheticalNode($2);
|
||||
})
|
||||
],
|
||||
// The condition for a while loop.
|
||||
WhileSource: [o("WHILE Expression", function() {
|
||||
return new WhileNode($2);
|
||||
}), o("WHILE Expression WHEN Expression", function() {
|
||||
return new WhileNode($2, {
|
||||
filter: $4
|
||||
});
|
||||
})
|
||||
],
|
||||
// The while loop. (there is no do..while).
|
||||
While: [o("WHILE Expression Block", function() {
|
||||
return new WhileNode($2, $3);
|
||||
}), o("WHILE Expression", function() {
|
||||
return new WhileNode($2, null);
|
||||
}), o("Expression WHILE Expression", function() {
|
||||
return new WhileNode($3, Expressions.wrap([$1]));
|
||||
While: [o("WhileSource Block", function() {
|
||||
return $1.add_body($2);
|
||||
}), o("Expression WhileSource", function() {
|
||||
return $2.add_body($1);
|
||||
})
|
||||
],
|
||||
// Array comprehensions, including guard and current index.
|
||||
|
|
16
lib/nodes.js
16
lib/nodes.js
|
@ -891,8 +891,13 @@
|
|||
// it, all other loops can be manufactured.
|
||||
WhileNode = (exports.WhileNode = inherit(Node, {
|
||||
type: 'While',
|
||||
constructor: function constructor(condition, body) {
|
||||
this.children = [(this.condition = condition), (this.body = body)];
|
||||
constructor: function constructor(condition, opts) {
|
||||
this.children = [(this.condition = condition)];
|
||||
this.filter = opts && opts.filter;
|
||||
return this;
|
||||
},
|
||||
add_body: function add_body(body) {
|
||||
this.children.push((this.body = body));
|
||||
return this;
|
||||
},
|
||||
top_sensitive: function top_sensitive() {
|
||||
|
@ -909,13 +914,18 @@
|
|||
if (!top) {
|
||||
rvar = o.scope.free_variable();
|
||||
set = this.idt() + rvar + ' = [];\n';
|
||||
this.body = PushNode.wrap(rvar, this.body);
|
||||
if (this.body) {
|
||||
this.body = PushNode.wrap(rvar, this.body);
|
||||
}
|
||||
}
|
||||
post = returns ? '\n' + this.idt() + 'return ' + rvar + ';' : '';
|
||||
pre = set + this.idt() + 'while (' + cond + ')';
|
||||
if (!this.body) {
|
||||
return pre + ' null;' + post;
|
||||
}
|
||||
if (this.filter) {
|
||||
this.body = Expressions.wrap([new IfNode(this.filter, this.body)]);
|
||||
}
|
||||
return pre + ' {\n' + this.body.compile(o) + '\n' + this.idt() + '}' + post;
|
||||
}
|
||||
}));
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -360,11 +360,16 @@ grammar: {
|
|||
o "( Expression )", -> new ParentheticalNode($2)
|
||||
]
|
||||
|
||||
# The condition for a while loop.
|
||||
WhileSource: [
|
||||
o "WHILE Expression", -> new WhileNode($2)
|
||||
o "WHILE Expression WHEN Expression", -> new WhileNode($2, {filter : $4})
|
||||
]
|
||||
|
||||
# The while loop. (there is no do..while).
|
||||
While: [
|
||||
o "WHILE Expression Block", -> new WhileNode($2, $3)
|
||||
o "WHILE Expression", -> new WhileNode($2, null)
|
||||
o "Expression WHILE Expression", -> new WhileNode($3, Expressions.wrap([$1]))
|
||||
o "WhileSource Block", -> $1.add_body $2
|
||||
o "Expression WhileSource", -> $2.add_body $1
|
||||
]
|
||||
|
||||
# Array comprehensions, including guard and current index.
|
||||
|
@ -384,10 +389,8 @@ grammar: {
|
|||
ForSource: [
|
||||
o "IN Expression", -> {source: $2}
|
||||
o "OF Expression", -> {source: $2, object: true}
|
||||
o "ForSource WHEN Expression", ->
|
||||
$1.filter: $3; $1
|
||||
o "ForSource BY Expression", ->
|
||||
$1.step: $3; $1
|
||||
o "ForSource WHEN Expression", -> $1.filter: $3; $1
|
||||
o "ForSource BY Expression", -> $1.step: $3; $1
|
||||
]
|
||||
|
||||
# Switch/When blocks.
|
||||
|
@ -406,8 +409,7 @@ grammar: {
|
|||
When: [
|
||||
o "LEADING_WHEN SimpleArgs Block", -> new IfNode($2, $3, null, {statement: true})
|
||||
o "LEADING_WHEN SimpleArgs Block TERMINATOR", -> new IfNode($2, $3, null, {statement: true})
|
||||
o "Comment TERMINATOR When", ->
|
||||
$3.comment: $1; $3
|
||||
o "Comment TERMINATOR When", -> $3.comment: $1; $3
|
||||
]
|
||||
|
||||
# The most basic form of "if".
|
||||
|
|
|
@ -701,8 +701,13 @@ SplatNode: exports.SplatNode: inherit Node, {
|
|||
WhileNode: exports.WhileNode: inherit Node, {
|
||||
type: 'While'
|
||||
|
||||
constructor: (condition, body) ->
|
||||
@children:[@condition: condition, @body: body]
|
||||
constructor: (condition, opts) ->
|
||||
@children:[@condition: condition]
|
||||
@filter: opts and opts.filter
|
||||
this
|
||||
|
||||
add_body: (body) ->
|
||||
@children.push @body: body
|
||||
this
|
||||
|
||||
top_sensitive: ->
|
||||
|
@ -718,10 +723,11 @@ WhileNode: exports.WhileNode: inherit Node, {
|
|||
if not top
|
||||
rvar: o.scope.free_variable()
|
||||
set: @idt() + rvar + ' = [];\n'
|
||||
@body: PushNode.wrap(rvar, @body)
|
||||
@body: PushNode.wrap(rvar, @body) if @body
|
||||
post: if returns then '\n' + @idt() + 'return ' + rvar + ';' else ''
|
||||
pre: set + @idt() + 'while (' + cond + ')'
|
||||
return pre + ' null;' + post if not @body
|
||||
@body: Expressions.wrap([new IfNode(@filter, @body)]) if @filter
|
||||
pre + ' {\n' + @body.compile(o) + '\n' + @idt() + '}' + post
|
||||
|
||||
}
|
||||
|
|
|
@ -26,12 +26,6 @@ reg: /\\/
|
|||
ok reg(str) and str is '\\'
|
||||
|
||||
|
||||
i: 10
|
||||
while i -= 1
|
||||
|
||||
ok i is 0
|
||||
|
||||
|
||||
money$: 'dollars'
|
||||
|
||||
ok money$ is 'dollars'
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
i: 100
|
||||
while i -= 1
|
||||
|
||||
ok i is 0
|
||||
|
||||
|
||||
i: 5
|
||||
list: while i -= 1
|
||||
i * 2
|
||||
|
@ -25,4 +19,12 @@ results: while func 1
|
|||
assert()
|
||||
i
|
||||
|
||||
ok results.join(' ') is '4 3 2 1'
|
||||
ok results.join(' ') is '4 3 2 1'
|
||||
|
||||
|
||||
i: 10
|
||||
results: while i -= 1 when i % 2 is 0
|
||||
i * 2
|
||||
|
||||
ok results.join(' ') is '16 12 8 4'
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue