1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

unifying all of the server-side evaluation under CoffeeScript.run -- this means that __filename and __dirname and relative requires should work from all angles under Node.js

This commit is contained in:
Jeremy Ashkenas 2010-03-07 21:49:08 -05:00
parent 0bc7719572
commit 06b50ecb98
9 changed files with 43 additions and 27 deletions

View file

@ -73,6 +73,5 @@ task 'test', 'run the CoffeeScript language test suite', ->
puts '\033[0;32mpassed ' + test_count + ' tests in ' + time + ' seconds\033[0m' puts '\033[0;32mpassed ' + test_count + ' tests in ' + time + ' seconds\033[0m'
fs.readdir 'test', (err, files) -> fs.readdir 'test', (err, files) ->
for file in files for file in files
fs.readFile 'test/' + file, (err, source) -> fs.readFile 'test/' + file, (err, code) ->
js: coffee.compile source coffee.run code, file
process.compile js, file

View file

@ -52,7 +52,7 @@
throw new Error("Cakefile not found in " + (process.cwd())); throw new Error("Cakefile not found in " + (process.cwd()));
} }
args = process.argv.slice(2, process.argv.length); args = process.argv.slice(2, process.argv.length);
eval(coffee.compile(fs.readFileSync('Cakefile'))); coffee.run(fs.readFileSync('Cakefile'), 'Cakefile');
oparse = new optparse.OptionParser(switches); oparse = new optparse.OptionParser(switches);
if (!(args.length)) { if (!(args.length)) {
return print_tasks(); return print_tasks();

View file

@ -34,6 +34,15 @@
exports.nodes = function nodes(code) { exports.nodes = function nodes(code) {
return parser.parse(lexer.tokenize(code)); return parser.parse(lexer.tokenize(code));
}; };
// Compile and execute a string of CoffeeScript (on the server), correctly
// setting `__filename`, `__dirname`, and relative `require()`.
exports.run = function run(code, source, options) {
var __dirname, __filename;
__filename = source;
__dirname = path.dirname(source);
module.filename = source;
return eval(exports.compile(code, options));
};
// The real Lexer produces a generic stream of tokens. This object provides a // 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 // thin wrapper around it, compatible with the Jison API. We can then pass it
// directly as a "Jison lexer". // directly as a "Jison lexer".

View file

@ -80,13 +80,15 @@
// in common. If evaluating the script directly sets `__filename`, `__dirname` // in common. If evaluating the script directly sets `__filename`, `__dirname`
// and `module.filename` to be correct relative to the script's path. // and `module.filename` to be correct relative to the script's path.
compile_script = function compile_script(source, code) { compile_script = function compile_script(source, code) {
var __dirname, __filename, js, o; var js, o;
o = options; o = options;
try { try {
if (o.tokens) { if (o.tokens) {
return print_tokens(CoffeeScript.tokens(code)); return print_tokens(CoffeeScript.tokens(code));
} else if (o.nodes) { } else if (o.nodes) {
return puts(CoffeeScript.nodes(code).toString()); return puts(CoffeeScript.nodes(code).toString());
} else if (o.run) {
return CoffeeScript.run(code, source, compile_options());
} else { } else {
js = CoffeeScript.compile(code, compile_options()); js = CoffeeScript.compile(code, compile_options());
if (o.compile) { if (o.compile) {
@ -95,11 +97,6 @@
return lint(js); return lint(js);
} else if (o.print || o.eval) { } else if (o.print || o.eval) {
return print(js); return print(js);
} else {
__filename = source;
__dirname = path.dirname(source);
module.filename = source;
return eval(js);
} }
} }
} catch (err) { } catch (err) {
@ -199,8 +196,10 @@
// Use the [OptionParser module](optparse.html) to extract all options from // Use the [OptionParser module](optparse.html) to extract all options from
// `process.argv` that are specified in `SWITCHES`. // `process.argv` that are specified in `SWITCHES`.
parse_options = function parse_options() { parse_options = function parse_options() {
var o;
option_parser = new optparse.OptionParser(SWITCHES, BANNER); option_parser = new optparse.OptionParser(SWITCHES, BANNER);
options = option_parser.parse(process.argv); o = (options = option_parser.parse(process.argv));
options.run = !(o.compile || o.print || o.lint || o.eval);
return sources = options.arguments.slice(2, options.arguments.length); return sources = options.arguments.slice(2, options.arguments.length);
}; };
// The compile-time options to pass to the CoffeeScript compiler. // The compile-time options to pass to the CoffeeScript compiler.

View file

@ -1,5 +1,5 @@
(function(){ (function(){
var CoffeeScript, prompt, quit, run; var CoffeeScript, prompt, run;
// A very simple Read-Eval-Print-Loop. Compiles one line at a time to JavaScript // A very simple Read-Eval-Print-Loop. Compiles one line at a time to JavaScript
// and evaluates it. Good for simple tests, or poking around the **Node.js** API. // and evaluates it. Good for simple tests, or poking around the **Node.js** API.
// Using it looks like this: // Using it looks like this:
@ -9,19 +9,21 @@
// Our prompt. // Our prompt.
prompt = 'coffee> '; prompt = 'coffee> ';
// Quick alias for quitting the REPL. // Quick alias for quitting the REPL.
quit = function quit() { process.mixin({
return process.exit(0); quit: function quit() {
}; return process.exit(0);
}
});
// The main REPL function. **run** is called every time a line of code is entered. // The main REPL function. **run** is called every time a line of code is entered.
// Attempt to evaluate the command. If there's an exception, print it out instead // Attempt to evaluate the command. If there's an exception, print it out instead
// of exiting. // of exiting.
run = function run(code) { run = function run(code) {
var val; var val;
try { try {
val = eval(CoffeeScript.compile(code, { val = CoffeeScript.run(code, 'repl', {
no_wrap: true, no_wrap: true,
globals: true globals: true
})); });
if (val !== undefined) { if (val !== undefined) {
p(val); p(val);
} }

View file

@ -46,7 +46,7 @@ exports.run: ->
path.exists 'Cakefile', (exists) -> path.exists 'Cakefile', (exists) ->
throw new Error("Cakefile not found in ${process.cwd()}") unless exists throw new Error("Cakefile not found in ${process.cwd()}") unless exists
args: process.argv[2...process.argv.length] args: process.argv[2...process.argv.length]
eval coffee.compile fs.readFileSync 'Cakefile' coffee.run fs.readFileSync('Cakefile'), 'Cakefile'
oparse: new optparse.OptionParser switches oparse: new optparse.OptionParser switches
return print_tasks() unless args.length return print_tasks() unless args.length
options: oparse.parse(args) options: oparse.parse(args)

View file

@ -35,6 +35,14 @@ exports.tokens: (code) ->
exports.nodes: (code) -> exports.nodes: (code) ->
parser.parse lexer.tokenize code parser.parse lexer.tokenize code
# Compile and execute a string of CoffeeScript (on the server), correctly
# setting `__filename`, `__dirname`, and relative `require()`.
exports.run: (code, source, options) ->
__filename: source
__dirname: path.dirname source
module.filename: source
eval exports.compile code, options
# The real Lexer produces a generic stream of tokens. This object provides a # 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 # thin wrapper around it, compatible with the Jison API. We can then pass it
# directly as a "Jison lexer". # directly as a "Jison lexer".

View file

@ -78,16 +78,12 @@ compile_script: (source, code) ->
try try
if o.tokens then print_tokens CoffeeScript.tokens code if o.tokens then print_tokens CoffeeScript.tokens code
else if o.nodes then puts CoffeeScript.nodes(code).toString() else if o.nodes then puts CoffeeScript.nodes(code).toString()
else if o.run then CoffeeScript.run code, source, compile_options()
else else
js: CoffeeScript.compile code, compile_options() js: CoffeeScript.compile code, compile_options()
if o.compile then write_js source, js if o.compile then write_js source, js
else if o.lint then lint js else if o.lint then lint js
else if o.print or o.eval then print js else if o.print or o.eval then print js
else
__filename: source
__dirname: path.dirname source
module.filename: source
eval js
catch err catch err
if o.watch then puts err.message else throw err if o.watch then puts err.message else throw err
@ -142,8 +138,9 @@ print_tokens: (tokens) ->
# `process.argv` that are specified in `SWITCHES`. # `process.argv` that are specified in `SWITCHES`.
parse_options: -> parse_options: ->
option_parser: new optparse.OptionParser SWITCHES, BANNER option_parser: new optparse.OptionParser SWITCHES, BANNER
options: option_parser.parse(process.argv) o: options: option_parser.parse(process.argv)
sources: options.arguments[2...options.arguments.length] options.run: not (o.compile or o.print or o.lint or o.eval)
sources: options.arguments[2...options.arguments.length]
# The compile-time options to pass to the CoffeeScript compiler. # The compile-time options to pass to the CoffeeScript compiler.
compile_options: -> compile_options: ->

View file

@ -11,14 +11,16 @@ CoffeeScript: require 'coffee-script'
prompt: 'coffee> ' prompt: 'coffee> '
# Quick alias for quitting the REPL. # Quick alias for quitting the REPL.
quit: -> process.exit(0) process.mixin {
quit: -> process.exit(0)
}
# The main REPL function. **run** is called every time a line of code is entered. # The main REPL function. **run** is called every time a line of code is entered.
# Attempt to evaluate the command. If there's an exception, print it out instead # Attempt to evaluate the command. If there's an exception, print it out instead
# of exiting. # of exiting.
run: (code) -> run: (code) ->
try try
val: eval CoffeeScript.compile code, {no_wrap: true, globals: true} val: CoffeeScript.run code, 'repl', {no_wrap: true, globals: true}
p val if val isnt undefined p val if val isnt undefined
catch err catch err
puts err.stack or err.toString() puts err.stack or err.toString()