mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-17 19:11:22 -05:00
removed YES/NO/ON/OFF from rewriter/parser
This commit is contained in:
@@ -68,14 +68,8 @@
|
|||||||
return new Literal(true);
|
return new Literal(true);
|
||||||
}), o("FALSE", function() {
|
}), o("FALSE", function() {
|
||||||
return new Literal(false);
|
return new Literal(false);
|
||||||
}), o("YES", function() {
|
}), o("NULL", function() {
|
||||||
return new Literal(true);
|
return new Literal('null');
|
||||||
}), o("NO", function() {
|
|
||||||
return new Literal(false);
|
|
||||||
}), o("ON", function() {
|
|
||||||
return new Literal(true);
|
|
||||||
}), o("OFF", function() {
|
|
||||||
return new Literal(false);
|
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
Assign: [
|
Assign: [
|
||||||
@@ -178,9 +172,7 @@
|
|||||||
return new Value($1);
|
return new Value($1);
|
||||||
}), o("Range", function() {
|
}), o("Range", function() {
|
||||||
return new Value($1);
|
return new Value($1);
|
||||||
}), o("This"), o("NULL", function() {
|
}), o("This")
|
||||||
return new Value(new Literal('null'));
|
|
||||||
})
|
|
||||||
],
|
],
|
||||||
Accessor: [
|
Accessor: [
|
||||||
o("PROPERTY_ACCESS Identifier", function() {
|
o("PROPERTY_ACCESS Identifier", function() {
|
||||||
|
|||||||
@@ -577,13 +577,17 @@
|
|||||||
return Lexer;
|
return Lexer;
|
||||||
})();
|
})();
|
||||||
JS_KEYWORDS = ['if', 'else', 'true', 'false', 'new', 'return', 'try', 'catch', 'finally', 'throw', 'break', 'continue', 'for', 'in', 'while', 'delete', 'instanceof', 'typeof', 'switch', 'super', 'extends', 'class', 'this', 'null', 'debugger'];
|
JS_KEYWORDS = ['if', 'else', 'true', 'false', 'new', 'return', 'try', 'catch', 'finally', 'throw', 'break', 'continue', 'for', 'in', 'while', 'delete', 'instanceof', 'typeof', 'switch', 'super', 'extends', 'class', 'this', 'null', 'debugger'];
|
||||||
COFFEE_KEYWORDS = ['then', 'unless', 'until', 'loop', 'yes', 'no', 'on', 'off', 'of', 'by', 'when'];
|
COFFEE_KEYWORDS = ['then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
|
||||||
for (op in (COFFEE_ALIASES = {
|
for (op in (COFFEE_ALIASES = {
|
||||||
and: '&&',
|
and: '&&',
|
||||||
or: '||',
|
or: '||',
|
||||||
is: '==',
|
is: '==',
|
||||||
isnt: '!=',
|
isnt: '!=',
|
||||||
not: '!'
|
not: '!',
|
||||||
|
yes: 'TRUE',
|
||||||
|
no: 'FALSE',
|
||||||
|
on: 'TRUE',
|
||||||
|
off: 'FALSE'
|
||||||
})) {
|
})) {
|
||||||
COFFEE_KEYWORDS.push(op);
|
COFFEE_KEYWORDS.push(op);
|
||||||
}
|
}
|
||||||
|
|||||||
364
lib/parser.js
364
lib/parser.js
File diff suppressed because one or more lines are too long
@@ -146,27 +146,28 @@
|
|||||||
return this.tokens.splice(i, 0, ['}', '}', token[2]]);
|
return this.tokens.splice(i, 0, ['}', '}', token[2]]);
|
||||||
};
|
};
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
return this.scanTokens(function(token, i, tokens) {
|
||||||
var idx, last, tag, tok;
|
var idx, tag, tok;
|
||||||
if (include(EXPRESSION_START, tag = token[0])) {
|
if (include(EXPRESSION_START, tag = token[0])) {
|
||||||
stack.push(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag);
|
stack.push(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
if (include(EXPRESSION_END, tag)) {
|
if (include(EXPRESSION_END, tag)) {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
last = stack[stack.length - 1];
|
if (!(tag === ':' && stack[stack.length - 1] !== '{')) {
|
||||||
if (tag === ':' && !(last && last[0] === '{')) {
|
return 1;
|
||||||
stack.push('{');
|
|
||||||
idx = this.tag(i - 2) === '@' ? i - 2 : i - 1;
|
|
||||||
if (this.tag(idx - 2) === 'HERECOMMENT') {
|
|
||||||
idx -= 2;
|
|
||||||
}
|
|
||||||
tok = ['{', '{', token[2]];
|
|
||||||
tok.generated = true;
|
|
||||||
tokens.splice(idx, 0, tok);
|
|
||||||
this.detectEnd(i + 2, condition, action);
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
return 1;
|
stack.push('{');
|
||||||
|
idx = this.tag(i - 2) === '@' ? i - 2 : i - 1;
|
||||||
|
if (this.tag(idx - 2) === 'HERECOMMENT') {
|
||||||
|
idx -= 2;
|
||||||
|
}
|
||||||
|
tok = ['{', '{', token[2]];
|
||||||
|
tok.generated = true;
|
||||||
|
tokens.splice(idx, 0, tok);
|
||||||
|
this.detectEnd(i + 2, condition, action);
|
||||||
|
return 2;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
exports.Rewriter.prototype.addImplicitParentheses = function() {
|
exports.Rewriter.prototype.addImplicitParentheses = function() {
|
||||||
@@ -178,18 +179,14 @@
|
|||||||
return this.tokens.splice(idx, 0, ['CALL_END', ')', token[2]]);
|
return this.tokens.splice(idx, 0, ['CALL_END', ')', token[2]]);
|
||||||
};
|
};
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
return this.scanTokens(function(token, i, tokens) {
|
||||||
var _ref, callObject, condition, idx, next, prev, seenSingle, tag;
|
var callObject, next, prev, seenSingle, tag;
|
||||||
tag = token[0];
|
tag = token[0];
|
||||||
if (tag === 'CLASS') {
|
if (tag === 'CLASS') {
|
||||||
classLine = true;
|
classLine = true;
|
||||||
}
|
}
|
||||||
prev = tokens[i - 1];
|
prev = tokens[i - 1];
|
||||||
next = tokens[i + 1];
|
next = tokens[i + 1];
|
||||||
idx = 1;
|
|
||||||
callObject = !classLine && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && include(IMPLICIT_FUNC, prev[0]);
|
callObject = !classLine && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && include(IMPLICIT_FUNC, prev[0]);
|
||||||
if (callObject) {
|
|
||||||
idx = 2;
|
|
||||||
}
|
|
||||||
seenSingle = false;
|
seenSingle = false;
|
||||||
if (include(LINEBREAKS, tag)) {
|
if (include(LINEBREAKS, tag)) {
|
||||||
classLine = false;
|
classLine = false;
|
||||||
@@ -197,29 +194,28 @@
|
|||||||
if (prev && !prev.spaced && tag === '?') {
|
if (prev && !prev.spaced && tag === '?') {
|
||||||
token.call = true;
|
token.call = true;
|
||||||
}
|
}
|
||||||
if (callObject || prev && prev.spaced && (prev.call || include(IMPLICIT_FUNC, prev[0])) && include(IMPLICIT_CALL, tag) && !(tag === 'UNARY' && ('IN' === (_ref = this.tag(i + 1)) || 'OF' === _ref || 'INSTANCEOF' === _ref))) {
|
if (!(callObject || ((prev != null) ? prev.spaced : undefined) && (prev.call || include(IMPLICIT_FUNC, prev[0])) && include(IMPLICIT_CALL, tag))) {
|
||||||
tokens.splice(i, 0, ['CALL_START', '(', token[2]]);
|
return 1;
|
||||||
condition = function(token, i) {
|
|
||||||
var post;
|
|
||||||
if (!seenSingle && token.fromThen) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
tag = token[0];
|
|
||||||
if (('IF' === tag || 'ELSE' === tag || 'UNLESS' === tag || '->' === tag || '=>' === tag)) {
|
|
||||||
seenSingle = true;
|
|
||||||
}
|
|
||||||
if (tag === 'PROPERTY_ACCESS' && this.tag(i - 1) === 'OUTDENT') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return !token.generated && this.tag(i - 1) !== ',' && include(IMPLICIT_END, tag) && (tag !== 'INDENT' || (this.tag(i - 2) !== 'CLASS' && !include(IMPLICIT_BLOCK, this.tag(i - 1)) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
|
|
||||||
};
|
|
||||||
this.detectEnd(i + idx, condition, action);
|
|
||||||
if (prev[0] === '?') {
|
|
||||||
prev[0] = 'FUNC_EXIST';
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
return 1;
|
tokens.splice(i, 0, ['CALL_START', '(', token[2]]);
|
||||||
|
this.detectEnd(i + (callObject ? 2 : 1), function(token, i) {
|
||||||
|
var post;
|
||||||
|
if (!seenSingle && token.fromThen) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
tag = token[0];
|
||||||
|
if (('IF' === tag || 'ELSE' === tag || 'UNLESS' === tag || '->' === tag || '=>' === tag)) {
|
||||||
|
seenSingle = true;
|
||||||
|
}
|
||||||
|
if (tag === 'PROPERTY_ACCESS' && this.tag(i - 1) === 'OUTDENT') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !token.generated && this.tag(i - 1) !== ',' && include(IMPLICIT_END, tag) && (tag !== 'INDENT' || (this.tag(i - 2) !== 'CLASS' && !include(IMPLICIT_BLOCK, this.tag(i - 1)) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
|
||||||
|
}, action);
|
||||||
|
if (prev[0] === '?') {
|
||||||
|
prev[0] = 'FUNC_EXIST';
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
exports.Rewriter.prototype.addImplicitIndentation = function() {
|
exports.Rewriter.prototype.addImplicitIndentation = function() {
|
||||||
@@ -369,7 +365,7 @@
|
|||||||
}
|
}
|
||||||
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
|
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
|
||||||
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
||||||
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'NULL', 'UNARY', 'TRUE', 'FALSE', 'YES', 'NO', 'ON', 'OFF', '@', '->', '=>', '[', '(', '{'];
|
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'NULL', 'UNARY', 'TRUE', 'FALSE', '@', '->', '=>', '[', '(', '{'];
|
||||||
IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','];
|
IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','];
|
||||||
IMPLICIT_END = ['POST_IF', 'POST_UNLESS', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'TERMINATOR', 'INDENT'];
|
IMPLICIT_END = ['POST_IF', 'POST_UNLESS', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'TERMINATOR', 'INDENT'];
|
||||||
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
|
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
|
||||||
|
|||||||
@@ -132,10 +132,7 @@ grammar =
|
|||||||
o "REGEX", -> new Literal $1
|
o "REGEX", -> new Literal $1
|
||||||
o "TRUE", -> new Literal true
|
o "TRUE", -> new Literal true
|
||||||
o "FALSE", -> new Literal false
|
o "FALSE", -> new Literal false
|
||||||
o "YES", -> new Literal true
|
o "NULL", -> new Literal 'null'
|
||||||
o "NO", -> new Literal false
|
|
||||||
o "ON", -> new Literal true
|
|
||||||
o "OFF", -> new Literal false
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Assignment of a variable, property, or index to a value.
|
# Assignment of a variable, property, or index to a value.
|
||||||
@@ -238,7 +235,6 @@ grammar =
|
|||||||
o "Parenthetical", -> new Value $1
|
o "Parenthetical", -> new Value $1
|
||||||
o "Range", -> new Value $1
|
o "Range", -> new Value $1
|
||||||
o "This"
|
o "This"
|
||||||
o "NULL", -> new Value new Literal 'null'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# The general group of accessors into an object, by property, by prototype
|
# The general group of accessors into an object, by property, by prototype
|
||||||
|
|||||||
@@ -518,17 +518,17 @@ JS_KEYWORDS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# CoffeeScript-only keywords.
|
# CoffeeScript-only keywords.
|
||||||
COFFEE_KEYWORDS = [
|
COFFEE_KEYWORDS = ['then', 'unless', 'until', 'loop', 'of', 'by', 'when']
|
||||||
'then', 'unless', 'until', 'loop'
|
|
||||||
'yes', 'no', 'on', 'off'
|
|
||||||
'of', 'by', 'when'
|
|
||||||
]
|
|
||||||
COFFEE_KEYWORDS.push op for all op of COFFEE_ALIASES =
|
COFFEE_KEYWORDS.push op for all op of COFFEE_ALIASES =
|
||||||
and : '&&'
|
and : '&&'
|
||||||
or : '||'
|
or : '||'
|
||||||
is : '=='
|
is : '=='
|
||||||
isnt : '!='
|
isnt : '!='
|
||||||
not : '!'
|
not : '!'
|
||||||
|
yes : 'TRUE'
|
||||||
|
no : 'FALSE'
|
||||||
|
on : 'TRUE'
|
||||||
|
off : 'FALSE'
|
||||||
COFFEE_ALIASES['==='] = '=='
|
COFFEE_ALIASES['==='] = '=='
|
||||||
|
|
||||||
# The list of keywords that are reserved by JavaScript, but not used, or are
|
# The list of keywords that are reserved by JavaScript, but not used, or are
|
||||||
|
|||||||
@@ -132,20 +132,20 @@ class exports.Rewriter
|
|||||||
action = (token, i) -> @tokens.splice i, 0, ['}', '}', token[2]]
|
action = (token, i) -> @tokens.splice i, 0, ['}', '}', token[2]]
|
||||||
@scanTokens (token, i, tokens) ->
|
@scanTokens (token, i, tokens) ->
|
||||||
if include EXPRESSION_START, tag = token[0]
|
if include EXPRESSION_START, tag = token[0]
|
||||||
stack.push(if tag is 'INDENT' and @tag(i - 1) is '{' then '{' else tag)
|
stack.push if tag is 'INDENT' and @tag(i - 1) is '{' then '{' else tag
|
||||||
|
return 1
|
||||||
if include EXPRESSION_END, tag
|
if include EXPRESSION_END, tag
|
||||||
stack.pop()
|
stack.pop()
|
||||||
last = stack[stack.length - 1]
|
return 1
|
||||||
if tag is ':' and not (last and last[0] is '{')
|
return 1 unless tag is ':' and stack[stack.length - 1] isnt '{'
|
||||||
stack.push '{'
|
stack.push '{'
|
||||||
idx = if @tag(i - 2) is '@' then i - 2 else i - 1
|
idx = if @tag(i - 2) is '@' then i - 2 else i - 1
|
||||||
idx -= 2 if @tag(idx - 2) is 'HERECOMMENT'
|
idx -= 2 if @tag(idx - 2) is 'HERECOMMENT'
|
||||||
tok = ['{', '{', token[2]]
|
tok = ['{', '{', token[2]]
|
||||||
tok.generated = yes
|
tok.generated = yes
|
||||||
tokens.splice idx, 0, tok
|
tokens.splice idx, 0, tok
|
||||||
@detectEnd i + 2, condition, action
|
@detectEnd i + 2, condition, action
|
||||||
return 2
|
2
|
||||||
1
|
|
||||||
|
|
||||||
# Methods may be optionally called without parentheses, for simple cases.
|
# Methods may be optionally called without parentheses, for simple cases.
|
||||||
# Insert the implicit parentheses here, so that the parser doesn't have to
|
# Insert the implicit parentheses here, so that the parser doesn't have to
|
||||||
@@ -160,31 +160,28 @@ class exports.Rewriter
|
|||||||
classLine = yes if tag is 'CLASS'
|
classLine = yes if tag is 'CLASS'
|
||||||
prev = tokens[i - 1]
|
prev = tokens[i - 1]
|
||||||
next = tokens[i + 1]
|
next = tokens[i + 1]
|
||||||
idx = 1
|
|
||||||
callObject = not classLine and tag is 'INDENT' and
|
callObject = not classLine and tag is 'INDENT' and
|
||||||
next and next.generated and next[0] is '{' and
|
next and next.generated and next[0] is '{' and
|
||||||
prev and include(IMPLICIT_FUNC, prev[0])
|
prev and include(IMPLICIT_FUNC, prev[0])
|
||||||
idx = 2 if callObject
|
|
||||||
seenSingle = no
|
seenSingle = no
|
||||||
classLine = no if include LINEBREAKS, tag
|
classLine = no if include LINEBREAKS, tag
|
||||||
token.call = yes if prev and not prev.spaced and tag is '?'
|
token.call = yes if prev and not prev.spaced and tag is '?'
|
||||||
if callObject or
|
return 1 unless callObject or
|
||||||
prev and prev.spaced and (prev.call or include(IMPLICIT_FUNC, prev[0])) and include(IMPLICIT_CALL, tag) and
|
prev?.spaced and (prev.call or include(IMPLICIT_FUNC, prev[0])) and
|
||||||
not (tag is 'UNARY' and @tag(i + 1) in ['IN', 'OF', 'INSTANCEOF'])
|
include(IMPLICIT_CALL, tag)
|
||||||
tokens.splice i, 0, ['CALL_START', '(', token[2]]
|
tokens.splice i, 0, ['CALL_START', '(', token[2]]
|
||||||
condition = (token, i) ->
|
@detectEnd i + (if callObject then 2 else 1), (token, i) ->
|
||||||
return yes if not seenSingle and token.fromThen
|
return yes if not seenSingle and token.fromThen
|
||||||
[tag] = token
|
[tag] = token
|
||||||
seenSingle = yes if tag in ['IF', 'ELSE', 'UNLESS', '->', '=>']
|
seenSingle = yes if tag in ['IF', 'ELSE', 'UNLESS', '->', '=>']
|
||||||
return yes if tag is 'PROPERTY_ACCESS' and @tag(i - 1) is 'OUTDENT'
|
return yes if tag is 'PROPERTY_ACCESS' and @tag(i - 1) is 'OUTDENT'
|
||||||
not token.generated and @tag(i - 1) isnt ',' and include(IMPLICIT_END, tag) and
|
not token.generated and @tag(i - 1) isnt ',' and include(IMPLICIT_END, tag) and
|
||||||
(tag isnt 'INDENT' or
|
(tag isnt 'INDENT' or
|
||||||
(@tag(i - 2) isnt 'CLASS' and not include(IMPLICIT_BLOCK, @tag(i - 1)) and
|
(@tag(i - 2) isnt 'CLASS' and not include(IMPLICIT_BLOCK, @tag(i - 1)) and
|
||||||
not ((post = @tokens[i + 1]) and post.generated and post[0] is '{')))
|
not ((post = @tokens[i + 1]) and post.generated and post[0] is '{')))
|
||||||
@detectEnd i + idx, condition, action
|
, action
|
||||||
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
|
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
|
||||||
return 2
|
2
|
||||||
1
|
|
||||||
|
|
||||||
# Because our grammar is LALR(1), it can't handle some single-line
|
# Because our grammar is LALR(1), it can't handle some single-line
|
||||||
# expressions that lack ending delimiters. The **Rewriter** adds the implicit
|
# expressions that lack ending delimiters. The **Rewriter** adds the implicit
|
||||||
@@ -331,8 +328,7 @@ IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@
|
|||||||
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
|
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
|
||||||
IMPLICIT_CALL = [
|
IMPLICIT_CALL = [
|
||||||
'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS'
|
'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS'
|
||||||
'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'NULL', 'UNARY'
|
'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'NULL', 'UNARY', 'TRUE', 'FALSE'
|
||||||
'TRUE', 'FALSE', 'YES', 'NO', 'ON', 'OFF'
|
|
||||||
'@', '->', '=>', '[', '(', '{'
|
'@', '->', '=>', '[', '(', '{'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user