Skip to content

Commit

Permalink
#9: share scope
Browse files Browse the repository at this point in the history
  • Loading branch information
also committed Aug 4, 2014
1 parent d1eaa0f commit 585e699
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 9 deletions.
18 changes: 16 additions & 2 deletions app/coffeescript_cell.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ Builtins = require './builtins'
React = require 'react'
Components = require './components'
printStackTrace = require 'stacktrace-js'
acorn = require 'acorn'
escope = require 'escope'
_ = require 'underscore'


if process.browser
{Scope} = CoffeeScript.require './scope'
freeVariable = Scope::freeVariable
Scope::freeVariable = (name, reserve) -> freeVariable.call @, "LEAD_COFFEESCRIPT_FREE_VARIABLE_#{name}", reserve

recompile = (error_marks, editor) ->
m.clear() for m in error_marks
Expand All @@ -25,8 +34,13 @@ get_fn = (run_context) ->
create_fn = (string) ->
(ctx) ->
try
compiled = CoffeeScript.compile(string, bare: true) + "\n//@ sourceURL=console-coffeescript.js"
return Context.scoped_eval ctx, compiled
locals = Object.keys ctx.repl_vars
compiled = CoffeeScript.compile(string, bare: true, locals: locals) + "\n//@ sourceURL=console-coffeescript.js"
ast = acorn.parse compiled
scopes = escope.analyze(ast).scopes
global_scope = _.find scopes, (s) -> s.type == 'global'
global_vars = _.pluck global_scope.variables, 'name'
return Context.scoped_eval ctx, compiled, _.reject global_vars, (name) -> name.indexOf('_LEAD_COFFEESCRIPT_FREE_VARIABLE_') == 0
catch e
if e instanceof SyntaxError
Context.add_component ctx, Builtins.ErrorComponent message: "Syntax Error: #{e.message} at #{e.location.first_line + 1}:#{e.location.first_column + 1}"
Expand Down
19 changes: 13 additions & 6 deletions app/context.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ TopLevelContextComponent = React.createClass
# the base context contains the loaded modules, and the list of modules to import into every context
create_base_context = ({module_names, imports}) ->
modules = Modules.get_modules(_.union imports or [], module_names or [])
{modules, imports}
# TODO find a better home for repl vars
{modules, imports, repl_vars: {}}

# the XXX context contains all the context functions and vars. basically, everything needed to support
# an editor
Expand Down Expand Up @@ -298,13 +299,19 @@ create_standalone_context = ({imports, module_names}={}) ->
base_context = create_base_context({imports: ['builtins'].concat(imports or []), module_names})
create_run_context [create_context base_context]

scoped_eval = (ctx, string) ->

scoped_eval = (ctx, string, var_names=[]) ->
if _.isFunction string
string = "(#{string}).apply(this);"
context_scope = ctx.scope
`with (context_scope) {`
result = (-> eval string).call ctx
`}`
_.each var_names, (name) ->
ctx.repl_vars[name] ?= undefined
result = null
(->
`with (ctx.scope) { with (ctx.repl_vars) {`
result = eval string
`}}`
).call ctx

result

eval_in_context = (run_context, string) ->
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
"bacon.model": "0.1.10",
"codemirror": "^4.3.0",
"jsdom": "~0.8.4",
"react-router": "^0.5.0"
"react-router": "^0.5.0",
"acorn": "^0.6.0",
"escope": "^1.0.1"
},
"devDependencies": {
"grunt": "~0.4.5",
Expand Down

0 comments on commit 585e699

Please sign in to comment.