Tuesday, March 10, 2009

bespin learns JavaScript

Today I hooked up bespin to Brendan Eich's JavaScript parser written in JavaScript.
Some evil recursive tree wrestling later, we can now find out the names, line and column numbers of all functions in a JS document. I also added some logic, to look up the tree for anonymous functions to see whether they were declared in an object literal, so we can use the key as the inferred name.

The parse tree could be used for all kinds of interesting things, like outlines and even IntelliSense(TM)(R). JS being a very dynamic language this, however, only goes so far. In particular systems like Joose or even dojo's simplistic object system do not go so well with static analysis.

As a next step, I'll move the parser to a web worker (I designed the API to be async, so this should be easy) and implement a simple outline view.

8 comments:

Roberto Saccon said...

Cool ! I am not familiar with narcissus. How does it compare to Pratt or "Top Down Operator Precedence" parser (the one used by Crockford in JSLINT) ?

reed said...

http://mxr.mozilla.org/mozilla-central/source/js/narcissus/jsparse.js has a newer version of Narcissus...

Malte said...

@reed Thanks for the Link! Unfortunately I had to patch the original source to make it runnable in the browser. Maybe this does better.

@rsaccon Didn't know about Pratt. Will check it out. On a first look Pratt looks to be better suited for our task

Brendan Eich said...

Narcissus is getting attention now, in part from researchers at UC Santa Cruz. We plan to make it work in Firefox, probably as an add-on with its own REPL console UI. With ES3.1's Object.defineProperty instead of the __defineProperty__ hack we can support all the standard property attributes.

The parser is recursive descent with operator precedence for expressions, so formally no different from a Pratt parser in language recognition power. JS has a few hard cases, I'm not sure whether JSLint and Narcissus agree on these.

I'm interested in patches to improve source coordinates (column number, etc.), please mail me any and I'll help get them integrated. Thanks!

/be

Malte said...

Hey,

dunno whether I'll be able to dig deep enough to make changes to the core features. Would you be interested in patches that make the source more portable and self-contained. I had to make some local changes to get it to work in FF as you say, plus Google Gears appears to reserve the global constant Block.

malte

Brendan Eich said...

Malte: absolutely. I've wondered whether we shouldn't wrap everything in a closure that's called right away (module pattern) provided there are no leaks. Anyway, I'm interested in whatever you have to contribute. Thanks,

/be

Malte said...

@brendan: Do you have a repository for narcissus that I could clone?

My plan would be to apply the module pattern (which means doing something smart with jsdefs.js, use Object.defineProperty and only expose the parse function (maybe under a different name).

Brendan Eich said...

@Malte: http://hg.mozilla.org/mozilla-central is the Narcissus repo, but it includes Firefox and Gecko. If you can stand to clone it, I would be happy to review your changes. If the time is now to make a narcissus repo of its own, just push back and let me konw. Thanks,

/be