Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: jashkenas/coffeescript
...
head fork: andreypopp/coffee-script
Checking mergeability… Don't worry, you can still create the pull request.
  • 4 commits
  • 11 files changed
  • 0 commit comments
  • 1 contributor
Commits on Nov 12, 2011
@andreypopp andreypopp Add option to compile file as anonymous AMD
Add --amd compile options to compile source file as anonymous AMD module, for
example this smippet:

  msg = "hello"
  alert msg
  _ = require "underscore"

would be compiled to:

  define(function(require) {
    var msg, _;
    msg = "hello";
    alert(msg);
    _ = require("underscore");
  });

Thus reducing the need to do it by hand and saving us one indentation level.
a9b607c
@andreypopp andreypopp Add `amd` statement for declarding AMD modules
Add

  amd <moduleid>

on top of the source file to declare file as AMD module. If <moduleid> is omited
then module will be compiled as anonymous AMD module.
15d3022
Commits on Nov 13, 2011
@andreypopp andreypopp Insert newline after AMD. b6db07f
@andreypopp andreypopp Recompile coffee. 597df46
View
5 lib/coffee-script/coffee-script.js
@@ -33,9 +33,12 @@
exports.helpers = require('./helpers');
exports.compile = compile = function(code, options) {
+ var node;
if (options == null) options = {};
try {
- return (parser.parse(lexer.tokenize(code))).compile(options);
+ node = parser.parse(lexer.tokenize(code));
+ if (options.amd) node = node.wrapInModule();
+ return node.compile(options);
} catch (err) {
if (options.filename) {
err.message = "In " + options.filename + ", " + err.message;
View
5 lib/coffee-script/command.js
@@ -27,7 +27,7 @@
BANNER = 'Usage: coffee [options] path/to/script.coffee\n\nIf called without options, `coffee` will run your script.';
- SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
+ SWITCHES = [['--amd', 'compile as anonymous AMD, implies -b/--bare'], ['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
opts = {};
@@ -293,7 +293,8 @@
compileOptions = function(filename) {
return {
filename: filename,
- bare: opts.bare
+ bare: opts.bare,
+ amd: opts.amd
};
};
View
12 lib/coffee-script/grammar.js
@@ -17,10 +17,20 @@
grammar = {
Root: [
- o('', function() {
+ o('Module TERMINATOR Body', function() {
+ return $1.wrap($3);
+ }), o('', function() {
return new Block;
}), o('Body'), o('Block TERMINATOR')
],
+ Module: [
+ o('AMD ModuleName', function() {
+ return new Module($2);
+ }), o('AMD', function() {
+ return new Module;
+ })
+ ],
+ ModuleName: [o('IDENTIFIER')],
Body: [
o('Line', function() {
return Block.wrap([$1]);
View
2  lib/coffee-script/lexer.js
@@ -591,7 +591,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'];
+ COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when', 'amd'];
COFFEE_ALIAS_MAP = {
and: '&&',
View
68 lib/coffee-script/nodes.js
@@ -1,5 +1,5 @@
(function() {
- var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, 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, unfoldSoak, utility, _ref;
+ var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, 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, Module, 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, 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;
@@ -163,6 +163,11 @@
return node;
};
+ Base.prototype.wrapInModule = function(name) {
+ if (name == null) name = null;
+ return new Module(name, this);
+ };
+
Base.prototype.children = [];
Base.prototype.isStatement = NO;
@@ -300,15 +305,19 @@
}
};
- Block.prototype.compileRoot = function(o) {
+ Block.prototype.compileRoot = function(o, indent) {
var code;
- o.indent = this.tab = o.bare ? '' : TAB;
+ if (indent == null) indent = false;
+ o.indent = this.tab = o.bare && !indent ? '' : TAB;
o.scope = new Scope(null, this, null);
o.level = LEVEL_TOP;
this.spaced = true;
code = this.compileWithDeclarations(o);
- if (o.bare || o.scope.variables.length <= 1) return code;
- return "(function() {\n" + code + "\n}).call(this);\n";
+ if (o.bare || o.scope.variables.length <= 1) {
+ return code;
+ } else {
+ return "(function() {\n" + code + "\n}).call(this);\n";
+ }
};
Block.prototype.compileWithDeclarations = function(o) {
@@ -411,6 +420,55 @@
})();
+ exports.Module = Module = (function() {
+
+ __extends(Module, Base);
+
+ function Module(identifier, block) {
+ if (block == null) block = null;
+ this.identifier = identifier;
+ this.block = block;
+ }
+
+ Module.prototype.children = ['block'];
+
+ Module.prototype.isStatement = YES;
+
+ Module.prototype.compile = function(o, level) {
+ var code, moduleNamePart;
+ o.bare = true;
+ code = this.block ? this.block.compileRoot(o, true) : '';
+ moduleNamePart = this.identifier ? "\"" + this.identifier + "\", " : '';
+ return "define(" + moduleNamePart + "[\"require\"], function(require) {\n" + code + "\n});\n";
+ };
+
+ Module.prototype.wrap = function(block) {
+ this.block = block;
+ return this;
+ };
+
+ Module.prototype.toString = function(idt, name) {
+ var tree;
+ if (idt == null) idt = '';
+ if (name == null) name = this.constructor.name;
+ tree = '\n' + idt + name;
+ if (this.identifier !== void 0) tree += " \"" + this.identifier + "\"";
+ if (this.soak) tree += '?';
+ this.eachChild(function(node) {
+ return tree += node.toString(idt + TAB);
+ });
+ return tree;
+ };
+
+ Module.prototype.wrapInModule = function(name) {
+ if (name == null) name = null;
+ return this;
+ };
+
+ return Module;
+
+ })();
+
exports.Return = Return = (function() {
__extends(Return, Base);
View
377 lib/coffee-script/parser.js
193 additions, 184 deletions not shown
View
5 src/coffee-script.coffee
@@ -33,7 +33,10 @@ exports.helpers = require './helpers'
# compiler.
exports.compile = compile = (code, options = {}) ->
try
- (parser.parse lexer.tokenize code).compile options
+ node = parser.parse lexer.tokenize code
+ if options.amd
+ node = node.wrapInModule()
+ node.compile options
catch err
err.message = "In #{options.filename}, #{err.message}" if options.filename
throw err
View
3  src/command.coffee
@@ -28,6 +28,7 @@ BANNER = '''
# The list of all the valid option flags that `coffee` knows how to handle.
SWITCHES = [
+ [ '--amd', 'compile as anonymous AMD, implies -b/--bare']
['-b', '--bare', 'compile without a top-level function wrapper']
['-c', '--compile', 'compile to JavaScript and save as .js files']
['-e', '--eval', 'pass a string from the command line as input']
@@ -241,7 +242,7 @@ parseOptions = ->
sources = o.arguments
# The compile-time options to pass to the CoffeeScript compiler.
-compileOptions = (filename) -> {filename, bare: opts.bare}
+compileOptions = (filename) -> {filename, bare: opts.bare, amd: opts.amd}
# Start up a new Node.js instance with the arguments in `--nodejs` passed to
# the `node` binary, preserving the other options.
View
10 src/grammar.coffee
@@ -56,11 +56,21 @@ grammar =
# The **Root** is the top-level node in the syntax tree. Since we parse bottom-up,
# all parsing must end here.
Root: [
+ o 'Module TERMINATOR Body', -> $1.wrap $3
o '', -> new Block
o 'Body'
o 'Block TERMINATOR'
]
+ Module: [
+ o 'AMD ModuleName', -> new Module $2
+ o 'AMD', -> new Module
+ ]
+
+ ModuleName: [
+ o 'IDENTIFIER'
+ ]
+
# Any list of statements and expressions, separated by line breaks or semicolons.
Body: [
o 'Line', -> Block.wrap [$1]
View
2  src/lexer.coffee
@@ -542,7 +542,7 @@ JS_KEYWORDS = [
]
# CoffeeScript-only keywords.
-COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when']
+COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when', 'amd']
COFFEE_ALIAS_MAP =
and : '&&'
View
53 src/nodes.coffee
@@ -134,6 +134,10 @@ exports.Base = class Base
continue until node is node = node.unwrap()
node
+ # Wrap node in module
+ wrapInModule: (name = null) ->
+ new Module(name, this)
+
# Default implementations of the common node properties and methods. Nodes
# will override these with custom logic, if needed.
children: []
@@ -242,15 +246,17 @@ exports.Block = class Block extends Base
# a safety closure, unless requested not to.
# It would be better not to generate them in the first place, but for now,
# clean up obvious double-parentheses.
- compileRoot: (o) ->
- o.indent = @tab = if o.bare then '' else TAB
+ compileRoot: (o, indent = false) ->
+ o.indent = @tab = if o.bare and not indent then '' else TAB
o.scope = new Scope null, this, null
o.level = LEVEL_TOP
@spaced = yes
code = @compileWithDeclarations o
# the `1` below accounts for `arguments`, always "in scope"
- return code if o.bare or o.scope.variables.length <= 1
- "(function() {\n#{code}\n}).call(this);\n"
+ if o.bare or o.scope.variables.length <= 1
+ code
+ else
+ "(function() {\n#{code}\n}).call(this);\n"
# Compile the expressions body for the contents of a function, with
# declarations of all inner variables pushed up to the top.
@@ -323,6 +329,45 @@ exports.Literal = class Literal extends Base
toString: ->
' "' + @value + '"'
+#### Module
+
+# A module declaration statement which wraps block of code
+# and set *amd* compilation flag.
+exports.Module = class Module extends Base
+ constructor: (identifier, block = null) ->
+ @identifier = identifier
+ @block = block
+
+ children: ['block']
+ isStatement: YES
+
+ compile: (o, level) ->
+ o.bare = true
+ code = if @block
+ @block.compileRoot(o, true)
+ else
+ ''
+ moduleNamePart = if @identifier
+ "\"#{@identifier}\", "
+ else
+ ''
+ "define(#{moduleNamePart}[\"require\"], function(require) {\n#{code}\n});\n"
+
+ wrap: (block) ->
+ @block = block
+ this
+
+ toString: (idt = '', name = @constructor.name) ->
+ tree = '\n' + idt + name
+ if @identifier isnt undefined
+ tree += " \"#{@identifier}\""
+ tree += '?' if @soak
+ @eachChild (node) -> tree += node.toString idt + TAB
+ tree
+
+ wrapInModule: (name = null) ->
+ this
+
#### Return
# A `return` is a *pureStatement* -- wrapping it in a closure wouldn't

No commit comments for this range

Something went wrong with that request. Please try again.