diff --git a/lib/coffee-script/repl.js b/lib/coffee-script/repl.js index 977f4d42..b4e45629 100644 --- a/lib/coffee-script/repl.js +++ b/lib/coffee-script/repl.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 1.5.0 (function() { - var CoffeeScript, addMultilineHandler, merge, nodeREPL, replDefaults, vm; + var CoffeeScript, CompilerError, addMultilineHandler, merge, nodeREPL, replDefaults, vm; vm = require('vm'); @@ -8,24 +8,29 @@ CoffeeScript = require('./coffee-script'); + CompilerError = require('./error').CompilerError; + merge = require('./helpers').merge; replDefaults = { prompt: 'coffee> ', "eval": function(input, context, filename, cb) { - var js; + var Assign, Block, Literal, Value, ast, js, _ref; input = input.replace(/\uFF00/g, '\n'); - input = input.replace(/(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/, '$1$2$3'); - if (/^\s*$/.test(input)) { - return cb(null); - } + input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1'); + _ref = require('./nodes'), Block = _ref.Block, Assign = _ref.Assign, Value = _ref.Value, Literal = _ref.Literal; try { - js = CoffeeScript.compile("_=(" + input + "\n)", { - filename: filename, + ast = CoffeeScript.nodes(input); + ast = new Block([new Assign(new Value(new Literal('_')), ast, '=')]); + js = ast.compile({ bare: true }); } catch (err) { - cb(err); + if (err instanceof CompilerError) { + console.log(err.prettyMessage(filename, input, true)); + } else { + cb(err); + } } return cb(null, vm.runInContext(js, context, filename)); } diff --git a/src/repl.coffee b/src/repl.coffee index c0855b43..fc2631e1 100644 --- a/src/repl.coffee +++ b/src/repl.coffee @@ -1,22 +1,35 @@ vm = require 'vm' nodeREPL = require 'repl' CoffeeScript = require './coffee-script' +{CompilerError} = require './error' {merge} = require './helpers' replDefaults = prompt: 'coffee> ', eval: (input, context, filename, cb) -> - # XXX: multiline hack + # XXX: multiline hack. input = input.replace /\uFF00/g, '\n' - # strip single-line comments - input = input.replace /(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/, '$1$2$3' - # empty command - return cb null if /^\s*$/.test input + # Node's REPL sends the input ending with a newline and then wrapped in + # parens. Unwrap all that. + input = input.replace /^\(([\s\S]*)\n\)$/m, '$1' + + # Require AST nodes to do some AST manipulation. + {Block, Assign, Value, Literal} = require './nodes' + # TODO: fix #1829: pass in-scope vars and avoid accidentally shadowing them by omitting those declarations try - js = CoffeeScript.compile "_=(#{input}\n)", {filename, bare: yes} + # Generate the AST of the clean input. + ast = CoffeeScript.nodes input + # Add assignment to `_` variable to force the input to be an expression. + ast = new Block [ + new Assign (new Value new Literal '_'), ast, '=' + ] + js = ast.compile bare: yes catch err - cb err + if err instanceof CompilerError + console.log err.prettyMessage filename, input, yes + else + cb err cb null, vm.runInContext(js, context, filename) addMultilineHandler = (repl) ->