Hi All,

I just started my first foray into javascript beyond the usual minimal glue 
I was used with browsers. After looking at some node tutorials the first 
thing I noticed was the CPS hell (honestly, no way in hell I am dealing 
with that ;)). I present an extremely rough draft of asyncscript; it 
modelled after (black-box) looking at how C# implements its async. 
https://github.com/jcdickinson/asyncscript

The metacompiler first takes an AST (lightly modified acorn.js) and turns 
in into IR. The IR basically adds blocks and closures to the AST, so you 
essentially land up with:

   - Closure
      - Block1
         - AST
      - Block2
         - AST
      - Block3
         - AST
         - Closure
            - ...
         - AST
      
Blocks are breaks in real execution (read: continuations - although I will 
also need to [ab]use them for branching constructs in the presence of the 
async keyword). The IR is then passed off to a few transformation stages 
(async, if, &&/||, while, for - of which only async is implemented). So for 
example, the async transform will create a split in the block (resulting in 
two blocks) at the statement containing the async keyword.

   - Closure (async)
      - Block1
         - AST that was in Block1 before await
         - await
      - Block2
         - grab async result
         - AST that was in Block1 after await
      
Finally the IR is turned into JS. Due to the lack of a goto statement in JS 
I needed to implement 'transitioning' blocks (if, and other 
non-continuation branches) as a while loop:

var state = 0;
while(true) {
  switch(state) {
   case 0:
    blar();
    state = 1; // Effectively a goto
    break;
   case 1:
    baz();
    return;
  }
}

Yes, it's ugly, but I would rather have ugly code than bloating the call 
stack (please, does anyone has any better ideas how to do this without 
wasting stack space?). 'sequencing' blocks simply return out of the 
function after registering the continuation. So at the end of the day you 
get:

asyncscript:
var username = "jimbob";
var settings = await httpGetAsync("http://myserver/?username="; + username);
await displaySomeModal(settings);

javascript (tidied):
(function () {
    var state = 0;
    var awaiter = createAwaiter();
    function continuation() {
        try {
            var result = arguments[1];
            if (typeof arguments[2] !== 'undefined') throw arguments[2];
            state = arguments[0];
            while (true) {
                switch (state) {
                    case 0: {
                        username = "jimbob";
                        await(continuation, 1, 
httpGetAsync("http://myserver/?username="; + username));
                        return;
                    }
                    case 1: {
                        tmp = result;
                        settings = tmp;
                        await(continuation, 2, displaySomeModal(settings));
                        return;
                    }
                    case 2: {
                        completeAwaiter(continuation);
                        return;
                    }
                    default:
                        throw 'The runtime has become unstable.';
                }
            }
        } catch (error) {
            completeAwaiter(continuation, null, error);
            return;
        }
    }
    continuation(0);
    return createPromise(awaiter);
})();

As I said, this is my first serious attempt at JS - so I might have made 
some obvious mistakes (quite possibly messing up the closure semantics, but 
I think I got it right). Feel free to tell me (in a justified way) how I am 
a noob :), also remember that this is a draft: so a very small amount of 
the JS syntax is actually implemented. I would just like some feedback 
before making something that is complete but blatantly incorrect.

I am also [ab]using AMD for the purposes of loading in different 'runtimes' 
(code generators that define how e.g. completeAwaiter and createPromise, 
are generated) for the purposes of e.g. jquery v.s. node-promise. I might 
be doing the totally wrong thing, but thought it was pretty cool. I will 
also fix the folder layout some time later: at the moment it hacks in 
intellisense support for VS2012.

If you think it's beyond help and want to re-implement it, I don't mind at 
all: I would be happy to contribute code and ideas to a repo maintained by 
someone who knows what they are doing.

-- 
jcd

-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Reply via email to