77
edits
(Update deletion) |
|||
| (10 intermediate revisions by 5 users not shown) | |||
| Line 1: | Line 1: | ||
== Brendan's notes == | {{OutdatedSpiderMonkey}} | ||
{{delete|Totally out of date}} | |||
== JavaScript API == | |||
=== Design === | |||
A general parsing API could treat the visitor interface from [http://code.google.com/p/es-lab/wiki/JsonMLASTFormat JsonMLAST] as a [http://en.wikipedia.org/wiki/Builder_pattern builder] with a parametric type. In Java-like pseudo-types: | |||
<pre> | |||
interface Visitor<A> { | |||
visitThisExpr(attr : {}) : A; | |||
visitReturnStmt(attr : {}, | |||
expr : A) : A; | |||
/* etc. */ | |||
} | |||
</pre> | |||
and take it as an optional argument to the constructor of a parser object: | |||
<pre> | |||
class Parser<A> { | |||
Parser(builder : Visitor<A>?); | |||
parse(src : string, | |||
[filename : string?, | |||
startLine : (number >= 1)?, | |||
startColumn : (number >= 0)?]) | |||
: A; | |||
} | |||
</pre> | |||
This would allow the <code>parse</code> method to use the visitor as a way of injecting the parsed nodes into whatever type ''A'' the client wants. Making the argument optional makes it easy to default to the JsonMLAST format. | |||
It's a little messy (wrt types) to reuse the visitor interface for this, since the JsonMLAST visitor expects JsonMLAST values as arguments, whereas this use expects the type ''A'' as arguments. So it's maybe better to have a parallel "Builder" interface that's the same as the visitor interface but with buildXXXX methods instead: | |||
<pre> | |||
interface Builder<A> { | |||
buildThisExpr(attr : {}) : A; | |||
buildReturnStmt(attr : {}, | |||
expr : A) : A; | |||
/* etc. */ | |||
} | |||
</pre> | |||
Should also implement a JsonMLAST processor that takes a visitor: | |||
<pre> | |||
processAST(ast : JsonMLAST, | |||
visitor : Visitor<A>) : A; | |||
</pre> | |||
This could be implemented in pure JS, at least initially. (It'll be ugly without pattern matching, though.) | |||
=== Plan === | |||
Several separate steps to make this work: | |||
*[https://bugzilla.mozilla.org/show_bug.cgi?id=548461 Bug 548461] -- refactor JSCompiler to JSSourceCompiler and JSAstCompiler (draft done, patch under review) | |||
*[https://bugzilla.mozilla.org/show_bug.cgi?id=533874 Bug 533874] -- implement marshalling to JsonMLAST (draft done, not quite ready for review) | |||
*implement source location information | |||
*generalize to take visitor (not started) | |||
*refactor to build on top of C++ API? (not started) | |||
[mailto:dherman@mozilla.com /dherman] | |||
== C++ API == | |||
=== Brendan's notes === | |||
Currently [http://lxr.mozilla.org/mozilla/source/js/src/jsparse.h jsparse.h] defines a <code>JSParseNode</code> struct, a variant record documented by the major comment before its declaration, and a few <code>JS_FRIEND_API</code> entry points for parsing and compiling, but not executing, token streams. | Currently [http://lxr.mozilla.org/mozilla/source/js/src/jsparse.h jsparse.h] defines a <code>JSParseNode</code> struct, a variant record documented by the major comment before its declaration, and a few <code>JS_FRIEND_API</code> entry points for parsing and compiling, but not executing, token streams. | ||
| Line 23: | Line 93: | ||
[mailto:brendan@mozilla.org /be] | [mailto:brendan@mozilla.org /be] | ||
== Kimman's Notes == | === Kimman's Notes === | ||
Work on this API originated from an email in the news group post by Jeremy. I volunteered to assist him and since then we have worked together on this. After getting a feel of the task at hand, we started work on a note outlining ideas for this API. Jeremy has been unable to devote time owing to other committments, and so I am posting this even though I have not had his comments on this note. | Work on this API originated from an email in the news group post by Jeremy. I volunteered to assist him and since then we have worked together on this. After getting a feel of the task at hand, we started work on a note outlining ideas for this API. Jeremy has been unable to devote time owing to other committments, and so I am posting this even though I have not had his comments on this note. | ||
=== Work Done So Far === | ==== Work Done So Far ==== | ||
Based on the hints provided in Brendan's post, the following progress | Based on the hints provided in Brendan's post, the following progress | ||
| Line 32: | Line 102: | ||
1. Parsing a script using js_ParseTokenStream | 1. Parsing a script using js_ParseTokenStream | ||
2. Walking of the ParseNodes tree using recursion | 2. Walking of the ParseNodes tree using recursion | ||
3. Implementation of a simple callback set (HaveNewSubTree, | 3. Implementation of a simple callback set (HaveNewSubTree, | ||
HaveNodeInTree, EndSubTree) that is called during the walking of the | HaveNodeInTree, EndSubTree) that is called during the walking of the | ||
| Line 51: | Line 123: | ||
the second that builds a frequency distribution for 'arity' of nodes, | the second that builds a frequency distribution for 'arity' of nodes, | ||
TOK_ constants and JS Opcodes. | TOK_ constants and JS Opcodes. | ||
5. Implementation of a non-recursive walker making the same callbacks. | 5. Implementation of a non-recursive walker making the same callbacks. | ||
=== About the ParserAPI === | ==== About the ParserAPI ==== | ||
Before implementing an API, it is essential to have the end-use in | Before implementing an API, it is essential to have the end-use in | ||
| Line 102: | Line 175: | ||
=== Design Ideas === | ==== Design Ideas ==== | ||
1. A user of the API should be able to control the extent of | 1. A user of the API should be able to control the extent of | ||
| Line 140: | Line 213: | ||
on TOK_ types. This would seem to be like introducing a 'guide' interface ie the guide interface prepares the visitable which a vistor can visit. | on TOK_ types. This would seem to be like introducing a 'guide' interface ie the guide interface prepares the visitable which a vistor can visit. | ||
5. Reviewing the SpiderMonkey code, there are several places where this | 5. Reviewing the SpiderMonkey code, there are several places where this walker (as a 'js_friend') could be used eg js_FoldConstants, js_EmitTree, CheckSideEffects and some others. These functions currently use recursion and in some cases this recursion appears expensive. I am not sure whether the 'auhtors/maintainers' of these functions would find the code easily maintained if they were to switch to using this API. | ||
=== Other Issues === | ==== Other Issues ==== | ||
1. The API should provide human readable descriptions for elements | 1. The API should provide human readable descriptions for elements | ||
edits