diff options
| author | Joshua Peek <josh@joshpeek.com> | 2012-07-23 15:52:49 -0500 |
|---|---|---|
| committer | Joshua Peek <josh@joshpeek.com> | 2012-07-23 15:52:49 -0500 |
| commit | 7b6caa0f6c7603aabb5e6ed657e24aaddbeafc78 (patch) | |
| tree | ec0522eae75bb04ae73d28ae3f599682a2bfdaeb /samples/CoffeeScript/coffee-script.coffee | |
| parent | 314f0e485227915931db361be14d308a210bedea (diff) | |
Rename samples subdirectories
Diffstat (limited to 'samples/CoffeeScript/coffee-script.coffee')
| -rw-r--r-- | samples/CoffeeScript/coffee-script.coffee | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/samples/CoffeeScript/coffee-script.coffee b/samples/CoffeeScript/coffee-script.coffee new file mode 100644 index 0000000..2933aeb --- /dev/null +++ b/samples/CoffeeScript/coffee-script.coffee @@ -0,0 +1,130 @@ +# CoffeeScript can be used both on the server, as a command-line compiler based +# on Node.js/V8, or to run CoffeeScripts directly in the browser. This module +# contains the main entry functions for tokenizing, parsing, and compiling +# source CoffeeScript into JavaScript. +# +# If included on a webpage, it will automatically sniff out, compile, and +# execute all scripts present in `text/coffeescript` tags. + +fs = require 'fs' +path = require 'path' +{Lexer,RESERVED} = require './lexer' +{parser} = require './parser' +vm = require 'vm' + +# TODO: Remove registerExtension when fully deprecated. +if require.extensions + require.extensions['.coffee'] = (module, filename) -> + content = compile fs.readFileSync(filename, 'utf8'), {filename} + module._compile content, filename +else if require.registerExtension + require.registerExtension '.coffee', (content) -> compile content + +# The current CoffeeScript version number. +exports.VERSION = '1.3.3' + +# Words that cannot be used as identifiers in CoffeeScript code +exports.RESERVED = RESERVED + +# Expose helpers for testing. +exports.helpers = require './helpers' + +# Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison +# compiler. +exports.compile = compile = (code, options = {}) -> + {merge} = exports.helpers + try + js = (parser.parse lexer.tokenize code).compile options + return js unless options.header + catch err + err.message = "In #{options.filename}, #{err.message}" if options.filename + throw err + header = "Generated by CoffeeScript #{@VERSION}" + "// #{header}\n#{js}" + +# Tokenize a string of CoffeeScript code, and return the array of tokens. +exports.tokens = (code, options) -> + lexer.tokenize code, options + +# Parse a string of CoffeeScript code or an array of lexed tokens, and +# return the AST. You can then compile it by calling `.compile()` on the root, +# or traverse it by using `.traverseChildren()` with a callback. +exports.nodes = (source, options) -> + if typeof source is 'string' + parser.parse lexer.tokenize source, options + else + parser.parse source + +# Compile and execute a string of CoffeeScript (on the server), correctly +# setting `__filename`, `__dirname`, and relative `require()`. +exports.run = (code, options = {}) -> + mainModule = require.main + + # Set the filename. + mainModule.filename = process.argv[1] = + if options.filename then fs.realpathSync(options.filename) else '.' + + # Clear the module cache. + mainModule.moduleCache and= {} + + # Assign paths for node_modules loading + mainModule.paths = require('module')._nodeModulePaths path.dirname fs.realpathSync options.filename + + # Compile. + if path.extname(mainModule.filename) isnt '.coffee' or require.extensions + mainModule._compile compile(code, options), mainModule.filename + else + mainModule._compile code, mainModule.filename + +# Compile and evaluate a string of CoffeeScript (in a Node.js-like environment). +# The CoffeeScript REPL uses this to run the input. +exports.eval = (code, options = {}) -> + return unless code = code.trim() + Script = vm.Script + if Script + if options.sandbox? + if options.sandbox instanceof Script.createContext().constructor + sandbox = options.sandbox + else + sandbox = Script.createContext() + sandbox[k] = v for own k, v of options.sandbox + sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox + else + sandbox = global + sandbox.__filename = options.filename || 'eval' + sandbox.__dirname = path.dirname sandbox.__filename + # define module/require only if they chose not to specify their own + unless sandbox isnt global or sandbox.module or sandbox.require + Module = require 'module' + sandbox.module = _module = new Module(options.modulename || 'eval') + sandbox.require = _require = (path) -> Module._load path, _module, true + _module.filename = sandbox.__filename + _require[r] = require[r] for r in Object.getOwnPropertyNames require when r isnt 'paths' + # use the same hack node currently uses for their own REPL + _require.paths = _module.paths = Module._nodeModulePaths process.cwd() + _require.resolve = (request) -> Module._resolveFilename request, _module + o = {} + o[k] = v for own k, v of options + o.bare = on # ensure return value + js = compile code, o + if sandbox is global + vm.runInThisContext js + else + vm.runInContext js, sandbox + +# Instantiate a Lexer for our use here. +lexer = new Lexer + +# The real Lexer produces a generic stream of tokens. This object provides a +# thin wrapper around it, compatible with the Jison API. We can then pass it +# directly as a "Jison lexer". +parser.lexer = + lex: -> + [tag, @yytext, @yylineno] = @tokens[@pos++] or [''] + tag + setInput: (@tokens) -> + @pos = 0 + upcomingInput: -> + "" + +parser.yy = require './nodes' |
