removed YES/NO/ON/OFF from rewriter/parser

This commit is contained in:
satyr
2010-10-08 00:56:01 +09:00
parent 9447796d8e
commit 4f486bc444
7 changed files with 260 additions and 284 deletions

View File

@@ -68,14 +68,8 @@
return new Literal(true);
}), o("FALSE", function() {
return new Literal(false);
}), o("YES", function() {
return new Literal(true);
}), o("NO", function() {
return new Literal(false);
}), o("ON", function() {
return new Literal(true);
}), o("OFF", function() {
return new Literal(false);
}), o("NULL", function() {
return new Literal('null');
})
],
Assign: [
@@ -178,9 +172,7 @@
return new Value($1);
}), o("Range", function() {
return new Value($1);
}), o("This"), o("NULL", function() {
return new Value(new Literal('null'));
})
}), o("This")
],
Accessor: [
o("PROPERTY_ACCESS Identifier", function() {

View File

@@ -577,13 +577,17 @@
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'];
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 = {
and: '&&',
or: '||',
is: '==',
isnt: '!=',
not: '!'
not: '!',
yes: 'TRUE',
no: 'FALSE',
on: 'TRUE',
off: 'FALSE'
})) {
COFFEE_KEYWORDS.push(op);
}

File diff suppressed because one or more lines are too long

View File

@@ -146,27 +146,28 @@
return this.tokens.splice(i, 0, ['}', '}', token[2]]);
};
return this.scanTokens(function(token, i, tokens) {
var idx, last, tag, tok;
var idx, tag, tok;
if (include(EXPRESSION_START, tag = token[0])) {
stack.push(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag);
return 1;
}
if (include(EXPRESSION_END, tag)) {
stack.pop();
return 1;
}
last = stack[stack.length - 1];
if (tag === ':' && !(last && last[0] === '{')) {
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;
if (!(tag === ':' && stack[stack.length - 1] !== '{')) {
return 1;
}
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() {
@@ -178,18 +179,14 @@
return this.tokens.splice(idx, 0, ['CALL_END', ')', token[2]]);
};
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];
if (tag === 'CLASS') {
classLine = true;
}
prev = tokens[i - 1];
next = tokens[i + 1];
idx = 1;
callObject = !classLine && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && include(IMPLICIT_FUNC, prev[0]);
if (callObject) {
idx = 2;
}
seenSingle = false;
if (include(LINEBREAKS, tag)) {
classLine = false;
@@ -197,29 +194,28 @@
if (prev && !prev.spaced && tag === '?') {
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))) {
tokens.splice(i, 0, ['CALL_START', '(', token[2]]);
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;
if (!(callObject || ((prev != null) ? prev.spaced : undefined) && (prev.call || include(IMPLICIT_FUNC, prev[0])) && include(IMPLICIT_CALL, tag))) {
return 1;
}
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() {
@@ -369,7 +365,7 @@
}
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
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_END = ['POST_IF', 'POST_UNLESS', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'TERMINATOR', 'INDENT'];
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];

View File

@@ -132,10 +132,7 @@ grammar =
o "REGEX", -> new Literal $1
o "TRUE", -> new Literal true
o "FALSE", -> new Literal false
o "YES", -> new Literal true
o "NO", -> new Literal false
o "ON", -> new Literal true
o "OFF", -> new Literal false
o "NULL", -> new Literal 'null'
]
# Assignment of a variable, property, or index to a value.
@@ -238,7 +235,6 @@ grammar =
o "Parenthetical", -> new Value $1
o "Range", -> new Value $1
o "This"
o "NULL", -> new Value new Literal 'null'
]
# The general group of accessors into an object, by property, by prototype

View File

@@ -518,17 +518,17 @@ JS_KEYWORDS = [
]
# CoffeeScript-only keywords.
COFFEE_KEYWORDS = [
'then', 'unless', 'until', 'loop'
'yes', 'no', 'on', 'off'
'of', 'by', 'when'
]
COFFEE_KEYWORDS = ['then', 'unless', 'until', 'loop', 'of', 'by', 'when']
COFFEE_KEYWORDS.push op for all op of COFFEE_ALIASES =
and : '&&'
or : '||'
is : '=='
isnt : '!='
not : '!'
yes : 'TRUE'
no : 'FALSE'
on : 'TRUE'
off : 'FALSE'
COFFEE_ALIASES['==='] = '=='
# The list of keywords that are reserved by JavaScript, but not used, or are

View File

@@ -132,20 +132,20 @@ class exports.Rewriter
action = (token, i) -> @tokens.splice i, 0, ['}', '}', token[2]]
@scanTokens (token, i, tokens) ->
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
stack.pop()
last = stack[stack.length - 1]
if tag is ':' and not (last and last[0] is '{')
stack.push '{'
idx = if @tag(i - 2) is '@' then i - 2 else i - 1
idx -= 2 if @tag(idx - 2) is 'HERECOMMENT'
tok = ['{', '{', token[2]]
tok.generated = yes
tokens.splice idx, 0, tok
@detectEnd i + 2, condition, action
return 2
1
return 1
return 1 unless tag is ':' and stack[stack.length - 1] isnt '{'
stack.push '{'
idx = if @tag(i - 2) is '@' then i - 2 else i - 1
idx -= 2 if @tag(idx - 2) is 'HERECOMMENT'
tok = ['{', '{', token[2]]
tok.generated = yes
tokens.splice idx, 0, tok
@detectEnd i + 2, condition, action
2
# Methods may be optionally called without parentheses, for simple cases.
# 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'
prev = tokens[i - 1]
next = tokens[i + 1]
idx = 1
callObject = not classLine and tag is 'INDENT' and
next and next.generated and next[0] is '{' and
prev and include(IMPLICIT_FUNC, prev[0])
idx = 2 if callObject
seenSingle = no
classLine = no if include LINEBREAKS, tag
token.call = yes if prev and not prev.spaced and tag is '?'
if callObject or
prev and prev.spaced and (prev.call or include(IMPLICIT_FUNC, prev[0])) and include(IMPLICIT_CALL, tag) and
not (tag is 'UNARY' and @tag(i + 1) in ['IN', 'OF', 'INSTANCEOF'])
tokens.splice i, 0, ['CALL_START', '(', token[2]]
condition = (token, i) ->
return yes if not seenSingle and token.fromThen
[tag] = token
seenSingle = yes if tag in ['IF', 'ELSE', 'UNLESS', '->', '=>']
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
(tag isnt 'INDENT' or
(@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 '{')))
@detectEnd i + idx, condition, action
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
return 2
1
return 1 unless callObject or
prev?.spaced and (prev.call or include(IMPLICIT_FUNC, prev[0])) and
include(IMPLICIT_CALL, tag)
tokens.splice i, 0, ['CALL_START', '(', token[2]]
@detectEnd i + (if callObject then 2 else 1), (token, i) ->
return yes if not seenSingle and token.fromThen
[tag] = token
seenSingle = yes if tag in ['IF', 'ELSE', 'UNLESS', '->', '=>']
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
(tag isnt 'INDENT' or
(@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 '{')))
, action
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
2
# Because our grammar is LALR(1), it can't handle some single-line
# 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.
IMPLICIT_CALL = [
'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS'
'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'NULL', 'UNARY'
'TRUE', 'FALSE', 'YES', 'NO', 'ON', 'OFF'
'IF', 'UNLESS', 'TRY', 'SWITCH', 'THIS', 'NULL', 'UNARY', 'TRUE', 'FALSE'
'@', '->', '=>', '[', '(', '{'
]