What is ecmascript-astecmascript-ast patches the V8 engine to enable javascript source code to be parsed to a string containing the source's AST in JsonML format. The JsonML string can then be evaluated (executed). The JSON global object is used as a (temporary) namespace:
... [More]
JSON.AST.parse(|String of js source code|) -> |String of JsonML AST|
JSON.AST.evaluate(|String of JsonML AST|) -> |js result object|The aim is to develop a generic - hopefully standardized - serialization format for the AST in JsonML. Using the output from the --print-json-ast option in the V8 shell as an input. See DesignNotes for details.
Project on hold until further clarification - see es-discuss. The way the various engines layout their AST nodes will have to correspond I guess. Fun hack though.
Example> more example.js
var source = "x = 2; if (x > 1) print(x + 3);";
print("--- js source ---");
print(source);
print("");
print("--- ast ---");
var ast = JSON.AST.parse(source);
print(ast);
print("");
print("--- evaluate(ast) ---");
JSON.AST.evaluate(ast);
> ./shell_g example.js
--- js source ---
x = 2; if (x > 1) print(x + 3);
--- ast ---
["Program",
["ExprStmt",
["Assign",
{"op":"="},
["Id",
{"name":"x"}
],
["Literal",
{"handle":2}
]
]
],
["If",
["CompareOp",
{"op":">"},
["Id",
{"name":"x"}
],
["Literal",
{"handle":1}
]
],
["ExprStmt",
["Call",
["Id",
{"name":"print"}
],
["BinOp",
{"op":"+"},
["Id",
{"name":"x"}
],
["Literal",
{"handle":3}
]
]
]
],
["EmptyStmt"]
]
]
--- evaluate(ast) ---
5
How to installGet the v8 source svn checkout http://v8.googlecode.com/svn/trunk/ v8astDownload the patch jsonast.diff into the v8ast directory (from Featured Downloads ->) Run the patch cd v8ast
patch -p1 < jsonast.diffBuild v8 and run example scons mode=debug sample=shell
./shell_g example.js # basic testN.B:
patch only works for debug mode. It's an experimental work-in-progress prototype!
JSON.AST.parse() serializes all of the grammar/AST to JsonML (I think). JSON.AST.evaluate() is rudimentary. (Basically example.js and ast-test/if.js and while.js work!) the patch creates shell scripts which can run the sample JS files in the ast-test subdir from the command line: # make the shell scripts executable
chmod u+x ast*.sh
# run sample files
./ast-parse.sh ast-test/if.js | tee zout.txt # parse JS file to JsonML AST
./ast-evaluate.sh zout.txt # evaluate JsonML AST file
./ast.sh ast-test/if.js # parse JS file to JsonML AST and then evaluate the JsonML ASTV8 debugger scons mode=debug d8 # build d8 javascript debugger
./shell_g d8ast.js -- ast-test/if.js # d8 uses arguments - no shell script wrapper needed.See BuildInstructions for how to build from scratch. FuturesGeneric Serialization formatThe aim is to develop a generic - hopefully standardized - format for the AST. With the V8 format as an input. (Which, i guess, ECMAScript engines could support as an new, additional format to any existing AST serialization formats).
Native and Pure Javascript implementationsThis prototype is implemented in native code. However, JSON.AST - like the JSON object - could initially be implemented in pure javascript. Then engines could determine whether to provide native implementations.
A native JSON.AST.parse() outputting JsonML should be relatively straighforward - walk the native tree - which is what this prototype does. JSON.AST.evaluate() is more tricky - two alternatives. 1) Parse and execute the JsonML directly (which the prototype does). 2) Parse the JsonML to JS - and then the JS can be eval'ed. (A JsonML to JS function is probably desirable in any case).
DSL's and line numbersWhen using JsonML as a DSL target it would be useful to pass the line number or character position of the DSL construct to the runtime so that runtime errors are correctly reported. How about:
["If", {pos:55}, ["CompOp", ...The V8 AST C++ nodes have members int statement_pos_ and int pos_ which store the character position and are used to report the runtime line number when errors occur. (Though how it does the conversion from pos to line number is opaque to me!). So the evaluate() function would set this value. How and when should errors in the JsonML syntax errors be reported though?
Compact formatThe example was pretty printed with indentation and newlines. A production version would offer a minified alternative.e.g:
["Program",["ExprStmt",["Assign",{"op":"="},["Id",{"name":"x"}], ...Perhaps there could an alternative compact format where the element strings are replaced with integers:
[44,[20,[21,{"op":"="},[25,{"name":"x"}], ...And the attribute name string with an integer or maybe the first letter:
[44,[20,[21,{1:"="},[25,{3:"x"}], ...
[44,[20,[21,{"o":"="},[25,{n:"x"}], ...It's compact and as the integers match the underlying enum no hash lookup for the element/attribute string names is required. Kind of a half way house between the AST and bytecode.
var ast = JSON.AST.parse(source, true); // true for compact mode
var result = JSON.AST.evaluate(ast); // No special mode requiredThe evaluate function would simply test if the element value was a string or integer and hash lookup or atoi. [Less]