Sorry, the diff of this file is not supported yet
+22
-4
@@ -5,3 +5,3 @@ { | ||
| "description": "a node.js version of Rails' \"rake notes\" functionality", | ||
| "version": "0.0.1", | ||
| "version": "0.0.2", | ||
| "repository": { | ||
@@ -15,4 +15,22 @@ "type": "git", | ||
| }, | ||
| "dependencies": {}, | ||
| "devDependencies": {} | ||
| } | ||
| "contributors": [ | ||
| { "name": "Veselin Todorov", | ||
| "email": "hi@vesln.com" } | ||
| ], | ||
| "dependencies": { | ||
| "colors": "*" | ||
| }, | ||
| "devDependencies": { | ||
| "coffee-script": ">= 1.1.1" | ||
| }, | ||
| "bin": { | ||
| "notes": "./bin/notes" | ||
| }, | ||
| "keywords": [ | ||
| "notes", | ||
| "annotate", | ||
| "todo", | ||
| "fixme" | ||
| ], | ||
| "preferGlobal": "true" | ||
| } |
+4
-0
| node-notes is a node.js version of Rails' "rake notes" functionality. It allows you | ||
| to put comments in your code and then have them annotated across your whole project. | ||
| To install: | ||
| npm install notes | ||
| For example, if a file contained these lines somewhere in it: | ||
@@ -5,0 +9,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
| (function() { | ||
| var CoffeeScript, runScripts; | ||
| CoffeeScript = require('./coffee-script'); | ||
| CoffeeScript.require = require; | ||
| CoffeeScript.eval = function(code, options) { | ||
| 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); |
| (function() { | ||
| var CoffeeScript, 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() { | ||
| return path.exists('Cakefile', function(exists) { | ||
| var arg, args, _i, _len, _ref, _results; | ||
| if (!exists) { | ||
| throw new Error("Cakefile not found in " + (process.cwd())); | ||
| } | ||
| args = process.argv.slice(2); | ||
| CoffeeScript.run(fs.readFileSync('Cakefile').toString(), { | ||
| filename: 'Cakefile' | ||
| }); | ||
| oparse = new optparse.OptionParser(switches); | ||
| if (!args.length) { | ||
| return printTasks(); | ||
| } | ||
| options = oparse.parse(args); | ||
| _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 desc, name, spaces, task; | ||
| console.log(''); | ||
| 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()); | ||
| } | ||
| }; | ||
| missingTask = function(task) { | ||
| console.log("No such task: \"" + task + "\""); | ||
| return process.exit(1); | ||
| }; | ||
| }).call(this); |
| (function() { | ||
| var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref; | ||
| fs = require('fs'); | ||
| path = require('path'); | ||
| vm = require('vm'); | ||
| _ref = require('./lexer'), Lexer = _ref.Lexer, RESERVED = _ref.RESERVED; | ||
| parser = require('./parser').parser; | ||
| 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.1.1'; | ||
| exports.RESERVED = RESERVED; | ||
| exports.helpers = require('./helpers'); | ||
| exports.compile = compile = function(code, options) { | ||
| if (options == null) { | ||
| options = {}; | ||
| } | ||
| try { | ||
| return (parser.parse(lexer.tokenize(code))).compile(options); | ||
| } catch (err) { | ||
| if (options.filename) { | ||
| err.message = "In " + options.filename + ", " + err.message; | ||
| } | ||
| throw err; | ||
| } | ||
| }; | ||
| 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 Module, root; | ||
| root = module; | ||
| while (root.parent) { | ||
| root = root.parent; | ||
| } | ||
| root.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.'; | ||
| if (root.moduleCache) { | ||
| root.moduleCache = {}; | ||
| } | ||
| if (process.binding('natives').module) { | ||
| Module = require('module').Module; | ||
| root.paths = Module._nodeModulePaths(path.dirname(options.filename)); | ||
| } | ||
| if (path.extname(root.filename) !== '.coffee' || require.extensions) { | ||
| return root._compile(compile(code, options), root.filename); | ||
| } else { | ||
| return root._compile(code, root.filename); | ||
| } | ||
| }; | ||
| exports.eval = function(code, options) { | ||
| var g, js, sandbox; | ||
| if (options == null) { | ||
| options = {}; | ||
| } | ||
| sandbox = options.sandbox; | ||
| if (!sandbox) { | ||
| sandbox = { | ||
| require: require, | ||
| module: { | ||
| exports: {} | ||
| } | ||
| }; | ||
| for (g in global) { | ||
| sandbox[g] = global[g]; | ||
| } | ||
| sandbox.global = sandbox; | ||
| sandbox.global.global = sandbox.global.root = sandbox.global.GLOBAL = sandbox; | ||
| } | ||
| sandbox.__filename = options.filename || 'eval'; | ||
| sandbox.__dirname = path.dirname(sandbox.__filename); | ||
| js = compile("_=(" + (code.trim()) + ")", options); | ||
| return vm.runInNewContext(js, sandbox, sandbox.__filename); | ||
| }; | ||
| lexer = new Lexer; | ||
| parser.lexer = { | ||
| lex: function() { | ||
| var tag, _ref2; | ||
| _ref2 = this.tokens[this.pos++] || [''], tag = _ref2[0], this.yytext = _ref2[1], this.yylineno = _ref2[2]; | ||
| return tag; | ||
| }, | ||
| setInput: function(tokens) { | ||
| this.tokens = tokens; | ||
| return this.pos = 0; | ||
| }, | ||
| upcomingInput: function() { | ||
| return ""; | ||
| } | ||
| }; | ||
| parser.yy = require('./nodes'); | ||
| }).call(this); |
| (function() { | ||
| var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compileScript, compileScripts, compileStdio, contents, exec, forkNode, fs, helpers, lint, loadRequires, optionParser, optparse, opts, parseOptions, path, printLine, printTokens, printWarn, sources, spawn, usage, version, watch, 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.binding('stdio').writeError(line + '\n'); | ||
| }; | ||
| BANNER = 'Usage: coffee [options] path/to/script.coffee'; | ||
| SWITCHES = [['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-o', '--output [DIR]', 'set the directory for compiled JavaScript'], ['-j', '--join [FILE]', 'concatenate the scripts before compiling'], ['-w', '--watch', 'watch scripts for changes, and recompile'], ['-p', '--print', 'print the compiled JavaScript to stdout'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-e', '--eval', 'compile a string from the command line'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-b', '--bare', 'compile without the top-level function wrapper'], ['-t', '--tokens', 'print the tokens that the lexer produces'], ['-n', '--nodes', 'print the parse tree that Jison produces'], ['--nodejs [ARGS]', 'pass options through to the "node" binary'], ['-v', '--version', 'display CoffeeScript version'], ['-h', '--help', 'display this help message']]; | ||
| opts = {}; | ||
| sources = []; | ||
| contents = []; | ||
| optionParser = null; | ||
| exports.run = function() { | ||
| 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.stdio) { | ||
| return compileStdio(); | ||
| } | ||
| if (opts.eval) { | ||
| return compileScript(null, sources[0]); | ||
| } | ||
| if (!sources.length) { | ||
| return require('./repl'); | ||
| } | ||
| if (opts.run) { | ||
| opts.literals = sources.splice(1).concat(opts.literals); | ||
| } | ||
| process.ARGV = process.argv = process.argv.slice(0, 2).concat(opts.literals); | ||
| process.argv[0] = 'coffee'; | ||
| process.execPath = require.main.filename; | ||
| return compileScripts(); | ||
| }; | ||
| compileScripts = function() { | ||
| var base, compile, source, _i, _len, _results; | ||
| _results = []; | ||
| for (_i = 0, _len = sources.length; _i < _len; _i++) { | ||
| source = sources[_i]; | ||
| base = path.join(source); | ||
| compile = function(source, topLevel) { | ||
| return path.exists(source, function(exists) { | ||
| if (topLevel && !exists) { | ||
| throw new Error("File not found: " + source); | ||
| } | ||
| return fs.stat(source, function(err, stats) { | ||
| if (err) { | ||
| throw err; | ||
| } | ||
| if (stats.isDirectory()) { | ||
| return fs.readdir(source, function(err, files) { | ||
| var file, _j, _len2, _results2; | ||
| _results2 = []; | ||
| for (_j = 0, _len2 = files.length; _j < _len2; _j++) { | ||
| file = files[_j]; | ||
| _results2.push(compile(path.join(source, file))); | ||
| } | ||
| return _results2; | ||
| }); | ||
| } else if (topLevel || path.extname(source) === '.coffee') { | ||
| fs.readFile(source, function(err, code) { | ||
| if (opts.join) { | ||
| contents[sources.indexOf(source)] = code.toString(); | ||
| if (helpers.compact(contents).length > 0) { | ||
| return compileJoin(); | ||
| } | ||
| } else { | ||
| return compileScript(source, code.toString(), base); | ||
| } | ||
| }); | ||
| if (opts.watch && !opts.join) { | ||
| return watch(source, base); | ||
| } | ||
| } | ||
| }); | ||
| }); | ||
| }; | ||
| _results.push(compile(source, true)); | ||
| } | ||
| return _results; | ||
| }; | ||
| 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 { | ||
| 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); | ||
| } | ||
| printWarn(err.stack); | ||
| 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); | ||
| }); | ||
| }; | ||
| compileJoin = function() { | ||
| var code; | ||
| code = contents.join('\n'); | ||
| return compileScript(opts.join, code, opts.join); | ||
| }; | ||
| loadRequires = function() { | ||
| var realFilename, req, _i, _len, _ref2; | ||
| realFilename = module.filename; | ||
| module.filename = '.'; | ||
| _ref2 = opts.require; | ||
| for (_i = 0, _len = _ref2.length; _i < _len; _i++) { | ||
| req = _ref2[_i]; | ||
| require(req); | ||
| } | ||
| return module.filename = realFilename; | ||
| }; | ||
| watch = function(source, base) { | ||
| return fs.watchFile(source, { | ||
| persistent: true, | ||
| interval: 500 | ||
| }, function(curr, prev) { | ||
| if (curr.size === prev.size && curr.mtime.getTime() === prev.mtime.getTime()) { | ||
| return; | ||
| } | ||
| return fs.readFile(source, function(err, code) { | ||
| if (err) { | ||
| throw err; | ||
| } | ||
| return compileScript(source, code.toString(), base); | ||
| }); | ||
| }); | ||
| }; | ||
| writeJs = function(source, js, base) { | ||
| var baseDir, compile, dir, filename, jsPath, 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; | ||
| jsPath = path.join(dir, filename); | ||
| 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 console.log("" + ((new Date).toLocaleTimeString()) + " - compiled " + source); | ||
| } | ||
| }); | ||
| }; | ||
| return path.exists(dir, function(exists) { | ||
| if (exists) { | ||
| return compile(); | ||
| } else { | ||
| return exec("mkdir -p " + dir, compile); | ||
| } | ||
| }); | ||
| }; | ||
| 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, _ref2, _results; | ||
| _results = []; | ||
| for (_i = 0, _len = tokens.length; _i < _len; _i++) { | ||
| token = tokens[_i]; | ||
| _ref2 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref2[0], value = _ref2[1]; | ||
| _results.push("[" + tag + " " + value + "]"); | ||
| } | ||
| return _results; | ||
| })(); | ||
| return printLine(strings.join(' ')); | ||
| }; | ||
| parseOptions = function() { | ||
| var o; | ||
| 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)); | ||
| return sources = o.arguments; | ||
| }; | ||
| compileOptions = function(filename) { | ||
| return { | ||
| filename: filename, | ||
| bare: opts.bare | ||
| }; | ||
| }; | ||
| 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); |
| (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('Throw'), 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')], | ||
| 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('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 = 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.push($2); | ||
| }), o('Invocation Accessor', function() { | ||
| return new Value($1, [$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($2, 'proto'); | ||
| }), 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 | ||
| }); | ||
| }), o('INDEX_PROTO Index', function() { | ||
| return extend($2, { | ||
| proto: 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 Value', function() { | ||
| return new Class(null, $3); | ||
| }), o('CLASS EXTENDS Value 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 Value', function() { | ||
| return new Class($2, $4); | ||
| }), o('CLASS SimpleAssignable EXTENDS Value 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); | ||
| }) | ||
| ], | ||
| 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', 'DO', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']]; | ||
| tokens = []; | ||
| for (name in grammar) { | ||
| alternatives = grammar[name]; | ||
| grammar[name] = (function() { | ||
| var _i, _j, _len, _len2, _ref, _results; | ||
| _results = []; | ||
| for (_i = 0, _len = alternatives.length; _i < _len; _i++) { | ||
| alt = alternatives[_i]; | ||
| _ref = alt[0].split(' '); | ||
| for (_j = 0, _len2 = _ref.length; _j < _len2; _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); |
| (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); |
| (function() { | ||
| var key, val, _ref; | ||
| _ref = require('./coffee-script'); | ||
| for (key in _ref) { | ||
| val = _ref[key]; | ||
| exports[key] = val; | ||
| } | ||
| }).call(this); |
| (function() { | ||
| var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref; | ||
| var __indexOf = Array.prototype.indexOf || function(item) { | ||
| for (var i = 0, l = this.length; i < l; i++) { | ||
| if (this[i] === item) return i; | ||
| } | ||
| return -1; | ||
| }; | ||
| Rewriter = require('./rewriter').Rewriter; | ||
| _ref = require('./helpers'), count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last; | ||
| exports.Lexer = Lexer = (function() { | ||
| function Lexer() {} | ||
| Lexer.prototype.tokenize = function(code, opts) { | ||
| var i; | ||
| 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.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 (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 (__indexOf.call(JS_KEYWORDS, id) >= 0 || !forcedIdentifier && __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.identifierError(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': | ||
| case 'debugger': | ||
| return 'STATEMENT'; | ||
| default: | ||
| return tag; | ||
| } | ||
| })(); | ||
| } | ||
| this.token(tag, id); | ||
| if (colon) { | ||
| this.token(':', ':'); | ||
| } | ||
| return input.length; | ||
| }; | ||
| Lexer.prototype.numberToken = function() { | ||
| var match, number; | ||
| if (!(match = NUMBER.exec(this.chunk))) { | ||
| return 0; | ||
| } | ||
| number = match[0]; | ||
| this.token('NUMBER', number); | ||
| return number.length; | ||
| }; | ||
| Lexer.prototype.stringToken = function() { | ||
| var match, 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; | ||
| } | ||
| 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.token('TERMINATOR', '\n'); | ||
| } | ||
| 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 match, prev, regex, _ref2; | ||
| if (this.chunk.charAt(0) !== '/') { | ||
| return 0; | ||
| } | ||
| if (match = HEREGEX.exec(this.chunk)) { | ||
| return this.heregexToken(match); | ||
| } | ||
| 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; | ||
| } | ||
| regex = match[0]; | ||
| this.token('REGEX', regex === '//' ? '/(?:)/' : regex); | ||
| return regex.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, '\\/'); | ||
| 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'); | ||
| 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.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, close) { | ||
| 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.token('OUTDENT', dent); | ||
| } | ||
| } | ||
| if (dent) { | ||
| this.outdebt -= moveOut; | ||
| } | ||
| 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() { | ||
| 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.assignmentError(); | ||
| } | ||
| if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') { | ||
| prev[0] = 'COMPOUND_ASSIGN'; | ||
| prev[1] += '='; | ||
| return value.length; | ||
| } | ||
| } | ||
| if (value === ';') { | ||
| 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'; | ||
| break; | ||
| case '::': | ||
| prev[0] = 'INDEX_PROTO'; | ||
| } | ||
| } | ||
| } | ||
| 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)) { | ||
| throw new Error("block comment cannot contain \"*/\", starting on line " + (this.line + 1)); | ||
| } | ||
| 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; | ||
| } | ||
| } | ||
| } | ||
| return this; | ||
| }; | ||
| Lexer.prototype.closeIndentation = function() { | ||
| return this.outdentToken(this.indent); | ||
| }; | ||
| Lexer.prototype.identifierError = function(word) { | ||
| throw SyntaxError("Reserved word \"" + word + "\" on line " + (this.line + 1)); | ||
| }; | ||
| Lexer.prototype.assignmentError = function() { | ||
| throw SyntaxError("Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned"); | ||
| }; | ||
| Lexer.prototype.balancedString = function(str, end) { | ||
| var i, letter, prev, stack, _ref2; | ||
| stack = [end]; | ||
| for (i = 1, _ref2 = str.length; 1 <= _ref2 ? i < _ref2 : i > _ref2; 1 <= _ref2 ? i++ : i--) { | ||
| switch (letter = str.charAt(i)) { | ||
| case '\\': | ||
| i++; | ||
| continue; | ||
| case end: | ||
| stack.pop(); | ||
| if (!stack.length) { | ||
| return str.slice(0, i + 1); | ||
| } | ||
| end = stack[stack.length - 1]; | ||
| continue; | ||
| } | ||
| if (end === '}' && (letter === '"' || letter === "'")) { | ||
| stack.push(end = letter); | ||
| } else if (end === '}' && letter === '{') { | ||
| stack.push(end = '}'); | ||
| } else if (end === '"' && prev === '#' && letter === '{') { | ||
| stack.push(end = '}'); | ||
| } | ||
| prev = letter; | ||
| } | ||
| throw new Error("missing " + (stack.pop()) + ", starting on line " + (this.line + 1)); | ||
| }; | ||
| Lexer.prototype.interpolateString = function(str, options) { | ||
| var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _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(['(', '(']); | ||
| nested.push([')', ')']); | ||
| } | ||
| 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 = 0, _len = tokens.length; i < _len; 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.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 prev, value; | ||
| return LINE_CONTINUER.test(this.chunk) || (prev = last(this.tokens, 1)) && prev[0] !== '.' && (value = this.value()) && !value.reserved && NO_NEWLINE.test(value) && !CODE.test(value) && !ASSIGNED.test(this.chunk); | ||
| }; | ||
| 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; | ||
| }; | ||
| 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']; | ||
| JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED); | ||
| exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS); | ||
| IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/; | ||
| NUMBER = /^0x[\da-f]+|^(?:\d+(\.\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 = /\*\//; | ||
| ASSIGNED = /^\s*@?([$A-Za-z_][$\w\x7f-\uffff]*|['"].*['"])[^\n\S]*?[:=][^:=>]/; | ||
| LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/; | ||
| TRAILING_SPACES = /\s+$/; | ||
| NO_NEWLINE = /^(?:[-+*&|\/%=<>!.\\][<>=&|]*|and|or|is(?:nt)?|n(?:ot|ew)|delete|typeof|instanceof)$/; | ||
| 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); |
Sorry, the diff of this file is too big to display
| (function() { | ||
| var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments; | ||
| exports.OptionParser = OptionParser = (function() { | ||
| function OptionParser(rules, banner) { | ||
| this.banner = banner; | ||
| this.rules = buildRules(rules); | ||
| } | ||
| OptionParser.prototype.parse = function(args) { | ||
| var arg, i, isOption, matchedRule, options, rule, value, _i, _len, _len2, _ref; | ||
| options = { | ||
| arguments: [], | ||
| literals: [] | ||
| }; | ||
| args = normalizeArguments(args); | ||
| for (i = 0, _len = args.length; i < _len; i++) { | ||
| arg = args[i]; | ||
| if (arg === '--') { | ||
| options.literals = args.slice(i + 1); | ||
| break; | ||
| } | ||
| isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG)); | ||
| matchedRule = false; | ||
| _ref = this.rules; | ||
| for (_i = 0, _len2 = _ref.length; _i < _len2; _i++) { | ||
| rule = _ref[_i]; | ||
| if (rule.shortFlag === arg || rule.longFlag === arg) { | ||
| value = rule.hasArgument ? args[i += 1] : true; | ||
| options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value; | ||
| matchedRule = true; | ||
| break; | ||
| } | ||
| } | ||
| if (isOption && !matchedRule) { | ||
| throw new Error("unrecognized option: " + arg); | ||
| } | ||
| if (!isOption) { | ||
| options.arguments = args.slice(i); | ||
| break; | ||
| } | ||
| } | ||
| return options; | ||
| }; | ||
| OptionParser.prototype.help = function() { | ||
| var letPart, lines, rule, spaces, _i, _len, _ref; | ||
| lines = []; | ||
| if (this.banner) { | ||
| lines.unshift("" + this.banner + "\n"); | ||
| } | ||
| _ref = this.rules; | ||
| for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
| rule = _ref[_i]; | ||
| spaces = 15 - rule.longFlag.length; | ||
| spaces = spaces > 0 ? Array(spaces + 1).join(' ') : ''; | ||
| letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' '; | ||
| lines.push(' ' + letPart + rule.longFlag + spaces + rule.description); | ||
| } | ||
| return "\n" + (lines.join('\n')) + "\n"; | ||
| }; | ||
| return OptionParser; | ||
| })(); | ||
| LONG_FLAG = /^(--\w[\w\-]+)/; | ||
| SHORT_FLAG = /^(-\w)/; | ||
| MULTI_FLAG = /^-(\w{2,})/; | ||
| OPTIONAL = /\[(\w+(\*?))\]/; | ||
| buildRules = function(rules) { | ||
| var tuple, _i, _len, _results; | ||
| _results = []; | ||
| for (_i = 0, _len = rules.length; _i < _len; _i++) { | ||
| tuple = rules[_i]; | ||
| if (tuple.length < 3) { | ||
| tuple.unshift(null); | ||
| } | ||
| _results.push(buildRule.apply(null, tuple)); | ||
| } | ||
| return _results; | ||
| }; | ||
| buildRule = function(shortFlag, longFlag, description, options) { | ||
| var match; | ||
| if (options == null) { | ||
| options = {}; | ||
| } | ||
| match = longFlag.match(OPTIONAL); | ||
| longFlag = longFlag.match(LONG_FLAG)[1]; | ||
| return { | ||
| name: longFlag.substr(2), | ||
| shortFlag: shortFlag, | ||
| longFlag: longFlag, | ||
| description: description, | ||
| hasArgument: !!(match && match[1]), | ||
| isList: !!(match && match[2]) | ||
| }; | ||
| }; | ||
| normalizeArguments = function(args) { | ||
| var arg, l, match, result, _i, _j, _len, _len2, _ref; | ||
| args = args.slice(0); | ||
| result = []; | ||
| for (_i = 0, _len = args.length; _i < _len; _i++) { | ||
| arg = args[_i]; | ||
| if (match = arg.match(MULTI_FLAG)) { | ||
| _ref = match[1].split(''); | ||
| for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) { | ||
| l = _ref[_j]; | ||
| result.push('-' + l); | ||
| } | ||
| } else { | ||
| result.push(arg); | ||
| } | ||
| } | ||
| return result; | ||
| }; | ||
| }).call(this); |
Sorry, the diff of this file is too big to display
| (function() { | ||
| var ACCESSOR, CoffeeScript, SIMPLEVAR, Script, autocomplete, backlog, completeAttribute, completeVariable, enableColours, error, getCompletions, getPropertyNames, inspect, readline, repl, run, stdin, stdout; | ||
| var __hasProp = Object.prototype.hasOwnProperty; | ||
| CoffeeScript = require('./coffee-script'); | ||
| readline = require('readline'); | ||
| inspect = require('util').inspect; | ||
| Script = require('vm').Script; | ||
| enableColours = false; | ||
| if (process.platform !== 'win32') { | ||
| enableColours = !process.env.NODE_DISABLE_COLORS; | ||
| } | ||
| stdin = process.openStdin(); | ||
| stdout = process.stdout; | ||
| error = function(err) { | ||
| return stdout.write((err.stack || err.toString()) + '\n\n'); | ||
| }; | ||
| backlog = ''; | ||
| run = (function() { | ||
| var g, sandbox; | ||
| sandbox = { | ||
| require: require, | ||
| module: { | ||
| exports: {} | ||
| } | ||
| }; | ||
| for (g in global) { | ||
| sandbox[g] = global[g]; | ||
| } | ||
| sandbox.global = sandbox; | ||
| sandbox.global.global = sandbox.global.root = sandbox.global.GLOBAL = sandbox; | ||
| return function(buffer) { | ||
| var code, val; | ||
| code = backlog += '\n' + buffer.toString(); | ||
| if (code[code.length - 1] === '\\') { | ||
| return backlog = backlog.slice(0, backlog.length - 1); | ||
| } | ||
| backlog = ''; | ||
| try { | ||
| val = CoffeeScript.eval(code, { | ||
| sandbox: sandbox, | ||
| bare: true, | ||
| filename: 'repl' | ||
| }); | ||
| if (val !== void 0) { | ||
| process.stdout.write(inspect(val, false, 2, enableColours) + '\n'); | ||
| } | ||
| } catch (err) { | ||
| error(err); | ||
| } | ||
| return repl.prompt(); | ||
| }; | ||
| })(); | ||
| ACCESSOR = /\s*([\w\.]+)(?:\.(\w*))$/; | ||
| SIMPLEVAR = /\s*(\w*)$/i; | ||
| autocomplete = function(text) { | ||
| return completeAttribute(text) || completeVariable(text) || [[], text]; | ||
| }; | ||
| completeAttribute = function(text) { | ||
| var all, completions, match, obj, prefix, val; | ||
| if (match = text.match(ACCESSOR)) { | ||
| all = match[0], obj = match[1], prefix = match[2]; | ||
| try { | ||
| val = Script.runInThisContext(obj); | ||
| } catch (error) { | ||
| return [[], text]; | ||
| } | ||
| completions = getCompletions(prefix, getPropertyNames(val)); | ||
| return [completions, prefix]; | ||
| } | ||
| }; | ||
| completeVariable = function(text) { | ||
| var completions, free, scope, _ref; | ||
| if (free = (_ref = text.match(SIMPLEVAR)) != null ? _ref[1] : void 0) { | ||
| scope = Script.runInThisContext('this'); | ||
| completions = getCompletions(free, CoffeeScript.RESERVED.concat(getPropertyNames(scope))); | ||
| return [completions, free]; | ||
| } | ||
| }; | ||
| getCompletions = function(prefix, candidates) { | ||
| var el, _i, _len, _results; | ||
| _results = []; | ||
| for (_i = 0, _len = candidates.length; _i < _len; _i++) { | ||
| el = candidates[_i]; | ||
| if (el.indexOf(prefix) === 0) { | ||
| _results.push(el); | ||
| } | ||
| } | ||
| return _results; | ||
| }; | ||
| getPropertyNames = function(obj) { | ||
| var name, _results; | ||
| _results = []; | ||
| for (name in obj) { | ||
| if (!__hasProp.call(obj, name)) continue; | ||
| _results.push(name); | ||
| } | ||
| return _results; | ||
| }; | ||
| process.on('uncaughtException', error); | ||
| if (readline.createInterface.length < 3) { | ||
| repl = readline.createInterface(stdin, autocomplete); | ||
| stdin.on('data', function(buffer) { | ||
| return repl.write(buffer); | ||
| }); | ||
| } else { | ||
| repl = readline.createInterface(stdin, stdout, autocomplete); | ||
| } | ||
| repl.setPrompt('coffee> '); | ||
| repl.on('close', function() { | ||
| return stdin.destroy(); | ||
| }); | ||
| repl.on('line', run); | ||
| repl.prompt(); | ||
| }).call(this); |
| (function() { | ||
| var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref; | ||
| var __indexOf = Array.prototype.indexOf || function(item) { | ||
| for (var i = 0, l = this.length; i < l; i++) { | ||
| if (this[i] === item) return i; | ||
| } | ||
| return -1; | ||
| }, __slice = Array.prototype.slice; | ||
| exports.Rewriter = (function() { | ||
| function Rewriter() {} | ||
| Rewriter.prototype.rewrite = function(tokens) { | ||
| this.tokens = tokens; | ||
| this.removeLeadingNewlines(); | ||
| this.removeMidExpressionNewlines(); | ||
| this.closeOpenCalls(); | ||
| this.closeOpenIndexes(); | ||
| this.addImplicitIndentation(); | ||
| this.tagPostfixConditionals(); | ||
| this.addImplicitBraces(); | ||
| this.addImplicitParentheses(); | ||
| this.ensureBalance(BALANCED_PAIRS); | ||
| this.rewriteClosingParens(); | ||
| return this.tokens; | ||
| }; | ||
| Rewriter.prototype.scanTokens = function(block) { | ||
| var i, token, tokens; | ||
| tokens = this.tokens; | ||
| i = 0; | ||
| while (token = tokens[i]) { | ||
| i += block.call(this, token, i, tokens); | ||
| } | ||
| return true; | ||
| }; | ||
| Rewriter.prototype.detectEnd = function(i, condition, action) { | ||
| var levels, token, tokens, _ref, _ref2; | ||
| tokens = this.tokens; | ||
| levels = 0; | ||
| while (token = tokens[i]) { | ||
| if (levels === 0 && condition.call(this, token, i)) { | ||
| return action.call(this, token, i); | ||
| } | ||
| if (!token || levels < 0) { | ||
| return action.call(this, token, i - 1); | ||
| } | ||
| if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) { | ||
| levels += 1; | ||
| } else if (_ref2 = token[0], __indexOf.call(EXPRESSION_END, _ref2) >= 0) { | ||
| levels -= 1; | ||
| } | ||
| i += 1; | ||
| } | ||
| return i - 1; | ||
| }; | ||
| Rewriter.prototype.removeLeadingNewlines = function() { | ||
| var i, tag, _len, _ref; | ||
| _ref = this.tokens; | ||
| for (i = 0, _len = _ref.length; i < _len; i++) { | ||
| tag = _ref[i][0]; | ||
| if (tag !== 'TERMINATOR') { | ||
| break; | ||
| } | ||
| } | ||
| if (i) { | ||
| return this.tokens.splice(0, i); | ||
| } | ||
| }; | ||
| Rewriter.prototype.removeMidExpressionNewlines = function() { | ||
| return this.scanTokens(function(token, i, tokens) { | ||
| var _ref; | ||
| if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) { | ||
| return 1; | ||
| } | ||
| tokens.splice(i, 1); | ||
| return 0; | ||
| }); | ||
| }; | ||
| Rewriter.prototype.closeOpenCalls = function() { | ||
| var action, condition; | ||
| condition = function(token, i) { | ||
| var _ref; | ||
| return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')'; | ||
| }; | ||
| action = function(token, i) { | ||
| return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END'; | ||
| }; | ||
| return this.scanTokens(function(token, i) { | ||
| if (token[0] === 'CALL_START') { | ||
| this.detectEnd(i + 1, condition, action); | ||
| } | ||
| return 1; | ||
| }); | ||
| }; | ||
| Rewriter.prototype.closeOpenIndexes = function() { | ||
| var action, condition; | ||
| condition = function(token, i) { | ||
| var _ref; | ||
| return (_ref = token[0]) === ']' || _ref === 'INDEX_END'; | ||
| }; | ||
| action = function(token, i) { | ||
| return token[0] = 'INDEX_END'; | ||
| }; | ||
| return this.scanTokens(function(token, i) { | ||
| if (token[0] === 'INDEX_START') { | ||
| this.detectEnd(i + 1, condition, action); | ||
| } | ||
| return 1; | ||
| }); | ||
| }; | ||
| Rewriter.prototype.addImplicitBraces = function() { | ||
| var action, condition, stack, start, startIndent; | ||
| stack = []; | ||
| start = null; | ||
| startIndent = 0; | ||
| condition = function(token, i) { | ||
| var one, tag, three, two, _ref, _ref2; | ||
| _ref = this.tokens.slice(i + 1, (i + 3 + 1) || 9e9), one = _ref[0], two = _ref[1], three = _ref[2]; | ||
| if ('HERECOMMENT' === (one != null ? one[0] : void 0)) { | ||
| return false; | ||
| } | ||
| tag = token[0]; | ||
| return ((tag === 'TERMINATOR' || tag === 'OUTDENT') && !((two != null ? two[0] : void 0) === ':' || (one != null ? one[0] : void 0) === '@' && (three != null ? three[0] : void 0) === ':')) || (tag === ',' && one && ((_ref2 = one[0]) !== 'IDENTIFIER' && _ref2 !== 'NUMBER' && _ref2 !== 'STRING' && _ref2 !== '@' && _ref2 !== 'TERMINATOR' && _ref2 !== 'OUTDENT')); | ||
| }; | ||
| action = function(token, i) { | ||
| var tok; | ||
| tok = ['}', '}', token[2]]; | ||
| tok.generated = true; | ||
| return this.tokens.splice(i, 0, tok); | ||
| }; | ||
| return this.scanTokens(function(token, i, tokens) { | ||
| var ago, idx, tag, tok, value, _ref, _ref2; | ||
| if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) { | ||
| stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]); | ||
| return 1; | ||
| } | ||
| if (__indexOf.call(EXPRESSION_END, tag) >= 0) { | ||
| start = stack.pop(); | ||
| return 1; | ||
| } | ||
| if (!(tag === ':' && ((ago = this.tag(i - 2)) === ':' || ((_ref2 = stack[stack.length - 1]) != null ? _ref2[0] : void 0) !== '{'))) { | ||
| return 1; | ||
| } | ||
| stack.push(['{']); | ||
| idx = ago === '@' ? i - 2 : i - 1; | ||
| while (this.tag(idx - 2) === 'HERECOMMENT') { | ||
| idx -= 2; | ||
| } | ||
| value = new String('{'); | ||
| value.generated = true; | ||
| tok = ['{', value, token[2]]; | ||
| tok.generated = true; | ||
| tokens.splice(idx, 0, tok); | ||
| this.detectEnd(i + 2, condition, action); | ||
| return 2; | ||
| }); | ||
| }; | ||
| Rewriter.prototype.addImplicitParentheses = function() { | ||
| var action, noCall; | ||
| noCall = false; | ||
| action = function(token, i) { | ||
| var idx; | ||
| idx = token[0] === 'OUTDENT' ? i + 1 : i; | ||
| return this.tokens.splice(idx, 0, ['CALL_END', ')', token[2]]); | ||
| }; | ||
| return this.scanTokens(function(token, i, tokens) { | ||
| var callObject, current, next, prev, seenSingle, tag, _ref, _ref2, _ref3; | ||
| tag = token[0]; | ||
| if (tag === 'CLASS' || tag === 'IF') { | ||
| noCall = true; | ||
| } | ||
| _ref = tokens.slice(i - 1, (i + 1 + 1) || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2]; | ||
| callObject = !noCall && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0); | ||
| seenSingle = false; | ||
| if (__indexOf.call(LINEBREAKS, tag) >= 0) { | ||
| noCall = false; | ||
| } | ||
| if (prev && !prev.spaced && tag === '?') { | ||
| token.call = true; | ||
| } | ||
| if (token.fromThen) { | ||
| return 1; | ||
| } | ||
| if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref3 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref3) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0))) { | ||
| return 1; | ||
| } | ||
| tokens.splice(i, 0, ['CALL_START', '(', token[2]]); | ||
| this.detectEnd(i + 1, function(token, i) { | ||
| var post, _ref4; | ||
| tag = token[0]; | ||
| if (!seenSingle && token.fromThen) { | ||
| return true; | ||
| } | ||
| if (tag === 'IF' || tag === 'ELSE' || tag === '->' || tag === '=>') { | ||
| seenSingle = true; | ||
| } | ||
| if ((tag === '.' || tag === '?.' || tag === '::') && this.tag(i - 1) === 'OUTDENT') { | ||
| return true; | ||
| } | ||
| return !token.generated && this.tag(i - 1) !== ',' && __indexOf.call(IMPLICIT_END, tag) >= 0 && (tag !== 'INDENT' || (this.tag(i - 2) !== 'CLASS' && (_ref4 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref4) < 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{'))); | ||
| }, action); | ||
| if (prev[0] === '?') { | ||
| prev[0] = 'FUNC_EXIST'; | ||
| } | ||
| return 2; | ||
| }); | ||
| }; | ||
| Rewriter.prototype.addImplicitIndentation = function() { | ||
| return this.scanTokens(function(token, i, tokens) { | ||
| var action, condition, indent, outdent, starter, tag, _ref, _ref2; | ||
| tag = token[0]; | ||
| if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') { | ||
| tokens.splice(i, 1); | ||
| return 0; | ||
| } | ||
| if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') { | ||
| tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation(token)))); | ||
| return 2; | ||
| } | ||
| if (tag === 'CATCH' && ((_ref = this.tag(i + 2)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) { | ||
| tokens.splice.apply(tokens, [i + 2, 0].concat(__slice.call(this.indentation(token)))); | ||
| return 4; | ||
| } | ||
| if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) { | ||
| starter = tag; | ||
| _ref2 = this.indentation(token), indent = _ref2[0], outdent = _ref2[1]; | ||
| if (starter === 'THEN') { | ||
| indent.fromThen = true; | ||
| } | ||
| indent.generated = outdent.generated = true; | ||
| tokens.splice(i + 1, 0, indent); | ||
| condition = function(token, i) { | ||
| var _ref3; | ||
| return token[1] !== ';' && (_ref3 = token[0], __indexOf.call(SINGLE_CLOSERS, _ref3) >= 0) && !(token[0] === 'ELSE' && (starter !== 'IF' && starter !== 'THEN')); | ||
| }; | ||
| action = function(token, i) { | ||
| return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent); | ||
| }; | ||
| this.detectEnd(i + 2, condition, action); | ||
| if (tag === 'THEN') { | ||
| tokens.splice(i, 1); | ||
| } | ||
| return 1; | ||
| } | ||
| return 1; | ||
| }); | ||
| }; | ||
| Rewriter.prototype.tagPostfixConditionals = function() { | ||
| var condition; | ||
| condition = function(token, i) { | ||
| var _ref; | ||
| return (_ref = token[0]) === 'TERMINATOR' || _ref === 'INDENT'; | ||
| }; | ||
| return this.scanTokens(function(token, i) { | ||
| var original; | ||
| if (token[0] !== 'IF') { | ||
| return 1; | ||
| } | ||
| original = token; | ||
| this.detectEnd(i + 1, condition, function(token, i) { | ||
| if (token[0] !== 'INDENT') { | ||
| return original[0] = 'POST_' + original[0]; | ||
| } | ||
| }); | ||
| return 1; | ||
| }); | ||
| }; | ||
| Rewriter.prototype.ensureBalance = function(pairs) { | ||
| var close, level, levels, open, openLine, tag, token, _i, _j, _len, _len2, _ref, _ref2; | ||
| levels = {}; | ||
| openLine = {}; | ||
| _ref = this.tokens; | ||
| for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
| token = _ref[_i]; | ||
| tag = token[0]; | ||
| for (_j = 0, _len2 = pairs.length; _j < _len2; _j++) { | ||
| _ref2 = pairs[_j], open = _ref2[0], close = _ref2[1]; | ||
| levels[open] |= 0; | ||
| if (tag === open) { | ||
| if (levels[open]++ === 0) { | ||
| openLine[open] = token[2]; | ||
| } | ||
| } else if (tag === close && --levels[open] < 0) { | ||
| throw Error("too many " + token[1] + " on line " + (token[2] + 1)); | ||
| } | ||
| } | ||
| } | ||
| for (open in levels) { | ||
| level = levels[open]; | ||
| if (level > 0) { | ||
| throw Error("unclosed " + open + " on line " + (openLine[open] + 1)); | ||
| } | ||
| } | ||
| return this; | ||
| }; | ||
| Rewriter.prototype.rewriteClosingParens = function() { | ||
| var debt, key, stack; | ||
| stack = []; | ||
| debt = {}; | ||
| for (key in INVERSES) { | ||
| debt[key] = 0; | ||
| } | ||
| return this.scanTokens(function(token, i, tokens) { | ||
| var inv, match, mtag, oppos, tag, val, _ref; | ||
| if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) { | ||
| stack.push(token); | ||
| return 1; | ||
| } | ||
| if (__indexOf.call(EXPRESSION_END, tag) < 0) { | ||
| return 1; | ||
| } | ||
| if (debt[inv = INVERSES[tag]] > 0) { | ||
| debt[inv] -= 1; | ||
| tokens.splice(i, 1); | ||
| return 0; | ||
| } | ||
| match = stack.pop(); | ||
| mtag = match[0]; | ||
| oppos = INVERSES[mtag]; | ||
| if (tag === oppos) { | ||
| return 1; | ||
| } | ||
| debt[mtag] += 1; | ||
| val = [oppos, mtag === 'INDENT' ? match[1] : oppos]; | ||
| if (this.tag(i + 2) === mtag) { | ||
| tokens.splice(i + 3, 0, val); | ||
| stack.push(match); | ||
| } else { | ||
| tokens.splice(i, 0, val); | ||
| } | ||
| return 1; | ||
| }); | ||
| }; | ||
| Rewriter.prototype.indentation = function(token) { | ||
| return [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]]; | ||
| }; | ||
| Rewriter.prototype.tag = function(i) { | ||
| var _ref; | ||
| return (_ref = this.tokens[i]) != null ? _ref[0] : void 0; | ||
| }; | ||
| return Rewriter; | ||
| })(); | ||
| BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']]; | ||
| INVERSES = {}; | ||
| EXPRESSION_START = []; | ||
| EXPRESSION_END = []; | ||
| for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) { | ||
| _ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1]; | ||
| EXPRESSION_START.push(INVERSES[rite] = left); | ||
| EXPRESSION_END.push(INVERSES[left] = rite); | ||
| } | ||
| 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', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', 'SUPER', '@', '->', '=>', '[', '(', '{', '--', '++']; | ||
| IMPLICIT_UNSPACED_CALL = ['+', '-']; | ||
| IMPLICIT_BLOCK = ['->', '=>', '{', '[', ',']; | ||
| IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR', 'INDENT']; | ||
| SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN']; | ||
| SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN']; | ||
| LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT']; | ||
| }).call(this); |
| (function() { | ||
| var Scope, extend, last, _ref; | ||
| _ref = require('./helpers'), extend = _ref.extend, last = _ref.last; | ||
| exports.Scope = Scope = (function() { | ||
| Scope.root = null; | ||
| function Scope(parent, expressions, method) { | ||
| this.parent = parent; | ||
| this.expressions = expressions; | ||
| this.method = method; | ||
| this.variables = [ | ||
| { | ||
| name: 'arguments', | ||
| type: 'arguments' | ||
| } | ||
| ]; | ||
| this.positions = {}; | ||
| if (!this.parent) { | ||
| Scope.root = this; | ||
| } | ||
| } | ||
| Scope.prototype.add = function(name, type, immediate) { | ||
| var pos; | ||
| if (this.shared && !immediate) { | ||
| return this.parent.add(name, type, immediate); | ||
| } | ||
| if (typeof (pos = this.positions[name]) === 'number') { | ||
| return this.variables[pos].type = type; | ||
| } else { | ||
| return this.positions[name] = this.variables.push({ | ||
| name: name, | ||
| type: type | ||
| }) - 1; | ||
| } | ||
| }; | ||
| Scope.prototype.find = function(name, options) { | ||
| if (this.check(name, options)) { | ||
| return true; | ||
| } | ||
| this.add(name, 'var'); | ||
| return false; | ||
| }; | ||
| Scope.prototype.parameter = function(name) { | ||
| if (this.shared && this.parent.check(name, true)) { | ||
| return; | ||
| } | ||
| return this.add(name, 'param'); | ||
| }; | ||
| Scope.prototype.check = function(name, immediate) { | ||
| var found, _ref2; | ||
| found = !!this.type(name); | ||
| if (found || immediate) { | ||
| return found; | ||
| } | ||
| return !!((_ref2 = this.parent) != null ? _ref2.check(name) : void 0); | ||
| }; | ||
| Scope.prototype.temporary = function(name, index) { | ||
| if (name.length > 1) { | ||
| return '_' + name + (index > 1 ? index : ''); | ||
| } else { | ||
| return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a'); | ||
| } | ||
| }; | ||
| Scope.prototype.type = function(name) { | ||
| var v, _i, _len, _ref2; | ||
| _ref2 = this.variables; | ||
| for (_i = 0, _len = _ref2.length; _i < _len; _i++) { | ||
| v = _ref2[_i]; | ||
| if (v.name === name) { | ||
| return v.type; | ||
| } | ||
| } | ||
| return null; | ||
| }; | ||
| Scope.prototype.freeVariable = function(type) { | ||
| var index, temp; | ||
| index = 0; | ||
| while (this.check((temp = this.temporary(type, index)))) { | ||
| index++; | ||
| } | ||
| this.add(temp, 'var', true); | ||
| return temp; | ||
| }; | ||
| Scope.prototype.assign = function(name, value) { | ||
| this.add(name, { | ||
| value: value, | ||
| assigned: true | ||
| }); | ||
| return this.hasAssignments = true; | ||
| }; | ||
| Scope.prototype.hasDeclarations = function() { | ||
| return !!this.declaredVariables().length; | ||
| }; | ||
| Scope.prototype.declaredVariables = function() { | ||
| var realVars, tempVars, v, _i, _len, _ref2; | ||
| realVars = []; | ||
| tempVars = []; | ||
| _ref2 = this.variables; | ||
| for (_i = 0, _len = _ref2.length; _i < _len; _i++) { | ||
| v = _ref2[_i]; | ||
| if (v.type === 'var') { | ||
| (v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name); | ||
| } | ||
| } | ||
| return realVars.sort().concat(tempVars.sort()); | ||
| }; | ||
| Scope.prototype.assignedVariables = function() { | ||
| var v, _i, _len, _ref2, _results; | ||
| _ref2 = this.variables; | ||
| _results = []; | ||
| for (_i = 0, _len = _ref2.length; _i < _len; _i++) { | ||
| v = _ref2[_i]; | ||
| if (v.type.assigned) { | ||
| _results.push("" + v.name + " = " + v.type.value); | ||
| } | ||
| } | ||
| return _results; | ||
| }; | ||
| return Scope; | ||
| })(); | ||
| }).call(this); |
| Copyright (c) 2011 Jeremy Ashkenas | ||
| Permission is hereby granted, free of charge, to any person | ||
| obtaining a copy of this software and associated documentation | ||
| files (the "Software"), to deal in the Software without | ||
| restriction, including without limitation the rights to use, | ||
| copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the | ||
| Software is furnished to do so, subject to the following | ||
| conditions: | ||
| The above copyright notice and this permission notice shall be | ||
| included in all copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
| OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
| WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| OTHER DEALINGS IN THE SOFTWARE. |
| { | ||
| "name": "coffee-script", | ||
| "description": "Unfancy JavaScript", | ||
| "keywords": ["javascript", "language", "coffeescript", "compiler"], | ||
| "author": "Jeremy Ashkenas", | ||
| "version": "1.1.1", | ||
| "licenses": [{ | ||
| "type": "MIT", | ||
| "url": "http://github.com/jashkenas/coffee-script/raw/master/LICENSE" | ||
| }], | ||
| "engines": { | ||
| "node": ">=0.2.5" | ||
| }, | ||
| "directories" : { | ||
| "lib" : "./lib" | ||
| }, | ||
| "main" : "./lib/coffee-script", | ||
| "bin": { | ||
| "coffee": "./bin/coffee", | ||
| "cake": "./bin/cake" | ||
| }, | ||
| "homepage": "http://coffeescript.org", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git://github.com/jashkenas/coffee-script.git" | ||
| } | ||
| } |
| require 'rubygems' | ||
| require 'erb' | ||
| require 'fileutils' | ||
| require 'rake/testtask' | ||
| require 'json' | ||
| desc "Build the documentation page" | ||
| task :doc do | ||
| source = 'documentation/index.html.erb' | ||
| child = fork { exec "bin/coffee -bcw -o documentation/js documentation/coffee/*.coffee" } | ||
| at_exit { Process.kill("INT", child) } | ||
| Signal.trap("INT") { exit } | ||
| loop do | ||
| mtime = File.stat(source).mtime | ||
| if !@mtime || mtime > @mtime | ||
| rendered = ERB.new(File.read(source)).result(binding) | ||
| File.open('index.html', 'w+') {|f| f.write(rendered) } | ||
| end | ||
| @mtime = mtime | ||
| sleep 1 | ||
| end | ||
| end | ||
| desc "Build coffee-script-source gem" | ||
| task :gem do | ||
| require 'rubygems' | ||
| require 'rubygems/package' | ||
| gemspec = Gem::Specification.new do |s| | ||
| s.name = 'coffee-script-source' | ||
| s.version = JSON.parse(File.read('package.json'))["version"] | ||
| s.date = Time.now.strftime("%Y-%m-%d") | ||
| s.homepage = "http://jashkenas.github.com/coffee-script/" | ||
| s.summary = "The CoffeeScript Compiler" | ||
| s.description = <<-EOS | ||
| CoffeeScript is a little language that compiles into JavaScript. | ||
| Underneath all of those embarrassing braces and semicolons, | ||
| JavaScript has always had a gorgeous object model at its heart. | ||
| CoffeeScript is an attempt to expose the good parts of JavaScript | ||
| in a simple way. | ||
| EOS | ||
| s.files = [ | ||
| 'lib/coffee_script/coffee-script.js', | ||
| 'lib/coffee_script/source.rb' | ||
| ] | ||
| s.authors = ['Jeremy Ashkenas'] | ||
| s.email = 'jashkenas@gmail.com' | ||
| s.rubyforge_project = 'coffee-script-source' | ||
| end | ||
| file = File.open("coffee-script-source.gem", "w") | ||
| Gem::Package.open(file, 'w') do |pkg| | ||
| pkg.metadata = gemspec.to_yaml | ||
| path = "lib/coffee_script/source.rb" | ||
| contents = <<-ERUBY | ||
| module CoffeeScript | ||
| module Source | ||
| def self.bundled_path | ||
| File.expand_path("../coffee-script.js", __FILE__) | ||
| end | ||
| end | ||
| end | ||
| ERUBY | ||
| pkg.add_file_simple(path, 0644, contents.size) do |tar_io| | ||
| tar_io.write(contents) | ||
| end | ||
| contents = File.read("extras/coffee-script.js") | ||
| path = "lib/coffee_script/coffee-script.js" | ||
| pkg.add_file_simple(path, 0644, contents.size) do |tar_io| | ||
| tar_io.write(contents) | ||
| end | ||
| end | ||
| end |
| = | ||
| { | ||
| } } { | ||
| { { } } | ||
| } }{ { | ||
| { }{ } } _____ __ __ | ||
| ( }{ }{ { ) / ____| / _|/ _| | ||
| .- { { } { }} -. | | ___ | |_| |_ ___ ___ | ||
| ( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \ | ||
| |`-..________ ..-'| | |___| (_) | | | || __/ __/ | ||
| | | \_____\___/|_| |_| \___|\___| | ||
| | ;--. | ||
| | (__ \ _____ _ _ | ||
| | | ) ) / ____| (_) | | | ||
| | |/ / | (___ ___ _ __ _ _ __ | |_ | ||
| | ( / \___ \ / __| '__| | '_ \| __| | ||
| | |/ ____) | (__| | | | |_) | |_ | ||
| | | |_____/ \___|_| |_| .__/ \__| | ||
| `-.._________..-' | | | ||
| |_| | ||
| CoffeeScript is a little language that compiles into JavaScript. | ||
| Install Node.js, and then the CoffeeScript compiler: | ||
| sudo bin/cake install | ||
| Or, if you have the Node Package Manager installed: | ||
| npm install -g coffee-script | ||
| (Leave off the -g if you don't wish to install globally.) | ||
| Compile a script: | ||
| coffee /path/to/script.coffee | ||
| For documentation, usage, and examples, see: | ||
| http://coffeescript.org/ | ||
| To suggest a feature, report a bug, or general discussion: | ||
| http://github.com/jashkenas/coffee-script/issues/ | ||
| If you'd like to chat, drop by #coffeescript on Freenode IRC, | ||
| or on webchat.freenode.net. | ||
| The source repository: | ||
| git://github.com/jashkenas/coffee-script.git | ||
| All contributors are listed here: | ||
| http://github.com/jashkenas/coffee-script/contributors |
| /* | ||
| colors.js | ||
| Copyright (c) 2010 Alexis Sellier (cloudhead) , Marak Squires | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in | ||
| all copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| THE SOFTWARE. | ||
| */ | ||
| // prototypes the string object to have additional method calls that add terminal colors | ||
| var isHeadless = (typeof module !== 'undefined'); | ||
| ['bold', 'underline', 'italic', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta'].forEach(function (style) { | ||
| // __defineGetter__ at the least works in more browsers | ||
| // http://robertnyman.com/javascript/javascript-getters-setters.html | ||
| // Object.defineProperty only works in Chrome | ||
| String.prototype.__defineGetter__(style, function () { | ||
| return isHeadless ? | ||
| stylize(this, style) : // for those running in node (headless environments) | ||
| this.replace(/( )/, '$1'); // and for those running in browsers: | ||
| // re: ^ you'd think 'return this' works (but doesn't) so replace coerces the string to be a real string | ||
| }); | ||
| }); | ||
| // prototypes string with method "rainbow" | ||
| // rainbow will apply a the color spectrum to a string, changing colors every letter | ||
| String.prototype.__defineGetter__('rainbow', function () { | ||
| if (!isHeadless) { | ||
| return this.replace(/( )/, '$1'); | ||
| } | ||
| var rainbowcolors = ['red','yellow','green','blue','magenta']; //RoY G BiV | ||
| var exploded = this.split(""); | ||
| var i=0; | ||
| exploded = exploded.map(function(letter) { | ||
| if (letter==" ") { | ||
| return letter; | ||
| } | ||
| else { | ||
| return stylize(letter,rainbowcolors[i++ % rainbowcolors.length]); | ||
| } | ||
| }); | ||
| return exploded.join(""); | ||
| }); | ||
| function stylize(str, style) { | ||
| var styles = { | ||
| //styles | ||
| 'bold' : [1, 22], | ||
| 'italic' : [3, 23], | ||
| 'underline' : [4, 24], | ||
| 'inverse' : [7, 27], | ||
| //grayscale | ||
| 'white' : [37, 39], | ||
| 'grey' : [90, 39], | ||
| 'black' : [90, 39], | ||
| //colors | ||
| 'blue' : [34, 39], | ||
| 'cyan' : [36, 39], | ||
| 'green' : [32, 39], | ||
| 'magenta' : [35, 39], | ||
| 'red' : [31, 39], | ||
| 'yellow' : [33, 39] | ||
| }; | ||
| return '\033[' + styles[style][0] + 'm' + str + | ||
| '\033[' + styles[style][1] + 'm'; | ||
| }; | ||
| // don't summon zalgo | ||
| String.prototype.__defineGetter__('zalgo', function () { | ||
| return zalgo(this); | ||
| }); | ||
| // please no | ||
| function zalgo(text, options) { | ||
| var soul = { | ||
| "up" : [ | ||
| '̍','̎','̄','̅', | ||
| '̿','̑','̆','̐', | ||
| '͒','͗','͑','̇', | ||
| '̈','̊','͂','̓', | ||
| '̈','͊','͋','͌', | ||
| '̃','̂','̌','͐', | ||
| '̀','́','̋','̏', | ||
| '̒','̓','̔','̽', | ||
| '̉','ͣ','ͤ','ͥ', | ||
| 'ͦ','ͧ','ͨ','ͩ', | ||
| 'ͪ','ͫ','ͬ','ͭ', | ||
| 'ͮ','ͯ','̾','͛', | ||
| '͆','̚' | ||
| ], | ||
| "down" : [ | ||
| '̖','̗','̘','̙', | ||
| '̜','̝','̞','̟', | ||
| '̠','̤','̥','̦', | ||
| '̩','̪','̫','̬', | ||
| '̭','̮','̯','̰', | ||
| '̱','̲','̳','̹', | ||
| '̺','̻','̼','ͅ', | ||
| '͇','͈','͉','͍', | ||
| '͎','͓','͔','͕', | ||
| '͖','͙','͚','̣' | ||
| ], | ||
| "mid" : [ | ||
| '̕','̛','̀','́', | ||
| '͘','̡','̢','̧', | ||
| '̨','̴','̵','̶', | ||
| '͜','͝','͞', | ||
| '͟','͠','͢','̸', | ||
| '̷','͡',' ҉' | ||
| ] | ||
| }, | ||
| all = [].concat(soul.up, soul.down, soul.mid), | ||
| zalgo = {}; | ||
| function randomNumber(range) { | ||
| r = Math.floor(Math.random()*range); | ||
| return r; | ||
| }; | ||
| function is_char(character) { | ||
| var bool = false; | ||
| all.filter(function(i){ | ||
| bool = (i == character); | ||
| }); | ||
| return bool; | ||
| } | ||
| function heComes(text, options){ | ||
| result = ''; | ||
| options = options || {}; | ||
| options["up"] = options["up"] || true; | ||
| options["mid"] = options["mid"] || true; | ||
| options["down"] = options["down"] || true; | ||
| options["size"] = options["size"] || "maxi"; | ||
| var counts; | ||
| text = text.split(''); | ||
| for(var l in text){ | ||
| if(is_char(l)) { continue; } | ||
| result = result + text[l]; | ||
| counts = {"up" : 0, "down" : 0, "mid" : 0}; | ||
| switch(options.size) { | ||
| case 'mini': | ||
| counts.up = randomNumber(8); | ||
| counts.min= randomNumber(2); | ||
| counts.down = randomNumber(8); | ||
| break; | ||
| case 'maxi': | ||
| counts.up = randomNumber(16) + 3; | ||
| counts.min = randomNumber(4) + 1; | ||
| counts.down = randomNumber(64) + 3; | ||
| break; | ||
| default: | ||
| counts.up = randomNumber(8) + 1; | ||
| counts.mid = randomNumber(6) / 2; | ||
| counts.down= randomNumber(8) + 1; | ||
| break; | ||
| } | ||
| var arr = ["up", "mid", "down"]; | ||
| for(var d in arr){ | ||
| var index = arr[d]; | ||
| for (var i = 0 ; i <= counts[index]; i++) | ||
| { | ||
| if(options[index]) { | ||
| result = result + soul[index][randomNumber(soul[index].length)]; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return result; | ||
| }; | ||
| return heComes(text); | ||
| } |
| <!DOCTYPE HTML> | ||
| <html lang="en-us"> | ||
| <head> | ||
| <meta http-equiv="Content-type" content="text/html; charset=utf-8"> | ||
| <title>Colors Example</title> | ||
| <script src="colors.js"></script> | ||
| <script type="text/javascript"> | ||
| console.log('Rainbows are fun!'.rainbow); | ||
| console.log('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); | ||
| console.log('Chains are also cool.'.bold.italic.underline.red); | ||
| </script> | ||
| </head> | ||
| <body> | ||
| <script> | ||
| document.write('Rainbows are fun!'.rainbow + '<br>'); | ||
| document.write('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse + '<br>'); | ||
| document.write('Chains are also cool.'.bold.italic.underline.red); | ||
| </script> | ||
| </body> | ||
| </html> |
| var sys = require('sys'); | ||
| var colors = require('./colors'); | ||
| sys.puts('Rainbows are fun!'.rainbow); | ||
| sys.puts('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); // styles not widely supported | ||
| sys.puts('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported | ||
| // sys.puts('zalgo time!'.zalgo); |
| Copyright (c) 2010 Alexis Sellier (cloudhead) , Marak Squires | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in | ||
| all copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| THE SOFTWARE. |
| { | ||
| "name": "colors", | ||
| "description": "get colors in your node.js console like what", | ||
| "version": "0.5.0", | ||
| "author": "Marak Squires", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "http://github.com/Marak/colors.js.git" | ||
| }, | ||
| "engine": [ | ||
| "node >=0.1.90" | ||
| ], | ||
| "main": "colors" | ||
| } |
| <h1>colors.js - get color and style in your node.js console like what</h1> | ||
| <img src="http://i.imgur.com/goJdO.png" border = "0"/> | ||
| var sys = require('sys'); | ||
| var colors = require('./colors'); | ||
| sys.puts('hello'.green); // outputs green text | ||
| sys.puts('i like cake and pies'.underline.red) // outputs red underlined text | ||
| sys.puts('inverse the color'.inverse); // inverses the color | ||
| sys.puts('OMG Rainbows!'.rainbow); // rainbow (ignores spaces) | ||
| <h2>colors and styles!</h2> | ||
| - bold | ||
| - italic | ||
| - underline | ||
| - inverse | ||
| - yellow | ||
| - cyan | ||
| - white | ||
| - magenta | ||
| - green | ||
| - red | ||
| - grey | ||
| - blue | ||
| ### Authors | ||
| #### Alexis Sellier (cloudhead) , Marak Squires , Justin Campbell, Dustin Diaz (@ded) |
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 2 instances
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
42
10.53%0
-100%1
-91.67%2
-50%12044
-95.91%1
Infinity%1
Infinity%6
-81.25%154
-97.49%2
100%+ Added
+ Added