Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

still not working...work in progress

  • Loading branch information...
commit 07c5d39ef54fdaa2ee20c1f1f3f19cab3aeca2e4 1 parent e5e38e5
Chris Coyne authored
91 lib/coffee-script/browser.js
View
@@ -0,0 +1,91 @@
+// Generated by CoffeeScript 1.3.1
+(function() {
+ var CoffeeScript, runScripts;
+
+ CoffeeScript = require('./coffee-script');
+
+ CoffeeScript.require = require;
+
+ CoffeeScript["eval"] = function(code, options) {
+ if (options == null) {
+ options = {};
+ }
+ if (options.bare == null) {
+ options.bare = true;
+ }
+ return eval(CoffeeScript.compile(code, options));
+ };
+
+ CoffeeScript.run = function(code, options) {
+ if (options == null) {
+ options = {};
+ }
+ options.bare = true;
+ return Function(CoffeeScript.compile(code, options))();
+ };
+
+ if (typeof window === "undefined" || window === null) {
+ return;
+ }
+
+ CoffeeScript.load = function(url, callback) {
+ var xhr;
+ xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP');
+ xhr.open('GET', url, true);
+ if ('overrideMimeType' in xhr) {
+ xhr.overrideMimeType('text/plain');
+ }
+ xhr.onreadystatechange = function() {
+ var _ref;
+ if (xhr.readyState === 4) {
+ if ((_ref = xhr.status) === 0 || _ref === 200) {
+ CoffeeScript.run(xhr.responseText);
+ } else {
+ throw new Error("Could not load " + url);
+ }
+ if (callback) {
+ return callback();
+ }
+ }
+ };
+ return xhr.send(null);
+ };
+
+ runScripts = function() {
+ var coffees, execute, index, length, s, scripts;
+ scripts = document.getElementsByTagName('script');
+ coffees = (function() {
+ var _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = scripts.length; _i < _len; _i++) {
+ s = scripts[_i];
+ if (s.type === 'text/coffeescript') {
+ _results.push(s);
+ }
+ }
+ return _results;
+ })();
+ index = 0;
+ length = coffees.length;
+ (execute = function() {
+ var script;
+ script = coffees[index++];
+ if ((script != null ? script.type : void 0) === 'text/coffeescript') {
+ if (script.src) {
+ return CoffeeScript.load(script.src, execute);
+ } else {
+ CoffeeScript.run(script.innerHTML);
+ return execute();
+ }
+ }
+ })();
+ return null;
+ };
+
+ if (window.addEventListener) {
+ addEventListener('DOMContentLoaded', runScripts, false);
+ } else {
+ attachEvent('onload', runScripts);
+ }
+
+}).call(this);
111 lib/coffee-script/cake.js
View
@@ -0,0 +1,111 @@
+// Generated by CoffeeScript 1.3.1
+(function() {
+ var CoffeeScript, cakefileDirectory, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
+
+ fs = require('fs');
+
+ path = require('path');
+
+ helpers = require('./helpers');
+
+ optparse = require('./optparse');
+
+ CoffeeScript = require('./coffee-script');
+
+ tasks = {};
+
+ options = {};
+
+ switches = [];
+
+ oparse = null;
+
+ helpers.extend(global, {
+ task: function(name, description, action) {
+ var _ref;
+ if (!action) {
+ _ref = [description, action], action = _ref[0], description = _ref[1];
+ }
+ return tasks[name] = {
+ name: name,
+ description: description,
+ action: action
+ };
+ },
+ option: function(letter, flag, description) {
+ return switches.push([letter, flag, description]);
+ },
+ invoke: function(name) {
+ if (!tasks[name]) {
+ missingTask(name);
+ }
+ return tasks[name].action(options);
+ }
+ });
+
+ exports.run = function() {
+ var arg, args, _i, _len, _ref, _results;
+ global.__originalDirname = fs.realpathSync('.');
+ process.chdir(cakefileDirectory(__originalDirname));
+ args = process.argv.slice(2);
+ CoffeeScript.run(fs.readFileSync('Cakefile').toString(), {
+ filename: 'Cakefile'
+ });
+ oparse = new optparse.OptionParser(switches);
+ if (!args.length) {
+ return printTasks();
+ }
+ try {
+ options = oparse.parse(args);
+ } catch (e) {
+ return fatalError("" + e);
+ }
+ _ref = options["arguments"];
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ arg = _ref[_i];
+ _results.push(invoke(arg));
+ }
+ return _results;
+ };
+
+ printTasks = function() {
+ var cakefilePath, desc, name, relative, spaces, task;
+ relative = path.relative || path.resolve;
+ cakefilePath = path.join(relative(__originalDirname, process.cwd()), 'Cakefile');
+ console.log("" + cakefilePath + " defines the following tasks:\n");
+ for (name in tasks) {
+ task = tasks[name];
+ spaces = 20 - name.length;
+ spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
+ desc = task.description ? "# " + task.description : '';
+ console.log("cake " + name + spaces + " " + desc);
+ }
+ if (switches.length) {
+ return console.log(oparse.help());
+ }
+ };
+
+ fatalError = function(message) {
+ console.error(message + '\n');
+ console.log('To see a list of all tasks/options, run "cake"');
+ return process.exit(1);
+ };
+
+ missingTask = function(task) {
+ return fatalError("No such task: " + task);
+ };
+
+ cakefileDirectory = function(dir) {
+ var parent;
+ if (path.existsSync(path.join(dir, 'Cakefile'))) {
+ return dir;
+ }
+ parent = path.normalize(path.join(dir, '..'));
+ if (parent !== dir) {
+ return cakefileDirectory(parent);
+ }
+ throw new Error("Cakefile not found in " + (process.cwd()));
+ };
+
+}).call(this);
167 lib/coffee-script/coffee-script.js
View
@@ -0,0 +1,167 @@
+// Generated by CoffeeScript 1.3.1
+(function() {
+ var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref,
+ __hasProp = {}.hasOwnProperty;
+
+ fs = require('fs');
+
+ path = require('path');
+
+ _ref = require('./lexer'), Lexer = _ref.Lexer, RESERVED = _ref.RESERVED;
+
+ parser = require('./parser').parser;
+
+ vm = require('vm');
+
+ if (require.extensions) {
+ require.extensions['.coffee'] = function(module, filename) {
+ var content;
+ content = compile(fs.readFileSync(filename, 'utf8'), {
+ filename: filename
+ });
+ return module._compile(content, filename);
+ };
+ } else if (require.registerExtension) {
+ require.registerExtension('.coffee', function(content) {
+ return compile(content);
+ });
+ }
+
+ exports.VERSION = '1.3.1';
+
+ exports.RESERVED = RESERVED;
+
+ exports.helpers = require('./helpers');
+
+ exports.compile = compile = function(code, options) {
+ var header, js, merge;
+ if (options == null) {
+ options = {};
+ }
+ merge = exports.helpers.merge;
+ try {
+ js = (parser.parse(lexer.tokenize(code))).compile(options);
+ if (!options.header) {
+ return js;
+ }
+ } catch (err) {
+ if (options.filename) {
+ err.message = "In " + options.filename + ", " + err.message;
+ }
+ throw err;
+ }
+ header = "Generated by CoffeeScript " + this.VERSION;
+ return "// " + header + "\n" + js;
+ };
+
+ exports.tokens = function(code, options) {
+ return lexer.tokenize(code, options);
+ };
+
+ exports.nodes = function(source, options) {
+ if (typeof source === 'string') {
+ return parser.parse(lexer.tokenize(source, options));
+ } else {
+ return parser.parse(source);
+ }
+ };
+
+ exports.run = function(code, options) {
+ var mainModule;
+ if (options == null) {
+ options = {};
+ }
+ mainModule = require.main;
+ mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.';
+ mainModule.moduleCache && (mainModule.moduleCache = {});
+ mainModule.paths = require('module')._nodeModulePaths(path.dirname(fs.realpathSync(options.filename)));
+ if (path.extname(mainModule.filename) !== '.coffee' || require.extensions) {
+ return mainModule._compile(compile(code, options), mainModule.filename);
+ } else {
+ return mainModule._compile(code, mainModule.filename);
+ }
+ };
+
+ exports["eval"] = function(code, options) {
+ var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref1, _ref2, _require;
+ if (options == null) {
+ options = {};
+ }
+ if (!(code = code.trim())) {
+ return;
+ }
+ Script = vm.Script;
+ if (Script) {
+ if (options.sandbox != null) {
+ if (options.sandbox instanceof Script.createContext().constructor) {
+ sandbox = options.sandbox;
+ } else {
+ sandbox = Script.createContext();
+ _ref1 = options.sandbox;
+ for (k in _ref1) {
+ if (!__hasProp.call(_ref1, k)) continue;
+ v = _ref1[k];
+ sandbox[k] = v;
+ }
+ }
+ sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox;
+ } else {
+ sandbox = global;
+ }
+ sandbox.__filename = options.filename || 'eval';
+ sandbox.__dirname = path.dirname(sandbox.__filename);
+ if (!(sandbox !== global || sandbox.module || sandbox.require)) {
+ Module = require('module');
+ sandbox.module = _module = new Module(options.modulename || 'eval');
+ sandbox.require = _require = function(path) {
+ return Module._load(path, _module, true);
+ };
+ _module.filename = sandbox.__filename;
+ _ref2 = Object.getOwnPropertyNames(require);
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ r = _ref2[_i];
+ if (r !== 'paths') {
+ _require[r] = require[r];
+ }
+ }
+ _require.paths = _module.paths = Module._nodeModulePaths(process.cwd());
+ _require.resolve = function(request) {
+ return Module._resolveFilename(request, _module);
+ };
+ }
+ }
+ o = {};
+ for (k in options) {
+ if (!__hasProp.call(options, k)) continue;
+ v = options[k];
+ o[k] = v;
+ }
+ o.bare = true;
+ js = compile(code, o);
+ if (sandbox === global) {
+ return vm.runInThisContext(js);
+ } else {
+ return vm.runInContext(js, sandbox);
+ }
+ };
+
+ lexer = new Lexer;
+
+ parser.lexer = {
+ lex: function() {
+ var tag, _ref1;
+ _ref1 = this.tokens[this.pos++] || [''], tag = _ref1[0], this.yytext = _ref1[1], this.yylineno = _ref1[2];
+ return tag;
+ },
+ setInput: function(tokens) {
+ this.tokens = tokens;
+ return this.pos = 0;
+ },
+ upcomingInput: function() {
+ return "";
+ }
+ };
+
+ parser.yy = require('./nodes');
+
+}).call(this);
502 lib/coffee-script/command.js
View
@@ -0,0 +1,502 @@
+// Generated by CoffeeScript 1.3.1
+(function() {
+ var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, forkNode, fs, helpers, hidden, joinTimeout, lint, loadRequires, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, version, wait, watch, watchDir, watchers, writeJs, _ref;
+
+ fs = require('fs');
+
+ path = require('path');
+
+ helpers = require('./helpers');
+
+ optparse = require('./optparse');
+
+ CoffeeScript = require('./coffee-script');
+
+ _ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec;
+
+ EventEmitter = require('events').EventEmitter;
+
+ helpers.extend(CoffeeScript, new EventEmitter);
+
+ printLine = function(line) {
+ return process.stdout.write(line + '\n');
+ };
+
+ printWarn = function(line) {
+ return process.stderr.write(line + '\n');
+ };
+
+ hidden = function(file) {
+ return /^\.|~$/.test(file);
+ };
+
+ BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\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']];
+
+ opts = {};
+
+ sources = [];
+
+ sourceCode = [];
+
+ notSources = {};
+
+ watchers = {};
+
+ optionParser = null;
+
+ exports.run = function() {
+ var literals, source, _i, _len, _results;
+ parseOptions();
+ if (opts.nodejs) {
+ return forkNode();
+ }
+ if (opts.help) {
+ return usage();
+ }
+ if (opts.version) {
+ return version();
+ }
+ if (opts.require) {
+ loadRequires();
+ }
+ if (opts.interactive) {
+ return require('./repl');
+ }
+ if (opts.watch && !fs.watch) {
+ return printWarn("The --watch feature depends on Node v0.6.0+. You are running " + process.version + ".");
+ }
+ if (opts.stdio) {
+ return compileStdio();
+ }
+ if (opts["eval"]) {
+ return compileScript(null, sources[0]);
+ }
+ if (!sources.length) {
+ return require('./repl');
+ }
+ literals = opts.run ? sources.splice(1) : [];
+ process.argv = process.argv.slice(0, 2).concat(literals);
+ process.argv[0] = 'coffee';
+ process.execPath = require.main.filename;
+ _results = [];
+ for (_i = 0, _len = sources.length; _i < _len; _i++) {
+ source = sources[_i];
+ _results.push(compilePath(source, true, path.normalize(source)));
+ }
+ return _results;
+ };
+
+ compilePath = function(source, topLevel, base) {
+ return fs.stat(source, function(err, stats) {
+ if (err && err.code !== 'ENOENT') {
+ throw err;
+ }
+ if ((err != null ? err.code : void 0) === 'ENOENT') {
+ if (topLevel && source.slice(-7) !== '.coffee') {
+ source = sources[sources.indexOf(source)] = "" + source + ".coffee";
+ return compilePath(source, topLevel, base);
+ }
+ if (topLevel) {
+ console.error("File not found: " + source);
+ process.exit(1);
+ }
+ return;
+ }
+ if (stats.isDirectory()) {
+ if (opts.watch) {
+ watchDir(source, base);
+ }
+ return fs.readdir(source, function(err, files) {
+ var file, index, _i, _len, _ref1, _ref2, _results;
+ if (err && err.code !== 'ENOENT') {
+ throw err;
+ }
+ if ((err != null ? err.code : void 0) === 'ENOENT') {
+ return;
+ }
+ index = sources.indexOf(source);
+ [].splice.apply(sources, [index, index - index + 1].concat(_ref1 = (function() {
+ var _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = files.length; _i < _len; _i++) {
+ file = files[_i];
+ _results.push(path.join(source, file));
+ }
+ return _results;
+ })())), _ref1;
+ [].splice.apply(sourceCode, [index, index - index + 1].concat(_ref2 = files.map(function() {
+ return null;
+ }))), _ref2;
+ _results = [];
+ for (_i = 0, _len = files.length; _i < _len; _i++) {
+ file = files[_i];
+ if (!hidden(file)) {
+ _results.push(compilePath(path.join(source, file), false, base));
+ }
+ }
+ return _results;
+ });
+ } else if (topLevel || path.extname(source) === '.coffee') {
+ if (opts.watch) {
+ watch(source, base);
+ }
+ return fs.readFile(source, function(err, code) {
+ if (err && err.code !== 'ENOENT') {
+ throw err;
+ }
+ if ((err != null ? err.code : void 0) === 'ENOENT') {
+ return;
+ }
+ return compileScript(source, code.toString(), base);
+ });
+ } else {
+ notSources[source] = true;
+ return removeSource(source, base);
+ }
+ });
+ };
+
+ compileScript = function(file, input, base) {
+ var o, options, t, task;
+ o = opts;
+ options = compileOptions(file);
+ try {
+ t = task = {
+ file: file,
+ input: input,
+ options: options
+ };
+ CoffeeScript.emit('compile', task);
+ if (o.tokens) {
+ return printTokens(CoffeeScript.tokens(t.input));
+ } else if (o.nodes) {
+ return printLine(CoffeeScript.nodes(t.input).toString().trim());
+ } else if (o.run) {
+ return CoffeeScript.run(t.input, t.options);
+ } else if (o.join && t.file !== o.join) {
+ sourceCode[sources.indexOf(t.file)] = t.input;
+ return compileJoin();
+ } else {
+ t.output = CoffeeScript.compile(t.input, t.options);
+ CoffeeScript.emit('success', task);
+ if (o.print) {
+ return printLine(t.output.trim());
+ } else if (o.compile) {
+ return writeJs(t.file, t.output, base);
+ } else if (o.lint) {
+ return lint(t.file, t.output);
+ }
+ }
+ } catch (err) {
+ CoffeeScript.emit('failure', err, task);
+ if (CoffeeScript.listeners('failure').length) {
+ return;
+ }
+ if (o.watch) {
+ return printLine(err.message + '\x07');
+ }
+ printWarn(err instanceof Error && err.stack || ("ERROR: " + err));
+ return process.exit(1);
+ }
+ };
+
+ compileStdio = function() {
+ var code, stdin;
+ code = '';
+ stdin = process.openStdin();
+ stdin.on('data', function(buffer) {
+ if (buffer) {
+ return code += buffer.toString();
+ }
+ });
+ return stdin.on('end', function() {
+ return compileScript(null, code);
+ });
+ };
+
+ joinTimeout = null;
+
+ compileJoin = function() {
+ if (!opts.join) {
+ return;
+ }
+ if (!sourceCode.some(function(code) {
+ return code === null;
+ })) {
+ clearTimeout(joinTimeout);
+ return joinTimeout = wait(100, function() {
+ return compileScript(opts.join, sourceCode.join('\n'), opts.join);
+ });
+ }
+ };
+
+ loadRequires = function() {
+ var realFilename, req, _i, _len, _ref1;
+ realFilename = module.filename;
+ module.filename = '.';
+ _ref1 = opts.require;
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ req = _ref1[_i];
+ require(req);
+ }
+ return module.filename = realFilename;
+ };
+
+ watch = function(source, base) {
+ var compile, compileTimeout, prevStats, rewatch, watchErr, watcher;
+ prevStats = null;
+ compileTimeout = null;
+ watchErr = function(e) {
+ if (e.code === 'ENOENT') {
+ if (sources.indexOf(source) === -1) {
+ return;
+ }
+ try {
+ rewatch();
+ return compile();
+ } catch (e) {
+ removeSource(source, base, true);
+ return compileJoin();
+ }
+ } else {
+ throw e;
+ }
+ };
+ compile = function() {
+ clearTimeout(compileTimeout);
+ return compileTimeout = wait(25, function() {
+ return fs.stat(source, function(err, stats) {
+ if (err) {
+ return watchErr(err);
+ }
+ if (prevStats && stats.size === prevStats.size && stats.mtime.getTime() === prevStats.mtime.getTime()) {
+ return rewatch();
+ }
+ prevStats = stats;
+ return fs.readFile(source, function(err, code) {
+ if (err) {
+ return watchErr(err);
+ }
+ compileScript(source, code.toString(), base);
+ return rewatch();
+ });
+ });
+ });
+ };
+ try {
+ watcher = fs.watch(source, compile);
+ } catch (e) {
+ watchErr(e);
+ }
+ return rewatch = function() {
+ if (watcher != null) {
+ watcher.close();
+ }
+ return watcher = fs.watch(source, compile);
+ };
+ };
+
+ watchDir = function(source, base) {
+ var readdirTimeout, watcher;
+ readdirTimeout = null;
+ try {
+ return watcher = fs.watch(source, function() {
+ clearTimeout(readdirTimeout);
+ return readdirTimeout = wait(25, function() {
+ return fs.readdir(source, function(err, files) {
+ var file, _i, _len, _results;
+ if (err) {
+ if (err.code !== 'ENOENT') {
+ throw err;
+ }
+ watcher.close();
+ return unwatchDir(source, base);
+ }
+ _results = [];
+ for (_i = 0, _len = files.length; _i < _len; _i++) {
+ file = files[_i];
+ if (!(!hidden(file) && !notSources[file])) {
+ continue;
+ }
+ file = path.join(source, file);
+ if (sources.some(function(s) {
+ return s.indexOf(file) >= 0;
+ })) {
+ continue;
+ }
+ sources.push(file);
+ sourceCode.push(null);
+ _results.push(compilePath(file, false, base));
+ }
+ return _results;
+ });
+ });
+ });
+ } catch (e) {
+ if (e.code !== 'ENOENT') {
+ throw e;
+ }
+ }
+ };
+
+ unwatchDir = function(source, base) {
+ var file, prevSources, toRemove, _i, _len;
+ prevSources = sources.slice(0);
+ toRemove = (function() {
+ var _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = sources.length; _i < _len; _i++) {
+ file = sources[_i];
+ if (file.indexOf(source) >= 0) {
+ _results.push(file);
+ }
+ }
+ return _results;
+ })();
+ for (_i = 0, _len = toRemove.length; _i < _len; _i++) {
+ file = toRemove[_i];
+ removeSource(file, base, true);
+ }
+ if (!sources.some(function(s, i) {
+ return prevSources[i] !== s;
+ })) {
+ return;
+ }
+ return compileJoin();
+ };
+
+ removeSource = function(source, base, removeJs) {
+ var index, jsPath;
+ index = sources.indexOf(source);
+ sources.splice(index, 1);
+ sourceCode.splice(index, 1);
+ if (removeJs && !opts.join) {
+ jsPath = outputPath(source, base);
+ return path.exists(jsPath, function(exists) {
+ if (exists) {
+ return fs.unlink(jsPath, function(err) {
+ if (err && err.code !== 'ENOENT') {
+ throw err;
+ }
+ return timeLog("removed " + source);
+ });
+ }
+ });
+ }
+ };
+
+ outputPath = function(source, base) {
+ var baseDir, dir, filename, srcDir;
+ filename = path.basename(source, path.extname(source)) + '.js';
+ srcDir = path.dirname(source);
+ baseDir = base === '.' ? srcDir : srcDir.substring(base.length);
+ dir = opts.output ? path.join(opts.output, baseDir) : srcDir;
+ return path.join(dir, filename);
+ };
+
+ writeJs = function(source, js, base) {
+ var compile, jsDir, jsPath;
+ jsPath = outputPath(source, base);
+ jsDir = path.dirname(jsPath);
+ compile = function() {
+ if (js.length <= 0) {
+ js = ' ';
+ }
+ return fs.writeFile(jsPath, js, function(err) {
+ if (err) {
+ return printLine(err.message);
+ } else if (opts.compile && opts.watch) {
+ return timeLog("compiled " + source);
+ }
+ });
+ };
+ return path.exists(jsDir, function(exists) {
+ if (exists) {
+ return compile();
+ } else {
+ return exec("mkdir -p " + jsDir, compile);
+ }
+ });
+ };
+
+ wait = function(milliseconds, func) {
+ return setTimeout(func, milliseconds);
+ };
+
+ timeLog = function(message) {
+ return console.log("" + ((new Date).toLocaleTimeString()) + " - " + message);
+ };
+
+ lint = function(file, js) {
+ var conf, jsl, printIt;
+ printIt = function(buffer) {
+ return printLine(file + ':\t' + buffer.toString().trim());
+ };
+ conf = __dirname + '/../../extras/jsl.conf';
+ jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]);
+ jsl.stdout.on('data', printIt);
+ jsl.stderr.on('data', printIt);
+ jsl.stdin.write(js);
+ return jsl.stdin.end();
+ };
+
+ printTokens = function(tokens) {
+ var strings, tag, token, value;
+ strings = (function() {
+ var _i, _len, _ref1, _results;
+ _results = [];
+ for (_i = 0, _len = tokens.length; _i < _len; _i++) {
+ token = tokens[_i];
+ _ref1 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref1[0], value = _ref1[1];
+ _results.push("[" + tag + " " + value + "]");
+ }
+ return _results;
+ })();
+ return printLine(strings.join(' '));
+ };
+
+ parseOptions = function() {
+ var i, o, source, _i, _len;
+ optionParser = new optparse.OptionParser(SWITCHES, BANNER);
+ o = opts = optionParser.parse(process.argv.slice(2));
+ o.compile || (o.compile = !!o.output);
+ o.run = !(o.compile || o.print || o.lint);
+ o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
+ sources = o["arguments"];
+ for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) {
+ source = sources[i];
+ sourceCode[i] = null;
+ }
+ };
+
+ compileOptions = function(filename) {
+ return {
+ filename: filename,
+ bare: opts.bare,
+ header: opts.compile
+ };
+ };
+
+ forkNode = function() {
+ var args, nodeArgs;
+ nodeArgs = opts.nodejs.split(/\s+/);
+ args = process.argv.slice(1);
+ args.splice(args.indexOf('--nodejs'), 2);
+ return spawn(process.execPath, nodeArgs.concat(args), {
+ cwd: process.cwd(),
+ env: process.env,
+ customFds: [0, 1, 2]
+ });
+ };
+
+ usage = function() {
+ return printLine((new optparse.OptionParser(SWITCHES, BANNER)).help());
+ };
+
+ version = function() {
+ return printLine("CoffeeScript version " + CoffeeScript.VERSION);
+ };
+
+}).call(this);
603 lib/coffee-script/grammar.js
View
@@ -0,0 +1,603 @@
+// Generated by CoffeeScript 1.3.1
+(function() {
+ var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
+
+ Parser = require('jison').Parser;
+
+ unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
+
+ o = function(patternString, action, options) {
+ var match;
+ patternString = patternString.replace(/\s{2,}/g, ' ');
+ if (!action) {
+ return [patternString, '$$ = $1;', options];
+ }
+ action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
+ action = action.replace(/\bnew /g, '$&yy.');
+ action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&');
+ return [patternString, "$$ = " + action + ";", options];
+ };
+
+ grammar = {
+ Root: [
+ o('', function() {
+ return new Block;
+ }), o('Body'), o('Block TERMINATOR')
+ ],
+ Body: [
+ o('Line', function() {
+ return Block.wrap([$1]);
+ }), o('Body TERMINATOR Line', function() {
+ return $1.push($3);
+ }), o('Body TERMINATOR')
+ ],
+ Line: [o('Expression'), o('Statement')],
+ Statement: [
+ o('Return'), o('Comment'), o('STATEMENT', function() {
+ return new Literal($1);
+ })
+ ],
+ 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')],
+ Block: [
+ o('INDENT OUTDENT', function() {
+ return new Block;
+ }), o('INDENT Body OUTDENT', function() {
+ return $2;
+ })
+ ],
+ Identifier: [
+ o('IDENTIFIER', function() {
+ return new Literal($1);
+ })
+ ],
+ AlphaNumeric: [
+ o('NUMBER', function() {
+ return new Literal($1);
+ }), o('STRING', function() {
+ return new Literal($1);
+ })
+ ],
+ Literal: [
+ o('AlphaNumeric'), o('JS', function() {
+ 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);
+ if ($1 === 'undefined') {
+ val.isUndefined = true;
+ }
+ return val;
+ })
+ ],
+ Assign: [
+ o('Assignable = Expression', function() {
+ return new Assign($1, $3);
+ }), o('Assignable = TERMINATOR Expression', function() {
+ return new Assign($1, $4);
+ }), o('Assignable = INDENT Expression OUTDENT', function() {
+ return new Assign($1, $4);
+ })
+ ],
+ AssignObj: [
+ o('ObjAssignable', function() {
+ return new Value($1);
+ }), o('ObjAssignable : Expression', function() {
+ return new Assign(new Value($1), $3, 'object');
+ }), o('ObjAssignable :\
+ INDENT Expression OUTDENT', function() {
+ return new Assign(new Value($1), $4, 'object');
+ }), o('Comment')
+ ],
+ ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')],
+ Return: [
+ o('RETURN Expression', function() {
+ return new Return($2);
+ }), o('RETURN', function() {
+ return new Return;
+ })
+ ],
+ Comment: [
+ o('HERECOMMENT', function() {
+ return new Comment($1);
+ })
+ ],
+ Code: [
+ o('PARAM_START ParamList PARAM_END FuncGlyph Block', function() {
+ return new Code($2, $5, $4);
+ }), o('FuncGlyph Block', function() {
+ return new Code([], $2, $1);
+ })
+ ],
+ FuncGlyph: [
+ o('->', function() {
+ return 'func';
+ }), o('=>', function() {
+ return 'boundfunc';
+ })
+ ],
+ OptComma: [o(''), o(',')],
+ ParamList: [
+ o('', function() {
+ return [];
+ }), o('Param', function() {
+ return [$1];
+ }), o('ParamList , Param', function() {
+ return $1.concat($3);
+ })
+ ],
+ Param: [
+ o('ParamVar', function() {
+ return new Param($1);
+ }), o('ParamVar ...', function() {
+ return new Param($1, null, true);
+ }), o('ParamVar = Expression', function() {
+ return new Param($1, $3);
+ })
+ ],
+ ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')],
+ Splat: [
+ o('Expression ...', function() {
+ return new Splat($1);
+ })
+ ],
+ SimpleAssignable: [
+ o('Identifier', function() {
+ return new Value($1);
+ }), o('Value Accessor', function() {
+ return $1.add($2);
+ }), o('Invocation Accessor', function() {
+ return new Value($1, [].concat($2));
+ }), o('ThisProperty')
+ ],
+ Assignable: [
+ o('SimpleAssignable'), o('Array', function() {
+ return new Value($1);
+ }), o('Object', function() {
+ return new Value($1);
+ })
+ ],
+ Value: [
+ o('Assignable'), o('Literal', function() {
+ return new Value($1);
+ }), o('Parenthetical', function() {
+ return new Value($1);
+ }), o('Range', function() {
+ return new Value($1);
+ }), o('This')
+ ],
+ Accessor: [
+ o('. Identifier', function() {
+ return new Access($2);
+ }), o('?. Identifier', function() {
+ return new Access($2, 'soak');
+ }), o(':: Identifier', function() {
+ return [new Access(new Literal('prototype')), new Access($2)];
+ }), o('::', function() {
+ return new Access(new Literal('prototype'));
+ }), o('Index')
+ ],
+ Index: [
+ o('INDEX_START IndexValue INDEX_END', function() {
+ return $2;
+ }), o('INDEX_SOAK Index', function() {
+ return extend($2, {
+ soak: true
+ });
+ })
+ ],
+ IndexValue: [
+ o('Expression', function() {
+ return new Index($1);
+ }), o('Slice', function() {
+ return new Slice($1);
+ })
+ ],
+ Object: [
+ o('{ AssignList OptComma }', function() {
+ return new Obj($2, $1.generated);
+ })
+ ],
+ AssignList: [
+ o('', function() {
+ return [];
+ }), o('AssignObj', function() {
+ return [$1];
+ }), o('AssignList , AssignObj', function() {
+ return $1.concat($3);
+ }), o('AssignList OptComma TERMINATOR AssignObj', function() {
+ return $1.concat($4);
+ }), o('AssignList OptComma INDENT AssignList OptComma OUTDENT', function() {
+ return $1.concat($4);
+ })
+ ],
+ Class: [
+ o('CLASS', function() {
+ return new Class;
+ }), o('CLASS Block', function() {
+ return new Class(null, null, $2);
+ }), o('CLASS EXTENDS Expression', function() {
+ return new Class(null, $3);
+ }), o('CLASS EXTENDS Expression Block', function() {
+ return new Class(null, $3, $4);
+ }), o('CLASS SimpleAssignable', function() {
+ return new Class($2);
+ }), o('CLASS SimpleAssignable Block', function() {
+ return new Class($2, null, $3);
+ }), o('CLASS SimpleAssignable EXTENDS Expression', function() {
+ return new Class($2, $4);
+ }), o('CLASS SimpleAssignable EXTENDS Expression Block', function() {
+ return new Class($2, $4, $5);
+ })
+ ],
+ Invocation: [
+ o('Value OptFuncExist Arguments', function() {
+ return new Call($1, $3, $2);
+ }), o('Invocation OptFuncExist Arguments', function() {
+ return new Call($1, $3, $2);
+ }), o('SUPER', function() {
+ return new Call('super', [new Splat(new Literal('arguments'))]);
+ }), o('SUPER Arguments', function() {
+ return new Call('super', $2);
+ })
+ ],
+ OptFuncExist: [
+ o('', function() {
+ return false;
+ }), o('FUNC_EXIST', function() {
+ return true;
+ })
+ ],
+ Arguments: [
+ o('CALL_START CALL_END', function() {
+ return [];
+ }), o('CALL_START ArgList OptComma CALL_END', function() {
+ return $2;
+ })
+ ],
+ This: [
+ o('THIS', function() {
+ return new Value(new Literal('this'));
+ }), o('@', function() {
+ return new Value(new Literal('this'));
+ })
+ ],
+ ThisProperty: [
+ o('@ Identifier', function() {
+ return new Value(new Literal('this'), [new Access($2)], 'this');
+ })
+ ],
+ Array: [
+ o('[ ]', function() {
+ return new Arr([]);
+ }), o('[ ArgList OptComma ]', function() {
+ return new Arr($2);
+ })
+ ],
+ RangeDots: [
+ o('..', function() {
+ return 'inclusive';
+ }), o('...', function() {
+ return 'exclusive';
+ })
+ ],
+ Range: [
+ o('[ Expression RangeDots Expression ]', function() {
+ return new Range($2, $4, $3);
+ })
+ ],
+ Slice: [
+ o('Expression RangeDots Expression', function() {
+ return new Range($1, $3, $2);
+ }), o('Expression RangeDots', function() {
+ return new Range($1, null, $2);
+ }), o('RangeDots Expression', function() {
+ return new Range(null, $2, $1);
+ }), o('RangeDots', function() {
+ return new Range(null, null, $1);
+ })
+ ],
+ ArgList: [
+ o('Arg', function() {
+ return [$1];
+ }), o('ArgList , Arg', function() {
+ return $1.concat($3);
+ }), o('ArgList OptComma TERMINATOR Arg', function() {
+ return $1.concat($4);
+ }), o('INDENT ArgList OptComma OUTDENT', function() {
+ return $2;
+ }), o('ArgList OptComma INDENT ArgList OptComma OUTDENT', function() {
+ return $1.concat($4);
+ })
+ ],
+ Arg: [o('Expression'), o('Splat')],
+ SimpleArgs: [
+ o('Expression'), o('SimpleArgs , Expression', function() {
+ return [].concat($1, $3);
+ })
+ ],
+ Try: [
+ o('TRY Block', function() {
+ return new Try($2);
+ }), o('TRY Block Catch', function() {
+ return new Try($2, $3[0], $3[1]);
+ }), o('TRY Block FINALLY Block', function() {
+ return new Try($2, null, null, $4);
+ }), o('TRY Block Catch FINALLY Block', function() {
+ return new Try($2, $3[0], $3[1], $5);
+ })
+ ],
+ Catch: [
+ o('CATCH Identifier Block', function() {
+ return [$2, $3];
+ })
+ ],
+ Throw: [
+ o('THROW Expression', function() {
+ return new Throw($2);
+ })
+ ],
+ Parenthetical: [
+ o('( Body )', function() {
+ return new Parens($2);
+ }), o('( INDENT Body OUTDENT )', function() {
+ return new Parens($3);
+ })
+ ],
+ WhileSource: [
+ o('WHILE Expression', function() {
+ return new While($2);
+ }), o('WHILE Expression WHEN Expression', function() {
+ return new While($2, {
+ guard: $4
+ });
+ }), o('UNTIL Expression', function() {
+ return new While($2, {
+ invert: true
+ });
+ }), o('UNTIL Expression WHEN Expression', function() {
+ return new While($2, {
+ invert: true,
+ guard: $4
+ });
+ })
+ ],
+ While: [
+ o('WhileSource Block', function() {
+ return $1.addBody($2);
+ }), o('Statement WhileSource', function() {
+ return $2.addBody(Block.wrap([$1]));
+ }), o('Expression WhileSource', function() {
+ return $2.addBody(Block.wrap([$1]));
+ }), o('Loop', function() {
+ return $1;
+ })
+ ],
+ Loop: [
+ o('LOOP Block', function() {
+ return new While(new Literal('true')).addBody($2);
+ }), o('LOOP Expression', function() {
+ return new While(new Literal('true')).addBody(Block.wrap([$2]));
+ })
+ ],
+ For: [
+ o('Statement ForBody', function() {
+ return new For($1, $2);
+ }), o('Expression ForBody', function() {
+ return new For($1, $2);
+ }), o('ForBody Block', function() {
+ return new For($2, $1);
+ })
+ ],
+ ForBody: [
+ o('FOR Range', function() {
+ return {
+ source: new Value($2)
+ };
+ }), o('ForStart ForSource', function() {
+ $2.own = $1.own;
+ $2.name = $1[0];
+ $2.index = $1[1];
+ return $2;
+ })
+ ],
+ ForStart: [
+ o('FOR ForVariables', function() {
+ return $2;
+ }), o('FOR OWN ForVariables', function() {
+ $3.own = true;
+ return $3;
+ })
+ ],
+ ForValue: [
+ o('Identifier'), o('Array', function() {
+ return new Value($1);
+ }), o('Object', function() {
+ return new Value($1);
+ })
+ ],
+ ForVariables: [
+ o('ForValue', function() {
+ return [$1];
+ }), o('ForValue , ForValue', function() {
+ return [$1, $3];
+ })
+ ],
+ ForSource: [
+ o('FORIN Expression', function() {
+ return {
+ source: $2
+ };
+ }), o('FOROF Expression', function() {
+ return {
+ source: $2,
+ object: true
+ };
+ }), o('FORIN Expression WHEN Expression', function() {
+ return {
+ source: $2,
+ guard: $4
+ };
+ }), o('FOROF Expression WHEN Expression', function() {
+ return {
+ source: $2,
+ guard: $4,
+ object: true
+ };
+ }), o('FORIN Expression BY Expression', function() {
+ return {
+ source: $2,
+ step: $4
+ };
+ }), o('FORIN Expression WHEN Expression BY Expression', function() {
+ return {
+ source: $2,
+ guard: $4,
+ step: $6
+ };
+ }), o('FORIN Expression BY Expression WHEN Expression', function() {
+ return {
+ source: $2,
+ step: $4,
+ guard: $6
+ };
+ })
+ ],
+ Switch: [
+ o('SWITCH Expression INDENT Whens OUTDENT', function() {
+ return new Switch($2, $4);
+ }), o('SWITCH Expression INDENT Whens ELSE Block OUTDENT', function() {
+ return new Switch($2, $4, $6);
+ }), o('SWITCH INDENT Whens OUTDENT', function() {
+ return new Switch(null, $3);
+ }), o('SWITCH INDENT Whens ELSE Block OUTDENT', function() {
+ return new Switch(null, $3, $5);
+ })
+ ],
+ Whens: [
+ o('When'), o('Whens When', function() {
+ return $1.concat($2);
+ })
+ ],
+ When: [
+ o('LEADING_WHEN SimpleArgs Block', function() {
+ return [[$2, $3]];
+ }), o('LEADING_WHEN SimpleArgs Block TERMINATOR', function() {
+ return [[$2, $3]];
+ })
+ ],
+ IfBlock: [
+ o('IF Expression Block', function() {
+ return new If($2, $3, {
+ type: $1
+ });
+ }), o('IfBlock ELSE IF Expression Block', function() {
+ return $1.addElse(new If($4, $5, {
+ type: $3
+ }));
+ })
+ ],
+ If: [
+ o('IfBlock'), o('IfBlock ELSE Block', function() {
+ return $1.addElse($3);
+ }), o('Statement POST_IF Expression', function() {
+ return new If($3, Block.wrap([$1]), {
+ type: $2,
+ statement: true
+ });
+ }), o('Expression POST_IF Expression', function() {
+ return new If($3, Block.wrap([$1]), {
+ type: $2,
+ statement: true
+ });
+ })
+ ],
+ Operation: [
+ o('UNARY Expression', function() {
+ return new Op($1, $2);
+ }), o('- Expression', (function() {
+ return new Op('-', $2);
+ }), {
+ prec: 'UNARY'
+ }), o('+ Expression', (function() {
+ return new Op('+', $2);
+ }), {
+ prec: 'UNARY'
+ }), o('-- SimpleAssignable', function() {
+ return new Op('--', $2);
+ }), o('++ SimpleAssignable', function() {
+ return new Op('++', $2);
+ }), o('SimpleAssignable --', function() {
+ return new Op('--', $1, null, true);
+ }), o('SimpleAssignable ++', function() {
+ return new Op('++', $1, null, true);
+ }), o('Expression ?', function() {
+ return new Existence($1);
+ }), o('Expression + Expression', function() {
+ return new Op('+', $1, $3);
+ }), o('Expression - Expression', function() {
+ return new Op('-', $1, $3);
+ }), o('Expression MATH Expression', function() {
+ return new Op($2, $1, $3);
+ }), o('Expression SHIFT Expression', function() {
+ return new Op($2, $1, $3);
+ }), o('Expression COMPARE Expression', function() {
+ return new Op($2, $1, $3);
+ }), o('Expression LOGIC Expression', function() {
+ return new Op($2, $1, $3);
+ }), o('Expression RELATION Expression', function() {
+ if ($2.charAt(0) === '!') {
+ return new Op($2.slice(1), $1, $3).invert();
+ } else {
+ return new Op($2, $1, $3);
+ }
+ }), o('SimpleAssignable COMPOUND_ASSIGN\
+ Expression', function() {
+ return new Assign($1, $3, $2);
+ }), o('SimpleAssignable COMPOUND_ASSIGN\
+ INDENT Expression OUTDENT', function() {
+ return new Assign($1, $4, $2);
+ }), o('SimpleAssignable EXTENDS Expression', function() {
+ return new Extends($1, $3);
+ })
+ ]
+ };
+
+ operators = [['left', '.', '?.', '::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']];
+
+ tokens = [];
+
+ for (name in grammar) {
+ alternatives = grammar[name];
+ grammar[name] = (function() {
+ var _i, _j, _len, _len1, _ref, _results;
+ _results = [];
+ for (_i = 0, _len = alternatives.length; _i < _len; _i++) {
+ alt = alternatives[_i];
+ _ref = alt[0].split(' ');
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
+ token = _ref[_j];
+ if (!grammar[token]) {
+ tokens.push(token);
+ }
+ }
+ if (name === 'Root') {
+ alt[1] = "return " + alt[1];
+ }
+ _results.push(alt);
+ }
+ return _results;
+ })();
+ }
+
+ exports.parser = new Parser({
+ tokens: tokens.join(' '),
+ bnf: grammar,
+ operators: operators.reverse(),
+ startSymbol: 'Root'
+ });
+
+}).call(this);
77 lib/coffee-script/helpers.js
View
@@ -0,0 +1,77 @@
+// Generated by CoffeeScript 1.3.1
+(function() {
+ var extend, flatten;
+
+ exports.starts = function(string, literal, start) {
+ return literal === string.substr(start, literal.length);
+ };
+
+ exports.ends = function(string, literal, back) {
+ var len;
+ len = literal.length;
+ return literal === string.substr(string.length - len - (back || 0), len);
+ };
+
+ exports.compact = function(array) {
+ var item, _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
+ item = array[_i];
+ if (item) {
+ _results.push(item);
+ }
+ }
+ return _results;
+ };
+
+ exports.count = function(string, substr) {
+ var num, pos;
+ num = pos = 0;
+ if (!substr.length) {
+ return 1 / 0;
+ }
+ while (pos = 1 + string.indexOf(substr, pos)) {
+ num++;
+ }
+ return num;
+ };
+
+ exports.merge = function(options, overrides) {
+ return extend(extend({}, options), overrides);
+ };
+
+ extend = exports.extend = function(object, properties) {
+ var key, val;
+ for (key in properties) {
+ val = properties[key];
+ object[key] = val;
+ }
+ return object;
+ };
+
+ exports.flatten = flatten = function(array) {
+ var element, flattened, _i, _len;
+ flattened = [];
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
+ element = array[_i];
+ if (element instanceof Array) {
+ flattened = flattened.concat(flatten(element));
+ } else {
+ flattened.push(element);
+ }
+ }
+ return flattened;
+ };
+
+ exports.del = function(obj, key) {
+ var val;
+ val = obj[key];
+ delete obj[key];
+ return val;
+ };
+
+ exports.last = function(array, back) {
+ return array[array.length - (back || 0) - 1];
+ };
+
+}).call(this);
11 lib/coffee-script/index.js
View
@@ -0,0 +1,11 @@
+// Generated by CoffeeScript 1.3.1
+(function() {
+ var key, val, _ref;
+
+ _ref = require('./coffee-script');
+ for (key in _ref) {
+ val = _ref[key];
+ exports[key] = val;
+ }
+
+}).call(this);
792 lib/coffee-script/lexer.js
View
@@ -0,0 +1,792 @@
+// Generated by CoffeeScript 1.3.1
+(function() {
+ var BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref, _ref1,
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+ _ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
+
+ _ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last;
+
+ exports.Lexer = Lexer = (function() {
+
+ Lexer.name = 'Lexer';
+
+ function Lexer() {}
+
+ Lexer.prototype.tokenize = function(code, opts) {
+ var i, tag;
+ if (opts == null) {
+ opts = {};
+ }
+ if (WHITESPACE.test(code)) {
+ code = "\n" + code;
+ }
+ code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
+ this.code = code;
+ this.line = opts.line || 0;
+ this.indent = 0;
+ this.indebt = 0;
+ this.outdebt = 0;
+ this.indents = [];
+ this.ends = [];
+ this.tokens = [];
+ i = 0;
+ while (this.chunk = code.slice(i)) {
+ i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
+ }
+ this.closeIndentation();
+ if (tag = this.ends.pop()) {
+ this.error("missing " + tag);
+ }
+ if (opts.rewrite === false) {
+ return this.tokens;
+ }
+ return (new Rewriter).rewrite(this.tokens);
+ };
+
+ Lexer.prototype.identifierToken = function() {
+ var colon, forcedIdentifier, id, input, match, prev, tag, _ref2, _ref3;
+ if (!(match = IDENTIFIER.exec(this.chunk))) {
+ return 0;
+ }
+ input = match[0], id = match[1], colon = match[2];
+ if (id === 'own' && this.tag() === 'FOR') {
+ this.token('OWN', id);
+ return id.length;
+ }
+ forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::') || !prev.spaced && prev[0] === '@');
+ tag = 'IDENTIFIER';
+ if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) {
+ tag = id.toUpperCase();
+ if (tag === 'WHEN' && (_ref3 = this.tag(), __indexOf.call(LINE_BREAK, _ref3) >= 0)) {
+ tag = 'LEADING_WHEN';
+ } else if (tag === 'FOR') {
+ this.seenFor = true;
+ } else if (tag === 'UNLESS') {
+ tag = 'IF';
+ } else if (__indexOf.call(UNARY, tag) >= 0) {
+ tag = 'UNARY';
+ } else if (__indexOf.call(RELATION, tag) >= 0) {
+ if (tag !== 'INSTANCEOF' && this.seenFor) {
+ tag = 'FOR' + tag;
+ this.seenFor = false;
+ } else {
+ tag = 'RELATION';
+ if (this.value() === '!') {
+ this.tokens.pop();
+ id = '!' + id;
+ }
+ }
+ }
+ }
+ if (__indexOf.call(JS_FORBIDDEN, id) >= 0) {
+ if (forcedIdentifier) {
+ tag = 'IDENTIFIER';
+ id = new String(id);
+ id.reserved = true;
+ } else if (__indexOf.call(RESERVED, id) >= 0) {
+ this.error("reserved word \"" + id + "\"");
+ }
+ }
+ if (!forcedIdentifier) {
+ if (__indexOf.call(COFFEE_ALIASES, id) >= 0) {
+ id = COFFEE_ALIAS_MAP[id];
+ }
+ tag = (function() {
+ switch (id) {
+ case '!':
+ return 'UNARY';
+ case '==':
+ case '!=':
+ return 'COMPARE';
+ case '&&':
+ case '||':
+ return 'LOGIC';
+ case 'true':
+ case 'false':
+ case 'null':
+ case 'undefined':
+ return 'BOOL';
+ case 'break':
+ case 'continue':
+ return 'STATEMENT';
+ default:
+ return tag;
+ }
+ })();
+ }
+ this.token(tag, id);
+ if (colon) {
+ this.token(':', ':');
+ }
+ return input.length;
+ };
+
+ Lexer.prototype.numberToken = function() {
+ var binaryLiteral, lexedLength, match, number, octalLiteral;
+ if (!(match = NUMBER.exec(this.chunk))) {
+ return 0;
+ }
+ number = match[0];
+ if (/^0[BOX]/.test(number)) {
+ this.error("radix prefix '" + number + "' must be lowercase");
+ } else if (/E/.test(number) && !/^0x/.test(number)) {
+ this.error("exponential notation '" + number + "' must be indicated with a lowercase 'e'");
+ } else if (/^0\d*[89]/.test(number)) {
+ this.error("decimal literal '" + number + "' must not be prefixed with '0'");
+ } else if (/^0\d+/.test(number)) {
+ this.error("octal literal '" + number + "' must be prefixed with '0o'");
+ }
+ lexedLength = number.length;
+ if (octalLiteral = /^0o([0-7]+)/.exec(number)) {
+ number = '0x' + (parseInt(octalLiteral[1], 8)).toString(16);
+ }
+ if (binaryLiteral = /^0b([01]+)/.exec(number)) {
+ number = '0x' + (parseInt(binaryLiteral[1], 2)).toString(16);
+ }
+ this.token('NUMBER', number);
+ return lexedLength;
+ };
+
+ Lexer.prototype.stringToken = function() {
+ var match, octalEsc, string;
+ switch (this.chunk.charAt(0)) {
+ case "'":
+ if (!(match = SIMPLESTR.exec(this.chunk))) {
+ return 0;
+ }
+ this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n'));
+ break;
+ case '"':
+ if (!(string = this.balancedString(this.chunk, '"'))) {
+ return 0;
+ }
+ if (0 < string.indexOf('#{', 1)) {
+ this.interpolateString(string.slice(1, -1));
+ } else {
+ this.token('STRING', this.escapeLines(string));
+ }
+ break;
+ default:
+ return 0;
+ }
+ if (octalEsc = /^(?:\\.|[^\\])*\\[0-7]/.test(string)) {
+ this.error("octal escape sequences " + string + " are not allowed");
+ }
+ this.line += count(string, '\n');
+ return string.length;
+ };
+
+ Lexer.prototype.heredocToken = function() {
+ var doc, heredoc, match, quote;
+ if (!(match = HEREDOC.exec(this.chunk))) {
+ return 0;
+ }
+ heredoc = match[0];
+ quote = heredoc.charAt(0);
+ doc = this.sanitizeHeredoc(match[2], {
+ quote: quote,
+ indent: null
+ });
+ if (quote === '"' && 0 <= doc.indexOf('#{')) {
+ this.interpolateString(doc, {
+ heredoc: true
+ });
+ } else {
+ this.token('STRING', this.makeString(doc, quote, true));
+ }
+ this.line += count(heredoc, '\n');
+ return heredoc.length;
+ };
+
+ Lexer.prototype.commentToken = function() {
+ var comment, here, match;
+ if (!(match = this.chunk.match(COMMENT))) {
+ return 0;
+ }
+ comment = match[0], here = match[1];
+ if (here) {
+ this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
+ herecomment: true,
+ indent: Array(this.indent + 1).join(' ')
+ }));
+ }
+ this.line += count(comment, '\n');
+ return comment.length;
+ };
+
+ Lexer.prototype.jsToken = function() {
+ var match, script;
+ if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {
+ return 0;
+ }
+ this.token('JS', (script = match[0]).slice(1, -1));
+ return script.length;
+ };
+
+ Lexer.prototype.regexToken = function() {
+ var flags, length, match, prev, regex, _ref2, _ref3;
+ if (this.chunk.charAt(0) !== '/') {
+ return 0;
+ }
+ if (match = HEREGEX.exec(this.chunk)) {
+ length = this.heregexToken(match);
+ this.line += count(match[0], '\n');
+ return length;
+ }
+ prev = last(this.tokens);
+ if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) {
+ return 0;
+ }
+ if (!(match = REGEX.exec(this.chunk))) {
+ return 0;
+ }
+ _ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2];
+ if (regex.slice(0, 2) === '/*') {
+ this.error('regular expressions cannot begin with `*`');
+ }
+ if (regex === '//') {
+ regex = '/(?:)/';
+ }
+ this.token('REGEX', "" + regex + flags);
+ return match.length;
+ };
+
+ Lexer.prototype.heregexToken = function(match) {
+ var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4, _ref5;
+ heregex = match[0], body = match[1], flags = match[2];
+ if (0 > body.indexOf('#{')) {
+ re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
+ if (re.match(/^\*/)) {
+ this.error('regular expressions cannot begin with `*`');
+ }
+ this.token('REGEX', "/" + (re || '(?:)') + "/" + flags);
+ return heregex.length;
+ }
+ this.token('IDENTIFIER', 'RegExp');
+ this.tokens.push(['CALL_START', '(']);
+ tokens = [];
+ _ref2 = this.interpolateString(body, {
+ regex: true
+ });
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ _ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1];
+ if (tag === 'TOKENS') {
+ tokens.push.apply(tokens, value);
+ } else {
+ if (!(value = value.replace(HEREGEX_OMIT, ''))) {
+ continue;
+ }
+ value = value.replace(/\\/g, '\\\\');
+ tokens.push(['STRING', this.makeString(value, '"', true)]);
+ }
+ tokens.push(['+', '+']);
+ }
+ tokens.pop();
+ if (((_ref4 = tokens[0]) != null ? _ref4[0] : void 0) !== 'STRING') {
+ this.tokens.push(['STRING', '""'], ['+', '+']);
+ }
+ (_ref5 = this.tokens).push.apply(_ref5, tokens);
+ if (flags) {
+ this.tokens.push([',', ','], ['STRING', '"' + flags + '"']);
+ }
+ this.token(')', ')');
+ return heregex.length;
+ };
+
+ Lexer.prototype.lineToken = function() {
+ var diff, indent, match, noNewlines, prev, size;
+ if (!(match = MULTI_DENT.exec(this.chunk))) {
+ return 0;
+ }
+ indent = match[0];
+ this.line += count(indent, '\n');
+ this.seenFor = false;
+ prev = last(this.tokens, 1);
+ size = indent.length - 1 - indent.lastIndexOf('\n');
+ noNewlines = this.unfinished();
+ if (size - this.indebt === this.indent) {
+ if (noNewlines) {
+ this.suppressNewlines();
+ } else {
+ this.newlineToken();
+ }
+ return indent.length;
+ }
+ if (size > this.indent) {
+ if (noNewlines) {
+ this.indebt = size - this.indent;
+ this.suppressNewlines();
+ return indent.length;
+ }
+ diff = size - this.indent + this.outdebt;
+ this.token('INDENT', diff);
+ this.indents.push(diff);
+ this.ends.push('OUTDENT');
+ this.outdebt = this.indebt = 0;
+ } else {
+ this.indebt = 0;
+ this.outdentToken(this.indent - size, noNewlines);
+ }
+ this.indent = size;
+ return indent.length;
+ };
+
+ Lexer.prototype.outdentToken = function(moveOut, noNewlines) {
+ var dent, len;
+ while (moveOut > 0) {
+ len = this.indents.length - 1;
+ if (this.indents[len] === void 0) {
+ moveOut = 0;
+ } else if (this.indents[len] === this.outdebt) {
+ moveOut -= this.outdebt;
+ this.outdebt = 0;
+ } else if (this.indents[len] < this.outdebt) {
+ this.outdebt -= this.indents[len];
+ moveOut -= this.indents[len];
+ } else {
+ dent = this.indents.pop() - this.outdebt;
+ moveOut -= dent;
+ this.outdebt = 0;
+ this.pair('OUTDENT');
+ this.token('OUTDENT', dent);
+ }
+ }
+ if (dent) {
+ this.outdebt -= moveOut;
+ }
+ while (this.value() === ';') {
+ this.tokens.pop();
+ }
+ if (!(this.tag() === 'TERMINATOR' || noNewlines)) {
+ this.token('TERMINATOR', '\n');
+ }
+ return this;
+ };
+
+ Lexer.prototype.whitespaceToken = function() {
+ var match, nline, prev;
+ if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) {
+ return 0;
+ }
+ prev = last(this.tokens);
+ if (prev) {
+ prev[match ? 'spaced' : 'newLine'] = true;
+ }
+ if (match) {
+ return match[0].length;
+ } else {
+ return 0;
+ }
+ };
+
+ Lexer.prototype.newlineToken = function() {
+ while (this.value() === ';') {
+ this.tokens.pop();
+ }
+ if (this.tag() !== 'TERMINATOR') {
+ this.token('TERMINATOR', '\n');
+ }
+ return this;
+ };
+
+ Lexer.prototype.suppressNewlines = function() {
+ if (this.value() === '\\') {
+ this.tokens.pop();
+ }
+ return this;
+ };
+
+ Lexer.prototype.literalToken = function() {
+ var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5;
+ if (match = OPERATOR.exec(this.chunk)) {
+ value = match[0];
+ if (CODE.test(value)) {
+ this.tagParameters();
+ }
+ } else {
+ value = this.chunk.charAt(0);
+ }
+ tag = value;
+ prev = last(this.tokens);
+ if (value === '=' && prev) {
+ if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) {
+ this.error("reserved word \"" + (this.value()) + "\" can't be assigned");
+ }
+ if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') {
+ prev[0] = 'COMPOUND_ASSIGN';
+ prev[1] += '=';
+ return value.length;
+ }
+ }
+ if (value === ';') {
+ this.seenFor = false;
+ tag = 'TERMINATOR';
+ } else if (__indexOf.call(MATH, value) >= 0) {
+ tag = 'MATH';
+ } else if (__indexOf.call(COMPARE, value) >= 0) {
+ tag = 'COMPARE';
+ } else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) {
+ tag = 'COMPOUND_ASSIGN';
+ } else if (__indexOf.call(UNARY, value) >= 0) {
+ tag = 'UNARY';
+ } else if (__indexOf.call(SHIFT, value) >= 0) {
+ tag = 'SHIFT';
+ } else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
+ tag = 'LOGIC';
+ } else if (prev && !prev.spaced) {
+ if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) {
+ if (prev[0] === '?') {
+ prev[0] = 'FUNC_EXIST';
+ }
+ tag = 'CALL_START';
+ } else if (value === '[' && (_ref5 = prev[0], __indexOf.call(INDEXABLE, _ref5) >= 0)) {
+ tag = 'INDEX_START';
+ switch (prev[0]) {
+ case '?':
+ prev[0] = 'INDEX_SOAK';
+ }
+ }
+ }
+ switch (value) {
+ case '(':
+ case '{':
+ case '[':
+ this.ends.push(INVERSES[value]);
+ break;
+ case ')':
+ case '}':
+ case ']':
+ this.pair(value);
+ }
+ this.token(tag, value);
+ return value.length;
+ };
+
+ Lexer.prototype.sanitizeHeredoc = function(doc, options) {
+ var attempt, herecomment, indent, match, _ref2;
+ indent = options.indent, herecomment = options.herecomment;
+ if (herecomment) {
+ if (HEREDOC_ILLEGAL.test(doc)) {
+ this.error("block comment cannot contain \"*/\", starting");
+ }
+ if (doc.indexOf('\n') <= 0) {
+ return doc;
+ }
+ } else {
+ while (match = HEREDOC_INDENT.exec(doc)) {
+ attempt = match[1];
+ if (indent === null || (0 < (_ref2 = attempt.length) && _ref2 < indent.length)) {
+ indent = attempt;
+ }
+ }
+ }
+ if (indent) {
+ doc = doc.replace(RegExp("\\n" + indent, "g"), '\n');
+ }
+ if (!herecomment) {
+ doc = doc.replace(/^\n/, '');
+ }
+ return doc;
+ };
+
+ Lexer.prototype.tagParameters = function() {
+ var i, stack, tok, tokens;
+ if (this.tag() !== ')') {
+ return this;
+ }
+ stack = [];
+ tokens = this.tokens;
+ i = tokens.length;
+ tokens[--i][0] = 'PARAM_END';
+ while (tok = tokens[--i]) {
+ switch (tok[0]) {
+ case ')':
+ stack.push(tok);
+ break;
+ case '(':
+ case 'CALL_START':
+ if (stack.length) {
+ stack.pop();
+ } else if (tok[0] === '(') {
+ tok[0] = 'PARAM_START';
+ return this;
+ } else {
+ return this;
+ }
+ }
+ }
+ return this;
+ };
+
+ Lexer.prototype.closeIndentation = function() {
+ return this.outdentToken(this.indent);
+ };
+
+ Lexer.prototype.balancedString = function(str, end) {
+ var continueCount, i, letter, match, prev, stack, _i, _ref2;
+ continueCount = 0;
+ stack = [end];
+ for (i = _i = 1, _ref2 = str.length; 1 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 1 <= _ref2 ? ++_i : --_i) {
+ if (continueCount) {
+ --continueCount;
+ continue;
+ }
+ switch (letter = str.charAt(i)) {
+ case '\\':
+ ++continueCount;
+ continue;
+ case end:
+ stack.pop();
+ if (!stack.length) {
+ return str.slice(0, i + 1 || 9e9);
+ }
+ end = stack[stack.length - 1];
+ continue;
+ }
+ if (end === '}' && (letter === '"' || letter === "'")) {
+ stack.push(end = letter);
+ } else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
+ continueCount += match[0].length - 1;
+ } else if (end === '}' && letter === '{') {
+ stack.push(end = '}');
+ } else if (end === '"' && prev === '#' && letter === '{') {
+ stack.push(end = '}');
+ }
+ prev = letter;
+ }
+ return this.error("missing " + (stack.pop()) + ", starting");
+ };
+
+ Lexer.prototype.interpolateString = function(str, options) {
+ var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4;
+ if (options == null) {
+ options = {};
+ }
+ heredoc = options.heredoc, regex = options.regex;
+ tokens = [];
+ pi = 0;
+ i = -1;
+ while (letter = str.charAt(i += 1)) {
+ if (letter === '\\') {
+ i += 1;
+ continue;
+ }
+ if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) {
+ continue;
+ }
+ if (pi < i) {
+ tokens.push(['NEOSTRING', str.slice(pi, i)]);
+ }
+ inner = expr.slice(1, -1);
+ if (inner.length) {
+ nested = new Lexer().tokenize(inner, {
+ line: this.line,
+ rewrite: false
+ });
+ nested.pop();
+ if (((_ref2 = nested[0]) != null ? _ref2[0] : void 0) === 'TERMINATOR') {
+ nested.shift();
+ }
+ if (len = nested.length) {
+ if (len > 1) {
+ nested.unshift(['(', '(', this.line]);
+ nested.push([')', ')', this.line]);
+ }
+ tokens.push(['TOKENS', nested]);
+ }
+ }
+ i += expr.length;
+ pi = i + 1;
+ }
+ if ((i > pi && pi < str.length)) {
+ tokens.push(['NEOSTRING', str.slice(pi)]);
+ }
+ if (regex) {
+ return tokens;
+ }
+ if (!tokens.length) {
+ return this.token('STRING', '""');
+ }
+ if (tokens[0][0] !== 'NEOSTRING') {
+ tokens.unshift(['', '']);
+ }
+ if (interpolated = tokens.length > 1) {
+ this.token('(', '(');
+ }
+ for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
+ _ref3 = tokens[i], tag = _ref3[0], value = _ref3[1];
+ if (i) {
+ this.token('+', '+');
+ }
+ if (tag === 'TOKENS') {
+ (_ref4 = this.tokens).push.apply(_ref4, value);
+ } else {
+ this.token('STRING', this.makeString(value, '"', heredoc));
+ }
+ }
+ if (interpolated) {
+ this.token(')', ')');
+ }
+ return tokens;
+ };
+
+ Lexer.prototype.pair = function(tag) {
+ var size, wanted;
+ if (tag !== (wanted = last(this.ends))) {
+ if ('OUTDENT' !== wanted) {
+ this.error("unmatched " + tag);
+ }
+ this.indent -= size = last(this.indents);
+ this.outdentToken(size, true);
+ return this.pair(tag);
+ }
+ return this.ends.pop();
+ };
+
+ Lexer.prototype.token = function(tag, value) {
+ return this.tokens.push([tag, value, this.line]);
+ };
+
+ Lexer.prototype.tag = function(index, tag) {
+ var tok;
+ return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]);
+ };
+
+ Lexer.prototype.value = function(index, val) {
+ var tok;
+ return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]);
+ };
+
+ Lexer.prototype.unfinished = function() {
+ var _ref2;
+ return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
+ };
+
+ Lexer.prototype.escapeLines = function(str, heredoc) {
+ return str.replace(MULTILINER, heredoc ? '\\n' : '');
+ };
+
+ Lexer.prototype.makeString = function(body, quote, heredoc) {
+ if (!body) {
+ return quote + quote;
+ }
+ body = body.replace(/\\([\s\S])/g, function(match, contents) {
+ if (contents === '\n' || contents === quote) {
+ return contents;
+ } else {
+ return match;
+ }
+ });
+ body = body.replace(RegExp("" + quote, "g"), '\\$&');
+ return quote + this.escapeLines(body, heredoc) + quote;
+ };
+
+ Lexer.prototype.error = function(message) {
+ throw SyntaxError("" + message + " on line " + (this.line + 1));
+ };
+
+ return Lexer;
+
+ })();
+
+ 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_ALIAS_MAP = {
+ and: '&&',
+ or: '||',
+ is: '==',
+ isnt: '!=',
+ not: '!',
+ yes: 'true',
+ no: 'false',
+ on: 'true',
+ off: 'false'
+ };
+
+ COFFEE_ALIASES = (function() {
+ var _results;
+ _results = [];
+ for (key in COFFEE_ALIAS_MAP) {
+ _results.push(key);
+ }
+ return _results;
+ })();
+
+ COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES);
+
+ RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', 'yield'];
+
+ STRICT_PROSCRIBED = ['arguments', 'eval'];
+
+ JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED);
+
+ exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED);
+
+ exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED;
+
+ IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/;
+
+ NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
+
+ HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/;
+
+ OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
+
+ WHITESPACE = /^[^\n\S]+/;
+
+ COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/;
+
+ CODE = /^[-=]>/;
+
+ MULTI_DENT = /^(?:\n[^\n\S]*)+/;
+
+ SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
+
+ JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
+
+ REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
+
+ HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/;
+
+ HEREGEX_OMIT = /\s+(?:#.*)?/g;
+
+ MULTILINER = /\n/g;
+
+ HEREDOC_INDENT = /\n+([^\n\S]*)/g;
+
+ HEREDOC_ILLEGAL = /\*\//;
+
+ LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/;
+
+ TRAILING_SPACES = /\s+$/;
+
+ COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
+
+ UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO'];
+
+ LOGIC = ['&&', '||', '&', '|', '^'];
+
+ SHIFT = ['<<', '>>', '>>>'];
+
+ COMPARE = ['==', '!=', '<', '>', '<=', '>='];
+
+ MATH = ['*', '/', '%'];
+
+ RELATION = ['IN', 'OF', 'INSTANCEOF'];
+
+ BOOL = ['TRUE', 'FALSE', 'NULL', 'UNDEFINED'];
+
+ NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', '++', '--', ']'];
+
+ NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING');
+
+ CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
+
+ INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL');
+
+ LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
+
+}).call(this);
2,972 lib/coffee-script/nodes.js
View
@@ -0,0 +1,2972 @@
+// Generated by CoffeeScript 1.3.1
+(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, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref, _ref1,
+ __hasProp = {}.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 = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+ Scope = require('./scope').Scope;
+
+ _ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED;
+
+ _ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last;
+
+ exports.extend = extend;
+
+ YES = function() {
+ return true;
+ };
+
+ NO = function() {
+ return false;
+ };
+
+ THIS = function() {
+ return this;
+ };
+
+ NEGATE = function() {
+ this.negated = !this.negated;
+ return this;
+ };
+
+ exports.Base = Base = (function() {
+
+ Base.name = 'Base';
+
+ function Base() {}
+
+ Base.prototype.compile = function(o, lvl) {
+ var node;
+ o = extend({}, o);
+ if (lvl) {
+ o.level = lvl;
+ }
+ node = this.unfoldSoak(o) || this;
+ node.tab = o.indent;
+ if (o.level === LEVEL_TOP || !node.isStatement(o)) {
+ return node.compileNode(o);
+ } else {