Permalink
Browse files

Added some preliminary support for defer epxressions. Small modificat…

…ions to the lexer, parser and rewriter to get this working. Need to finish up the output path here, of course.
  • Loading branch information...
1 parent 6f69b86 commit 81c9d5747cf07f972881301a563e6ee9089d8dc0 @maxtaco committed with Nov 25, 2011
View
13 lib/coffee-script/grammar.js
@@ -31,7 +31,7 @@
],
Line: [o('Expression'), o('Statement')],
Statement: [
- o('Return'), o('Comment'), o('STATEMENT', function() {
+ o('Return'), o('Throw'), o('Comment'), o('STATEMENT', function() {
return new Literal($1);
}), o('Await')
],
@@ -42,7 +42,7 @@
return new Await(Block.wrap([$2]));
})
],
- Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class'), o('Throw')],
+ Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class'), o('Defer')],
Block: [
o('INDENT OUTDENT', function() {
return new Block;
@@ -67,8 +67,6 @@
return new Literal($1);
}), o('REGEX', function() {
return new Literal($1);
- }), o('DEBUGGER', function() {
- return new Literal($1);
}), o('BOOL', function() {
var val;
val = new Literal($1);
@@ -153,7 +151,7 @@
}), o('Value Accessor', function() {
return $1.add($2);
}), o('Invocation Accessor', function() {
- return new Value($1, [].concat($2));
+ return new Value($1, [$2]);
}), o('ThisProperty')
],
Assignable: [
@@ -247,6 +245,11 @@
return new Call('super', $2);
})
],
+ Defer: [
+ o('DEFER Arguments', function() {
+ return new Defer($2);
+ })
+ ],
OptFuncExist: [
o('', function() {
return false;
View
33 lib/coffee-script/lexer.js
@@ -14,7 +14,7 @@
function Lexer() {}
Lexer.prototype.tokenize = function(code, opts) {
- var i, tag;
+ var debug, i, ret, t, tag;
if (opts == null) opts = {};
if (WHITESPACE.test(code)) code = "\n" + code;
code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
@@ -33,7 +33,32 @@
this.closeIndentation();
if (tag = this.ends.pop()) this.error("missing " + tag);
if (opts.rewrite === false) return this.tokens;
- return (new Rewriter).rewrite(this.tokens);
+ debug = false;
+ if (debug) {
+ console.log(((function() {
+ var _i, _len, _ref3, _results;
+ _ref3 = this.tokens;
+ _results = [];
+ for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
+ t = _ref3[_i];
+ _results.push(t[0] + '/' + t[1]);
+ }
+ return _results;
+ }).call(this)).join(' '));
+ }
+ ret = (new Rewriter).rewrite(this.tokens);
+ if (debug) {
+ console.log(((function() {
+ var _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = ret.length; _i < _len; _i++) {
+ t = ret[_i];
+ _results.push(t[0] + '/' + t[1]);
+ }
+ return _results;
+ })()).join(' '));
+ }
+ return ret;
};
Lexer.prototype.identifierToken = function() {
@@ -612,7 +637,7 @@
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
- COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when', 'await'];
+ COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when', 'await', 'defer'];
COFFEE_ALIAS_MAP = {
and: '&&',
@@ -703,7 +728,7 @@
NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING');
- CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
+ CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER', 'DEFER'];
INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL');
View
16 lib/coffee-script/nodes.js
@@ -1,5 +1,5 @@
(function() {
- var Access, Arr, Assign, Await, Base, Block, CALL_CONTINUATION, Call, Class, Closure, Code, Comment, CpsCascade, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, tame, unfoldSoak, utility, _ref;
+ var Access, Arr, Assign, Await, Base, Block, CALL_CONTINUATION, Call, Class, Closure, Code, Comment, CpsCascade, Defer, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, tame, unfoldSoak, utility, _ref;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; };
Scope = require('./scope').Scope;
@@ -2184,6 +2184,20 @@
})();
+ exports.Defer = Defer = (function() {
+
+ __extends(Defer, Base);
+
+ function Defer(args) {
+ this.args = args;
+ }
+
+ Defer.prototype.children = ['args'];
+
+ return Defer;
+
+ })();
+
exports.Await = Await = (function() {
__extends(Await, Base);
View
326 lib/coffee-script/parser.js
165 additions, 161 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
2 lib/coffee-script/rewriter.js
@@ -294,7 +294,7 @@
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', 'DEFER'];
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', 'SUPER', '@', '->', '=>', '[', '(', '{', '--', '++'];
View
5 src/grammar.coffee
@@ -104,6 +104,7 @@ grammar =
o 'Switch'
o 'Class'
o 'Throw'
+ o 'Defer'
]
# An indented block of expressions. Note that the [Rewriter](rewriter.html)
@@ -304,6 +305,10 @@ grammar =
o 'SUPER Arguments', -> new Call 'super', $2
]
+ Defer : [
+ o 'DEFER Arguments', -> new Defer $2
+ ]
+
# An optional existence check on a function.
OptFuncExist: [
o '', -> no
View
12 src/lexer.coffee
@@ -63,7 +63,13 @@ exports.Lexer = class Lexer
@closeIndentation()
@error "missing #{tag}" if tag = @ends.pop()
return @tokens if opts.rewrite is off
- (new Rewriter).rewrite @tokens
+ debug = false # MK REMOVE: turn to true to debug the lexer!!
+ if debug
+ console.log (t[0] + '/' + t[1] for t in @tokens).join ' '
+ ret = (new Rewriter).rewrite @tokens
+ if debug
+ console.log (t[0] + '/' + t[1] for t in ret).join ' '
+ ret
# Tokenizers
# ----------
@@ -557,7 +563,7 @@ JS_KEYWORDS = [
]
# CoffeeScript-only keywords.
-COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when', 'await' ]
+COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when', 'await', 'defer' ]
COFFEE_ALIAS_MAP =
and : '&&'
@@ -701,7 +707,7 @@ NOT_SPACED_REGEX = NOT_REGEX.concat ')', '}', 'THIS', 'IDENTIFIER', 'STRING'
# Tokens which could legitimately be invoked or indexed. An opening
# parentheses or bracket following these tokens will be recorded as the start
# of a function invocation or indexing operation.
-CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']
+CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER', 'DEFER']
INDEXABLE = CALLABLE.concat 'NUMBER', 'BOOL'
# Tokens that, when immediately preceding a `WHEN`, indicate that the `WHEN`
View
15 src/nodes.coffee
@@ -1776,6 +1776,21 @@ exports.In = class In extends Base
toString: (idt) ->
super idt, @constructor.name + if @negated then '!' else ''
+#### Defer
+
+exports.Defer = class Defer extends Base
+ constructor : (args) ->
+ @args = args
+
+ children : ['args']
+
+##### Call or Defer
+#
+#exports.CallOrDefer = class CallOrDefer
+# wrap: (val, args, opt) ->
+# if val == 'defer' new Defer args
+# else new Call val, args, opts
+
#### Await
exports.Await = class Await extends Base
View
2 src/rewriter.coffee
@@ -287,7 +287,7 @@ for [left, rite] in BALANCED_PAIRS
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat EXPRESSION_END
# Tokens that, if followed by an `IMPLICIT_CALL`, indicate a function invocation.
-IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']
+IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS', 'DEFER']
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
IMPLICIT_CALL = [

0 comments on commit 81c9d57

Please sign in to comment.