Result is the following, so you don't have to do it yourself:
text/coffeescript
tags.fs = require 'fs'
path = require 'path'
{Lexer} = require './lexer'
{parser} = require './parser'
helpers = require './helpers'
vm = require 'vm'
sourcemap = require './sourcemap'
BOM
s.loadFile = (module, filename) ->
raw = fs.readFileSync filename, 'utf8'
stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
module._compile compile(stripped, {filename, literate: helpers.isLiterate filename}), filename
if require.extensions
for ext in ['.coffee', '.litcoffee', '.md', '.coffee.md']
require.extensions[ext] = loadFile
exports.VERSION = '1.6.1'
exports.helpers = helpers
options.sourceMap
is specified, then options.filename
must also be specified. AllgenerateV3SourceMap()
may also be passed here.options.sourceMap
is passed,exports.compile = compile = (code, options = {}) ->
{merge} = exports.helpers
if options.sourceMap sourceMap = new sourcemap.SourceMap() fragments = (parser.parse lexer.tokenize(code, options)).compileToFragments options
currentLine = 0
currentLine += 1 if options.header
currentColumn = 0
js = ""
for fragment in fragments
if sourceMap if fragment.locationData sourceMap.addMapping(
[fragment.locationData.first_line, fragment.locationData.first_column],
[currentLine, currentColumn],
{noReplace: true})
newLines = helpers.count fragment.code, "\n"
currentLine += newLines
currentColumn = fragment.code.length - (if newLines then fragment.code.lastIndexOf "\n" else 0)
js += fragment.code if options.header
header = "Generated by CoffeeScript #{@VERSION}"
js = "// #{header}\n#{js}"
if options.sourceMap
answer = {js}
if sourceMap
answer.sourceMap = sourceMap
answer.v3SourceMap = sourcemap.generateV3SourceMap(sourceMap, options)
answer
else
js
exports.tokens = (code, options) ->
lexer.tokenize code, options
.compile()
on the root,.traverseChildren()
with a callback.exports.nodes = (source, options) ->
if typeof source is 'string'
parser.parse lexer.tokenize source, options
else
parser.parse source
__filename
, __dirname
, and relative require()
.exports.run = (code, options = {}) ->
mainModule = require.main
options.sourceMap ?= true
mainModule.filename = process.argv[1] = if options.filename then fs.realpathSync(options.filename) else '.'
mainModule.moduleCache and= {}
mainModule.paths = require('module')._nodeModulePaths path.dirname fs.realpathSync options.filename or '.'
if not helpers.isCoffee(mainModule.filename) or require.extensions
answer = compile(code, options)
do patchStackTrace
mainModule._sourceMaps[mainModule.filename] = answer.sourceMap
mainModule._compile answer.js, mainModule.filename
else
mainModule._compile code, mainModule.filename
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
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'
_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
lexer = new Lexer
parser.lexer =
lex: ->
token = @tokens[@pos++]
if token
[tag, @yytext, @yylloc] = token
@yylineno = @yylloc.first_line
else
tag = ''
tag setInput: (@tokens) -> @pos = 0 upcomingInput: -> ""
parser.yy = require './nodes'
parser.yy.parseError = (message, {token}) ->
message = "unexpected #{if token is 1 then 'end of input' else token}"
loc
property, which should have the locationloc
helpers.throwSyntaxError message, parser.lexer.yylloc
patched = false
patchStackTrace = ->
return if patched
patched = true
mainModule = require.main
mainModule._sourceMaps = {}
# exception is thrown in the module body.) Error.prepareStackTrace = (err, stack) -> sourceFiles = {} getSourceMapping = (filename, line, column) ->
sourceMap = mainModule._sourceMaps[filename]
answer = sourceMap.getSourcePosition [line, column] if sourceMap
answer
frames = for frame in stack
break if frame.getFunction() is exports.run
" at #{formatSourcePosition frame, getSourceMapping}"
"#{err.name}: #{err.message ? ''}\n#{frames.join '\n'}\n"
formatSourcePosition = (frame, getSourceMapping) ->
fileName = undefined
fileLocation = ''
if frame.isNative() fileLocation = "native" else if frame.isEval()
fileName = frame.getScriptNameOrSourceURL()
fileLocation = "#{frame.getEvalOrigin()}, " unless fileName
else
fileName = frame.getFileName()
fileName or= "<anonymous>"
line = frame.getLineNumber()
column = frame.getColumnNumber()
source = getSourceMapping fileName, line, column
fileLocation =
if source
"#{fileName}:#{source[0]}:#{source[1]}, <js>:#{line}:#{column}"
else
"#{fileName}:#{line}:#{column}"
functionName = frame.getFunctionName()
isConstructor = frame.isConstructor()
isMethodCall = not (frame.isToplevel() or isConstructor)
if isMethodCall
methodName = frame.getMethodName()
typeName = frame.getTypeName()
if functionName
tp = as = ''
if typeName and functionName.indexOf typeName
tp = "#{typeName}."
if methodName and functionName.indexOf(".#{methodName}") isnt functionName.length - methodName.length - 1
as = " [as #{methodName}]"
"#{tp}#{functionName}#{as} (#{fileLocation})" else "#{typeName}.#{methodName or '<anonymous>'} (#{fileLocation})" else if isConstructor "new #{functionName or '<anonymous>'} (#{fileLocation})" else if functionName "#{functionName} (#{fileLocation})" else fileLocation