Skip to content

Commit

Permalink
autocb first try
Browse files Browse the repository at this point in the history
  • Loading branch information
maxtaco committed Jan 24, 2012
1 parent f2c561e commit 187abb1
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 18 deletions.
2 changes: 1 addition & 1 deletion TAME.md
Expand Up @@ -5,7 +5,7 @@ Tame is a system for handling callbacks in event-based code. There
were two existing implementations, one in [the sfslite library for
C++](https://github.com/maxtaco/sfslite), and another in [tamejs
translator for JavaScript](https://github.com/maxtaco/tamejs), and
this fork of CoffeeScript attempts a third implementation. The code
this extension to CoffeeScript is a third implementation. The code
and translation techniques are derived from experience with JS, but
with some new Coffee-style flavoring. Also, some of the features in
tamejs are not yet available here.
Expand Down
1 change: 1 addition & 0 deletions TODO-tame.md
Expand Up @@ -4,3 +4,4 @@ Todos
* continuations must therefore return a value
* tamed `for`, `while` and others return a value
* splats in defer
* Autocb?
48 changes: 45 additions & 3 deletions lib/coffee-script/nodes.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions lib/coffee-script/parser.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion lib/coffee-script/tame.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 35 additions & 11 deletions src/nodes.coffee
Expand Up @@ -95,7 +95,7 @@ exports.Base = class Base
if res
new Call new Literal("#{res}.push"), [me]
else
new Return me
new Return me, @hasAutocb

# Does this node, or any of its children, contain a node of a certain kind?
# Recursively traverses down the *children* of the nodes, yielding to a block
Expand Down Expand Up @@ -130,12 +130,10 @@ exports.Base = class Base
#
toString: (idt = '', name = @constructor.name) ->
extras = ""
if @tameNodeFlag
extras += "A"
if @tameLoopFlag
extras += "L"
if @cpsPivotFlag
extras += "P"
extras += "A" if @tameNodeFlag
extras += "L" if @tameLoopFlag
extras += "P" if @cpsPivotFlag
extras += "C" if @hasAutocb
if extras.length
extras = " (" + extras + ")"
tree = '\n' + idt + name
Expand Down Expand Up @@ -211,7 +209,7 @@ exports.Base = class Base
flood = true if @isLoop() and @tameNodeFlag
@tameLoopFlag = flood
for child in @flattenChildren()
@tameLoopFlag = true if child.walkAstTamedLoop (flood)
@tameLoopFlag = true if child.walkAstTamedLoop flood
@tameLoopFlag

# A node is marked as a "cpsPivot" of it is (a) a 'tamed' node,
Expand All @@ -224,6 +222,13 @@ exports.Base = class Base

#
#-----------------------------------------------------------------------

markAutocbs : (found) ->
@hasAutocb = found
for child in @flattenChildren()
child.markAutocbs(found)

#-----------------------------------------------------------------------

needsDummyContinuation : ->
if not @gotCpsSplit
Expand Down Expand Up @@ -268,6 +273,7 @@ exports.Base = class Base
tameNodeFlag : false
gotCpsSplit : false
cpsPivotFlag : false
hasAutocb : false

unwrap : THIS
unfoldSoak : NO
Expand Down Expand Up @@ -462,11 +468,12 @@ exports.Block = class Block extends Base
child = new Block rest
pivot.tameNestContinuationBlock child

# we have to set the taming bit on the new Block
# Pass our node bits onto our new children
for e in rest
child.tameNodeFlag = true if e.tameNodeFlag
child.tameLoopFlag = true if e.tameLoopFlag
child.cpsPivotFlag = true if e.cpsPivotFlag
child.hasAutocb = true if e.hasAutocb

# now recursive apply the transformation to the new child,
# this being especially import in blocks that have multiple
Expand Down Expand Up @@ -510,6 +517,7 @@ exports.Block = class Block extends Base
@addRuntime() if @needsRuntime() and not @findTameRequire()
@walkAstTamedLoop(false)
@walkCpsPivots()
@markAutocbs()
@cpsRotate()
this

Expand Down Expand Up @@ -570,7 +578,7 @@ exports.Literal = class Literal extends Base
# A `return` is a *pureStatement* -- wrapping it in a closure wouldn't
# make sense.
exports.Return = class Return extends Base
constructor: (expr) ->
constructor: (expr, @hasAutocb) ->
@expression = expr if expr and not expr.unwrap().isUndefined

children: ['expression']
Expand All @@ -584,7 +592,15 @@ exports.Return = class Return extends Base
if expr and expr not instanceof Return then expr.compile o, level else super o, level

compileNode: (o) ->
@tab + "return#{[" #{@expression.compile o, LEVEL_PAREN}" if @expression]};"
if @hasAutocb
cb = new Value new Literal tame.const.autocb
args = if @expression then [ @expression ] else []
call = new Call cb, args
ret = new Literal "return"
block = new Block [ call, ret];
block.compile o
else
@tab + "return#{[" #{@expression.compile o, LEVEL_PAREN}" if @expression]};"

#### Value

Expand Down Expand Up @@ -1396,6 +1412,14 @@ exports.Code = class Code extends Base

jumps: NO

markAutocbs: (found) ->
found = false
for p in @params
if p.name instanceof Literal and p.name.value == tame.const.autocb
found = true
break
super(found)

# Compilation creates a new scope unless explicitly asked to share with the
# outer scope. Handles splat parameters in the parameter list by peeking at
# the JavaScript `arguments` object. If the function is bound with the `=>`
Expand Down
1 change: 1 addition & 0 deletions src/tame.coffee
Expand Up @@ -20,6 +20,7 @@ exports.const =
slot : "__slot"
assign_fn : "assign_fn"
runtime : "tamerun"
autocb : "autocb"

#=======================================================================
# runtime
Expand Down

0 comments on commit 187abb1

Please sign in to comment.