Self-compiler: now does while loops
This commit is contained in:
parent
fd80d784f4
commit
8e3e06a6e9
|
@ -314,10 +314,10 @@
|
|||
num = 0;
|
||||
pos = string.indexOf(letter);
|
||||
while (pos !== -1) {
|
||||
count += 1;
|
||||
num += 1;
|
||||
pos = string.indexOf(letter, pos + 1);
|
||||
}
|
||||
return count;
|
||||
return num;
|
||||
};
|
||||
// Attempt to match a string against the current chunk, returning the indexed
|
||||
// match.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(function(){
|
||||
var AccessorNode, ArrayNode, AssignNode, CallNode, ClosureNode, CodeNode, CommentNode, Expressions, ExtendsNode, IndexNode, LiteralNode, Node, ObjectNode, PushNode, RangeNode, ReturnNode, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThisNode, ValueNode, any, compact, del, dup, flatten, inherit, merge, statement;
|
||||
var AccessorNode, ArrayNode, AssignNode, CallNode, ClosureNode, CodeNode, CommentNode, Expressions, ExtendsNode, IndexNode, LiteralNode, Node, ObjectNode, PushNode, RangeNode, ReturnNode, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThisNode, ValueNode, WhileNode, any, compact, del, dup, flatten, inherit, merge, statement;
|
||||
var __hasProp = Object.prototype.hasOwnProperty;
|
||||
process.mixin(require('./scope'));
|
||||
// The abstract base class for all CoffeeScript nodes.
|
||||
|
@ -372,7 +372,7 @@
|
|||
compile: function compile(o) {
|
||||
o = o || {
|
||||
};
|
||||
return o.scope ? compile.__superClass__.constructor.call(this, o) : this.compile_root(o);
|
||||
return o.scope ? Node.prototype.compile.call(this, o) : this.compile_root(o);
|
||||
},
|
||||
// Compile each expression in the Expressions body.
|
||||
compile_node: function compile_node(o) {
|
||||
|
@ -998,4 +998,36 @@
|
|||
return "Array.prototype.slice.call(" + this.name + ', ' + this.index + ')';
|
||||
}
|
||||
}));
|
||||
// A while loop, the only sort of low-level loop exposed by CoffeeScript. From
|
||||
// it, all other loops can be manufactured.
|
||||
WhileNode = (exports.WhileNode = inherit(Node, {
|
||||
constructor: function constructor(condition, body) {
|
||||
this.children = [(this.condition = condition), (this.body = body)];
|
||||
return this;
|
||||
},
|
||||
top_sensitive: function top_sensitive() {
|
||||
return true;
|
||||
},
|
||||
compile_node: function compile_node(o) {
|
||||
var cond, post, pre, returns, rvar, set, top;
|
||||
returns = del(o, 'returns');
|
||||
top = del(o, 'top') && !returns;
|
||||
o.indent = this.idt(1);
|
||||
o.top = true;
|
||||
cond = this.condition.compile(o);
|
||||
set = '';
|
||||
if (!top) {
|
||||
rvar = o.scope.free_variable();
|
||||
set = this.idt() + rvar + ' = [];\n';
|
||||
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;
|
||||
}
|
||||
return pre + ' {\n' + this.body.compile(o) + '\n' + this.idt() + '}' + post;
|
||||
}
|
||||
}));
|
||||
statement(WhileNode);
|
||||
})();
|
|
@ -246,9 +246,9 @@ lex::count: (string, letter) ->
|
|||
num: 0
|
||||
pos: string.indexOf(letter)
|
||||
while pos isnt -1
|
||||
count += 1
|
||||
num += 1
|
||||
pos: string.indexOf(letter, pos + 1)
|
||||
count
|
||||
num
|
||||
|
||||
# Attempt to match a string against the current chunk, returning the indexed
|
||||
# match.
|
||||
|
|
|
@ -182,7 +182,7 @@ Expressions: exports.Expressions: inherit Node, {
|
|||
|
||||
compile: (o) ->
|
||||
o ||= {}
|
||||
if o.scope then super(o) else @compile_root(o)
|
||||
if o.scope then Node::compile.call(this, o) else @compile_root(o)
|
||||
|
||||
# Compile each expression in the Expressions body.
|
||||
compile_node: (o) ->
|
||||
|
@ -711,6 +711,37 @@ SplatNode: exports.SplatNode: inherit Node, {
|
|||
|
||||
}
|
||||
|
||||
# A while loop, the only sort of low-level loop exposed by CoffeeScript. From
|
||||
# it, all other loops can be manufactured.
|
||||
WhileNode: exports.WhileNode: inherit Node, {
|
||||
|
||||
constructor: (condition, body) ->
|
||||
@children:[@condition: condition, @body: body]
|
||||
this
|
||||
|
||||
top_sensitive: ->
|
||||
true
|
||||
|
||||
compile_node: (o) ->
|
||||
returns: del(o, 'returns')
|
||||
top: del(o, 'top') and not returns
|
||||
o.indent: @idt(1)
|
||||
o.top: true
|
||||
cond: @condition.compile(o)
|
||||
set: ''
|
||||
if not top
|
||||
rvar: o.scope.free_variable()
|
||||
set: @idt() + rvar + ' = [];\n'
|
||||
@body: PushNode.wrap(rvar, @body)
|
||||
post: if returns then '\n' + @idt() + 'return ' + rvar + ';' else ''
|
||||
pre: set + @idt() + 'while (' + cond + ')'
|
||||
return pre + ' null;' + post if not @body
|
||||
pre + ' {\n' + @body.compile(o) + '\n' + @idt() + '}' + post
|
||||
|
||||
}
|
||||
|
||||
statement WhileNode
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue