mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
added last to helpers
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
exports.count = function(string, letter) {
|
||||
var num, pos;
|
||||
num = (pos = 0);
|
||||
while (0 < (pos = 1 + string.indexOf(letter, pos))) {
|
||||
while (pos = 1 + string.indexOf(letter, pos)) {
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
@@ -64,4 +64,7 @@
|
||||
delete obj[key];
|
||||
return val;
|
||||
};
|
||||
exports.last = function(array, back) {
|
||||
return array[array.length - (back || 0) - 1];
|
||||
};
|
||||
}).call(this);
|
||||
|
||||
61
lib/lexer.js
61
lib/lexer.js
@@ -1,5 +1,5 @@
|
||||
(function() {
|
||||
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_END, REGEX_ESCAPE, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, SHIFT, SIMPLESTR, UNARY, WHITESPACE, _ref, compact, count, include, starts;
|
||||
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_END, REGEX_ESCAPE, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, SHIFT, SIMPLESTR, UNARY, WHITESPACE, _ref, compact, count, include, last, starts;
|
||||
var __slice = Array.prototype.slice;
|
||||
_ref = require('./rewriter');
|
||||
Rewriter = _ref.Rewriter;
|
||||
@@ -8,6 +8,7 @@
|
||||
count = _ref.count;
|
||||
starts = _ref.starts;
|
||||
compact = _ref.compact;
|
||||
last = _ref.last;
|
||||
exports.Lexer = (function() {
|
||||
Lexer = function() {};
|
||||
Lexer.prototype.tokenize = function(code, options) {
|
||||
@@ -212,7 +213,7 @@
|
||||
indent = match[0];
|
||||
this.line += count(indent, '\n');
|
||||
this.i += indent.length;
|
||||
prev = this.prev(2);
|
||||
prev = last(this.tokens, 1);
|
||||
size = indent.length - 1 - indent.lastIndexOf('\n');
|
||||
nextCharacter = NEXT_CHARACTER.exec(this.chunk)[1];
|
||||
noNewlines = (('.' === nextCharacter || ',' === nextCharacter)) || this.unfinished();
|
||||
@@ -270,7 +271,7 @@
|
||||
if (!(match = WHITESPACE.exec(this.chunk))) {
|
||||
return false;
|
||||
}
|
||||
prev = this.prev();
|
||||
prev = last(this.tokens);
|
||||
if (prev) {
|
||||
prev.spaced = true;
|
||||
}
|
||||
@@ -290,7 +291,7 @@
|
||||
return true;
|
||||
};
|
||||
Lexer.prototype.literalToken = function() {
|
||||
var _ref2, match, prev, space, spaced, tag, value;
|
||||
var _ref2, match, prev, space, spaced, tag, val, value;
|
||||
if (match = this.chunk.match(OPERATOR)) {
|
||||
_ref2 = match;
|
||||
value = _ref2[0];
|
||||
@@ -302,14 +303,15 @@
|
||||
value = this.chunk.charAt(0);
|
||||
}
|
||||
this.i += value.length;
|
||||
spaced = (prev = this.prev()) && prev.spaced;
|
||||
prev = last(this.tokens);
|
||||
spaced = prev == null ? undefined : prev.spaced;
|
||||
tag = value;
|
||||
if (value === '=') {
|
||||
if (include(JS_FORBIDDEN, this.value())) {
|
||||
if (include(JS_FORBIDDEN, val = this.value())) {
|
||||
this.assignmentError();
|
||||
}
|
||||
if (('or' === (_ref2 = this.value()) || 'and' === _ref2)) {
|
||||
this.tokens.splice(this.tokens.length - 1, 1, ['COMPOUND_ASSIGN', CONVERSIONS[this.value()] + '=', prev[2]]);
|
||||
if (('or' === val || 'and' === val)) {
|
||||
this.tokens.splice(-1, 1, ['COMPOUND_ASSIGN', CONVERSIONS[val] + '=', prev[2]]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -337,10 +339,10 @@
|
||||
tag = 'INDEX_START';
|
||||
switch (this.tag()) {
|
||||
case '?':
|
||||
this.tag(1, 'INDEX_SOAK');
|
||||
this.tag(0, 'INDEX_SOAK');
|
||||
break;
|
||||
case '::':
|
||||
this.tag(1, 'INDEX_PROTO');
|
||||
this.tag(0, 'INDEX_PROTO');
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -350,18 +352,18 @@
|
||||
};
|
||||
Lexer.prototype.tagAccessor = function() {
|
||||
var accessor, prev;
|
||||
if ((!(prev = this.prev())) || (prev && prev.spaced)) {
|
||||
if (!(prev = last(this.tokens)) || prev.spaced) {
|
||||
return false;
|
||||
}
|
||||
accessor = (function() {
|
||||
if (prev[1] === '::') {
|
||||
return this.tag(1, 'PROTOTYPE_ACCESS');
|
||||
} else if (prev[1] === '.' && this.value(2) !== '.') {
|
||||
if (this.tag(2) === '?') {
|
||||
this.tag(1, 'SOAK_ACCESS');
|
||||
return this.tag(0, 'PROTOTYPE_ACCESS');
|
||||
} else if (prev[1] === '.' && this.value(1) !== '.') {
|
||||
if (this.tag(1) === '?') {
|
||||
this.tag(0, 'SOAK_ACCESS');
|
||||
return this.tokens.splice(-2, 1);
|
||||
} else {
|
||||
return this.tag(1, 'PROPERTY_ACCESS');
|
||||
return this.tag(0, 'PROPERTY_ACCESS');
|
||||
}
|
||||
} else {
|
||||
return prev[0] === '@';
|
||||
@@ -402,11 +404,9 @@
|
||||
if (this.tag() !== ')') {
|
||||
return null;
|
||||
}
|
||||
i = 0;
|
||||
i = this.tokens.length;
|
||||
while (true) {
|
||||
i += 1;
|
||||
tok = this.prev(i);
|
||||
if (!tok) {
|
||||
if (!(tok = this.tokens[--i])) {
|
||||
return null;
|
||||
}
|
||||
switch (tok[0]) {
|
||||
@@ -449,7 +449,7 @@
|
||||
_ref3 = pair;
|
||||
open = _ref3[0];
|
||||
close = _ref3[1];
|
||||
if (levels.length && starts(str, close, i) && levels[levels.length - 1] === pair) {
|
||||
if (levels.length && starts(str, close, i) && last(levels) === pair) {
|
||||
levels.pop();
|
||||
i += close.length - 1;
|
||||
if (!(levels.length)) {
|
||||
@@ -563,30 +563,21 @@
|
||||
};
|
||||
Lexer.prototype.tag = function(index, newTag) {
|
||||
var tok;
|
||||
if (!(tok = this.prev(index))) {
|
||||
if (!(tok = last(this.tokens, index))) {
|
||||
return null;
|
||||
}
|
||||
if (typeof newTag !== "undefined" && newTag !== null) {
|
||||
return (tok[0] = newTag);
|
||||
}
|
||||
return tok[0];
|
||||
return (tok[0] = (typeof newTag !== "undefined" && newTag !== null) ? newTag : tok[0]);
|
||||
};
|
||||
Lexer.prototype.value = function(index, val) {
|
||||
var tok;
|
||||
if (!(tok = this.prev(index))) {
|
||||
if (!(tok = last(this.tokens, index))) {
|
||||
return null;
|
||||
}
|
||||
if (typeof val !== "undefined" && val !== null) {
|
||||
return (tok[1] = val);
|
||||
}
|
||||
return tok[1];
|
||||
};
|
||||
Lexer.prototype.prev = function(index) {
|
||||
return this.tokens[this.tokens.length - (index || 1)];
|
||||
return (tok[1] = (typeof val !== "undefined" && val !== null) ? val : tok[1]);
|
||||
};
|
||||
Lexer.prototype.unfinished = function() {
|
||||
var prev, value;
|
||||
return (prev = this.prev(2)) && prev[0] !== '.' && (value = this.value()) && NO_NEWLINE.test(value) && !CODE.test(value) && !ASSIGNED.test(this.chunk);
|
||||
return (prev = last(this.tokens, 1)) && prev[0] !== '.' && (value = this.value()) && NO_NEWLINE.test(value) && !CODE.test(value) && !ASSIGNED.test(this.chunk);
|
||||
};
|
||||
Lexer.prototype.escapeLines = function(str, heredoc) {
|
||||
return str.replace(MULTILINER, heredoc ? '\\n' : '');
|
||||
|
||||
58
lib/nodes.js
58
lib/nodes.js
@@ -1,5 +1,5 @@
|
||||
(function() {
|
||||
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, InNode, IndexNode, LiteralNode, NO, NUMBER, ObjectNode, OpNode, ParamNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SIMPLENUM, Scope, SliceNode, SplatNode, SwitchNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, YES, _ref, compact, del, ends, flatten, include, indexOf, literal, merge, starts, utility;
|
||||
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, InNode, IndexNode, LiteralNode, NO, NUMBER, ObjectNode, OpNode, ParamNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SIMPLENUM, Scope, SliceNode, SplatNode, SwitchNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, YES, _ref, compact, del, ends, flatten, include, indexOf, last, literal, merge, starts, utility;
|
||||
var __extends = function(child, parent) {
|
||||
var ctor = function(){};
|
||||
ctor.prototype = parent.prototype;
|
||||
@@ -19,6 +19,7 @@
|
||||
indexOf = _ref.indexOf;
|
||||
starts = _ref.starts;
|
||||
ends = _ref.ends;
|
||||
last = _ref.last;
|
||||
YES = function() {
|
||||
return true;
|
||||
};
|
||||
@@ -191,16 +192,14 @@
|
||||
return this.expressions.length === 0;
|
||||
};
|
||||
Expressions.prototype.makeReturn = function() {
|
||||
var idx, last;
|
||||
idx = this.expressions.length - 1;
|
||||
last = this.expressions[idx];
|
||||
if (last instanceof CommentNode) {
|
||||
last = this.expressions[idx -= 1];
|
||||
var end, idx;
|
||||
end = this.expressions[(idx = this.expressions.length - 1)];
|
||||
if (end instanceof CommentNode) {
|
||||
end = this.expressions[idx -= 1];
|
||||
}
|
||||
if (!last || last instanceof ReturnNode) {
|
||||
return this;
|
||||
if (end && !(end instanceof ReturnNode)) {
|
||||
this.expressions[idx] = end.makeReturn();
|
||||
}
|
||||
this.expressions[idx] = last.makeReturn();
|
||||
return this;
|
||||
};
|
||||
Expressions.prototype.compile = function(o) {
|
||||
@@ -335,10 +334,10 @@
|
||||
return this.base instanceof ObjectNode && !this.hasProperties();
|
||||
};
|
||||
ValueNode.prototype.isSplice = function() {
|
||||
return this.hasProperties() && this.properties[this.properties.length - 1] instanceof SliceNode;
|
||||
return last(this.properties) instanceof SliceNode;
|
||||
};
|
||||
ValueNode.prototype.isComplex = function() {
|
||||
return this.base.isComplex() || this.properties.length;
|
||||
return this.base.isComplex() || this.hasProperties();
|
||||
};
|
||||
ValueNode.prototype.makeReturn = function() {
|
||||
return this.hasProperties() ? ValueNode.__super__.makeReturn.call(this) : this.base.makeReturn();
|
||||
@@ -380,7 +379,7 @@
|
||||
return !o.top || this.properties.length ? ValueNode.__super__.compile.call(this, o) : this.base.compile(o);
|
||||
};
|
||||
ValueNode.prototype.compileNode = function(o) {
|
||||
var _i, _len, _ref2, baseline, complete, copy, hasSoak, i, me, only, op, part, prevcomp, prop, props, temp;
|
||||
var _i, _len, _ref2, baseline, complete, copy, hasSoak, i, me, only, op, part, prop, props, temp;
|
||||
only = del(o, 'onlyFirst');
|
||||
op = this.tags.operation;
|
||||
props = only ? this.properties.slice(0, -1) : this.properties;
|
||||
@@ -413,7 +412,7 @@
|
||||
if (prop.soakNode) {
|
||||
if (i === 0 && this.base.isComplex()) {
|
||||
temp = o.scope.freeVariable('ref');
|
||||
complete = ("(" + (baseline = temp) + " = (" + (prevcomp = complete) + "))");
|
||||
complete = ("(" + (baseline = temp) + " = (" + (complete) + "))");
|
||||
}
|
||||
complete = i === 0 && !o.scope.check(complete) ? ("(typeof " + (complete) + " === \"undefined\" || " + (baseline) + " === null)") : ("" + (complete) + " == null");
|
||||
complete += ' ? undefined : ' + (baseline += prop.compile(o));
|
||||
@@ -493,7 +492,7 @@
|
||||
}
|
||||
op = this.tags.operation;
|
||||
if (this.exist) {
|
||||
if (this.variable instanceof ValueNode && this.variable.properties[this.variable.properties.length - 1] instanceof AccessorNode) {
|
||||
if (this.variable instanceof ValueNode && last(this.variable.properties) instanceof AccessorNode) {
|
||||
methodAccessor = this.variable.properties.pop();
|
||||
_ref2 = this.variable.compileReference(o);
|
||||
first = _ref2[0];
|
||||
@@ -771,7 +770,7 @@
|
||||
}
|
||||
return _result;
|
||||
}).call(this);
|
||||
lastNoncom = nonComments[nonComments.length - 1];
|
||||
lastNoncom = last(nonComments);
|
||||
props = (function() {
|
||||
_result = []; _ref2 = this.properties;
|
||||
for (i = 0, _len = _ref2.length; i < _len; i++) {
|
||||
@@ -949,7 +948,7 @@
|
||||
return this.isValue() && (this.variable.isArray() || this.variable.isObject());
|
||||
};
|
||||
AssignNode.prototype.compileNode = function(o) {
|
||||
var last, match, name, proto, stmt, top, val;
|
||||
var end, match, name, proto, stmt, top, val;
|
||||
top = del(o, 'top');
|
||||
if (this.isStatement(o)) {
|
||||
return this.compilePatternMatch(o);
|
||||
@@ -959,12 +958,12 @@
|
||||
}
|
||||
stmt = del(o, 'asStatement');
|
||||
name = this.variable.compile(o);
|
||||
last = this.isValue() ? this.variable.last.replace(this.LEADING_DOT, '') : name;
|
||||
end = this.isValue() ? this.variable.last.replace(this.LEADING_DOT, '') : name;
|
||||
match = name.match(this.PROTO_ASSIGN);
|
||||
proto = match && match[1];
|
||||
if (this.value instanceof CodeNode) {
|
||||
if (last.match(IDENTIFIER)) {
|
||||
this.value.name = last;
|
||||
if (IDENTIFIER.test(end)) {
|
||||
this.value.name = end;
|
||||
}
|
||||
if (proto) {
|
||||
this.value.proto = proto;
|
||||
@@ -1202,25 +1201,26 @@
|
||||
return "" + (utility('slice')) + ".call(" + (name) + ", " + (index) + (trail) + ")";
|
||||
};
|
||||
SplatNode.compileSplattedArray = function(list, o) {
|
||||
var _len, _ref2, arg, args, code, i, last, prev;
|
||||
var _len, _ref2, arg, args, code, end, i, prev;
|
||||
args = [];
|
||||
end = -1;
|
||||
_ref2 = list;
|
||||
for (i = 0, _len = _ref2.length; i < _len; i++) {
|
||||
arg = _ref2[i];
|
||||
code = arg.compile(o);
|
||||
prev = args[(last = args.length - 1)];
|
||||
prev = args[end];
|
||||
if (!(arg instanceof SplatNode)) {
|
||||
if (prev && starts(prev, '[') && ends(prev, ']')) {
|
||||
args[last] = ("" + (prev.slice(0, -1)) + ", " + (code) + "]");
|
||||
args[end] = ("" + (prev.slice(0, -1)) + ", " + (code) + "]");
|
||||
continue;
|
||||
} else if (prev && starts(prev, '.concat([') && ends(prev, '])')) {
|
||||
args[last] = ("" + (prev.slice(0, -2)) + ", " + (code) + "])");
|
||||
continue;
|
||||
} else {
|
||||
code = ("[" + (code) + "]");
|
||||
}
|
||||
if (prev && starts(prev, '.concat([') && ends(prev, '])')) {
|
||||
args[end] = ("" + (prev.slice(0, -2)) + ", " + (code) + "])");
|
||||
continue;
|
||||
}
|
||||
code = ("[" + (code) + "]");
|
||||
}
|
||||
args.push(i === 0 ? code : (".concat(" + (code) + ")"));
|
||||
args[++end] = i === 0 ? code : (".concat(" + (code) + ")");
|
||||
}
|
||||
return args.join('');
|
||||
};
|
||||
@@ -1756,7 +1756,7 @@
|
||||
code += ("\n" + (this.idt(1)) + "case " + (condition.compile(o)) + ":");
|
||||
}
|
||||
code += ("\n" + (block.compile(o)));
|
||||
if (!(exprs[exprs.length - 1] instanceof ReturnNode)) {
|
||||
if (!(last(exprs) instanceof ReturnNode)) {
|
||||
code += ("\n" + (idt) + "break;");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user