[Pkg-mozext-commits] [adblock-plus] 69/464: Output the JS source code as an AST.
David Prévot
taffit at moszumanska.debian.org
Tue Jul 22 20:44:04 UTC 2014
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository adblock-plus.
commit bba7a0b033c67e7b01e23e1a4ece0fde319b3874
Author: Joshua Cranmer <Pidgeot18 at gmail.com>
Date: Wed Mar 24 20:10:00 2010 -0400
Output the JS source code as an AST.
---
Makefile | 2 +-
autotest/test_trueast.js | 9 +
autotest/test_trueast.js.expected | 50 ++++
jshydra.cpp | 15 +-
jshydra_bridge.h | 1 +
scripts/basic.js | 2 +-
scripts/outASTML.js | 7 +
utils/astml.js | 549 ++++++++++++++++++++++++++++++++++++++
utils/dumpast.js | 26 ++
9 files changed, 658 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index b8f336d..b0bc9f6 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ include $(MOZ_SRCDIR)/js/src/config/config.mk
LINK := -L$(MOZ_OBJDIR)/dist/lib -lnspr4 -lm
-jshydra: jshydra.o jshydra_funcs.o jshydra_bridge.o
+jshydra: jshydra.o jshydra_funcs.o jshydra_bridge.o jshydra_ast.o
g++ -o $@ $^ $(MOZ_OBJDIR)/js/src/libjs_static.a $(LINK)
.deps:
diff --git a/autotest/test_trueast.js b/autotest/test_trueast.js
new file mode 100644
index 0000000..b427e84
--- /dev/null
+++ b/autotest/test_trueast.js
@@ -0,0 +1,9 @@
+// Arguments: test_trueast.js
+// Name: Simple asts
+
+include("../utils/astml.js");
+
+function process_js(pn, file) {
+ let ast = makeAST(pn);
+ dump_trueast(ast);
+}
diff --git a/autotest/test_trueast.js.expected b/autotest/test_trueast.js.expected
new file mode 100644
index 0000000..e8f69b5
--- /dev/null
+++ b/autotest/test_trueast.js.expected
@@ -0,0 +1,50 @@
+Program @ 0:0:
+ + sourceElements: [
+ ExpressionStatement @ 4:0:
+ + expr:
+ CallExpression @ 4:0:
+ + func:
+ IdentifierExpression @ 4:0:
+ + name: include
+ + arguments: [
+ LiteralExpression @ 4:8:
+ + objtype: string
+ + value: ../utils/astml.js
+ ]
+ FunctionDeclaration @ 6:0:
+ + name: process_js
+ + arguments: [
+ Parameter @ 6:20:
+ + name: pn
+ Parameter @ 6:24:
+ + name: file
+ ]
+ + body:
+ BlockStatement @ 6:30:
+ + statements: [
+ VarStatement @ 7:2:
+ + variables: [
+ VarDeclaration @ 7:6:
+ + name: ast
+ + initializer:
+ CallExpression @ 7:12:
+ + func:
+ IdentifierExpression @ 7:12:
+ + name: makeAST
+ + arguments: [
+ IdentifierExpression @ 7:20:
+ + name: pn
+ ]
+ ]
+ ExpressionStatement @ 8:2:
+ + expr:
+ CallExpression @ 8:2:
+ + func:
+ IdentifierExpression @ 8:2:
+ + name: dump_trueast
+ + arguments: [
+ IdentifierExpression @ 8:15:
+ + name: ast
+ ]
+ ]
+ ]
diff --git a/jshydra.cpp b/jshydra.cpp
index 669a1e7..84ec3f0 100644
--- a/jshydra.cpp
+++ b/jshydra.cpp
@@ -9,6 +9,16 @@
#include "jshydra_bridge.h"
+struct ASTNode {
+ JSTokenType type;
+ JSTokenPos position;
+ ASTNode *firstChild;
+ ASTNode *nextSibling;
+ void *data;
+};
+
+extern ASTNode *parseNodeToASTNode(JSParseNode *node);
+
void setIntProperty(JSObject *obj, const char *name, int value) {
jshydra_defineProperty(cx, obj, name, INT_TO_JSVAL(value));
}
@@ -99,6 +109,7 @@ JSObject *makeNode(JSParseNode *node) {
JSObject *array = JS_NewArrayObject(cx, 0, NULL);
setArrayElement(array, 0, makeNode(node->pn_kid));
setObjectProperty(object, "kids", array);
+ jshydra_defineProperty(cx, object, "number", INT_TO_JSVAL(node->pn_num));
break;
}
case NAME: {
@@ -144,8 +155,10 @@ JSObject *makeNode(JSParseNode *node) {
jshydra_defineProperty(cx, object, "value", dval);
break;
}
- case NULLARY:
+ case NULLARY: {
+ jshydra_defineProperty(cx, object, "number", INT_TO_JSVAL(node->pn_num));
break;
+ }
case ERROR:
default:
fprintf(stderr, "Unexpected type: %d (arity %d)\n", node->pn_type, node->pn_arity);
diff --git a/jshydra_bridge.h b/jshydra_bridge.h
index 034eb25..d2e23b2 100644
--- a/jshydra_bridge.h
+++ b/jshydra_bridge.h
@@ -29,4 +29,5 @@ jsval jshydra_getToplevelFunction(JSContext *cx, char const *name);
void jshydra_rootObject(JSContext *cx, JSObject *obj);
+JSObject *jshydra_getRegexPrototype(JSContext *cx);
#endif
diff --git a/scripts/basic.js b/scripts/basic.js
index ecf8d9b..4d357c7 100644
--- a/scripts/basic.js
+++ b/scripts/basic.js
@@ -3,7 +3,7 @@
// jshydra.
_print("HI!");
function process_js(ast) {
- for (f in ast) {
+ for (let f in ast) {
_print(f + ": "+ ast[f]);
}
_print(uneval(ast));
diff --git a/scripts/outASTML.js b/scripts/outASTML.js
new file mode 100644
index 0000000..3efa7d4
--- /dev/null
+++ b/scripts/outASTML.js
@@ -0,0 +1,7 @@
+include("../utils/astml.js");
+
+function process_js(pn, file) {
+ dump_ast(pn);
+ let ast = makeAST(pn);
+ dump_trueast(ast);
+}
diff --git a/utils/astml.js b/utils/astml.js
new file mode 100644
index 0000000..5dee77b
--- /dev/null
+++ b/utils/astml.js
@@ -0,0 +1,549 @@
+// Output an JsonML codec for the AST
+
+// Explanation of a node:
+// {
+// type: The type of the node
+// location: "line:col-line:col"
+// }
+/**
+ * Node formats:
+ * Program
+ * sourceElements: Array of elements (functions, statements)
+ * FunctionDeclaration
+ * name: Name of the function
+ * arguments: Array of arguments
+ * body: Array of elements in function body
+ * VarStatement
+ * variables: Variables being initialized
+ * VarDeclaration
+ * name: Name of variable
+ * initializer: Initial value of variable
+ * CallExpression
+ * func: Name of the function being called
+ * arguments: Array of arguments
+ * IdentifierExpression
+ * name: Name of identifier
+ * LiteralExpression
+ * objtype: "null", "boolean", "numeric", "string", "regex"
+ * value: Value of the literal
+ * BinaryExpression
+ * operator: operator (e.g., '|', '+')
+ + lhs, rhs: left-hand, right-hand expressions for the operator
+ */
+include("../utils/dumpast.js");
+include("../utils/cleanast.js");
+
+function getLocation(pn) {
+ return pn.line + ":" + pn.column;
+}
+function shellNode(pn, type) {
+ return {type: type, location: getLocation(pn)};
+}
+function binaryNode(pn, operator) {
+ let ast = shellNode(pn, "BinaryExpression");
+ ast.operator = operator;
+ ast.lhs = parseToAst(pn.kids[0]);
+ ast.rhs = parseToAst(pn.kids[1]);
+ for (let i = 2; i < pn.kids.length; i++) {
+ let sup = shellNode(pn.kids[i], "BinaryExpression");
+ sup.operator = operator;
+ sup.lhs = ast;
+ sup.rhs = parseToAst(pn.kids[i]);
+ ast = sup;
+ }
+ return ast;
+}
+
+function makeAST(pn) {
+ let ast = {
+ type: "Program",
+ location: getLocation(pn),
+ sourceElements: parseToAst(pn).statements
+ };
+ return ast;
+}
+
+function parseToAst(pn) {
+ if (!pn)
+ return pn;
+ try {
+ return global["convert" + decode_type(pn.type)](pn);
+ } catch (e if e instanceof TypeError) {
+ dump_ast(pn);
+ //throw e;
+ throw "Unexpected token " + decode_type(pn.type);
+ }
+}
+
+// Nodes that I don't see in output
+// TOK_ERROR, TOK_EOL, TOK_ELSE, TOK_FINALLY, TOK_SEQ
+// TOK_XMLSTAGO - TOK_XMLLIST are XML and thus ignored
+
+function convertTOK_SEMI(pn) {
+ let ast = shellNode(pn, "ExpressionStatement");
+ if (pn.kids[0])
+ ast.expr = parseToAst(pn.kids[0]);
+ else {
+ ast.type = "EmptyStatement";
+ }
+ return ast;
+}
+
+function convertTOK_COMMA(pn) {
+ return shellNode(pn, "EmptyExpression");
+}
+
+function convertTOK_ASSIGN(pn) {
+ let ast = shellNode(pn, "AssignmentExpression");
+ ast.lhs = parseToAst(pn.kids[0]);
+ ast.rhs = parseToAst(pn.kids[1]);
+ switch (pn.op) {
+ case JSOP_NOP: break;
+ case JSOP_BITOR: ast.operator = '|'; break;
+ case JSOP_BITXOR: ast.operator = '^'; break;
+ case JSOP_BITAND: ast.operator = '&'; break;
+ case JSOP_LSH: ast.operator = '<<'; break;
+ case JSOP_RSH: ast.operator = '>>'; break;
+ case JSOP_URSH: ast.operator = '>>>'; break;
+ case JSOP_ADD: ast.operator = '+'; break;
+ case JSOP_SUB: ast.operator = '-'; break;
+ case JSOP_MUL: ast.operator = '*'; break;
+ case JSOP_DIV: ast.operator = '/'; break;
+ case JSOP_MOD: ast.operator = '%'; break;
+ default: throw "Unexpected operator " + decode_op(pn.op);
+ };
+ return ast;
+}
+
+function convertTOK_HOOK(pn) {
+ let ast = shellNode(pn, "ConditionalExpression");
+ ast.condition = parseToAst(pn.kids[0]);
+ ast.iftrue = parseToAst(pn.kids[1]);
+ ast.iffalse = parseToAst(pn.kids[2]);
+ return ast;
+}
+
+function convertTOK_COLON(pn) {
+ let ast = shellNode(pn, "PropertyLiteral");
+ ast.property = parseToAst(pn.kids[0]);
+ ast.value = parseToAst(pn.kids[1]);
+ return ast;
+}
+
+function convertTOK_OR(pn) { return binaryNode(pn, "||"); }
+function convertTOK_AND(pn) { return binaryNode(pn, "&&"); }
+function convertTOK_BITOR(pn) { return binaryNode(pn, "|"); }
+function convertTOK_BITXOR(pn) { return binaryNode(pn, "^"); }
+function convertTOK_BITAND(pn) { return binaryNode(pn, "&"); }
+function convertTOK_EQOP(pn) {
+ switch (pn.op) {
+ case JSOP_EQ: return binaryNode(pn, "==");
+ case JSOP_NE: return binaryNode(pn, "!=");
+ case JSOP_STRICTEQ: return binaryNode(pn, "===");
+ case JSOP_STRICTNE: return binaryNode(pn, "!==");
+ }
+ throw "Unknown operator: " + decode_op(pn.op);
+}
+function convertTOK_RELOP(pn) {
+ switch (pn.op) {
+ case JSOP_LT: return binaryNode(pn, "<");
+ case JSOP_LE: return binaryNode(pn, "<=");
+ case JSOP_GT: return binaryNode(pn, ">");
+ case JSOP_GE: return binaryNode(pn, ">=");
+ }
+ throw "Unknown operator: " + decode_op(pn.op);
+}
+function convertTOK_SHOP(pn) {
+ switch (pn.op) {
+ case JSOP_LSH: return binaryNode(pn, "<<");
+ case JSOP_RSH: return binaryNode(pn, ">>");
+ case JSOP_URSH: return binaryNode(pn, ">>>");
+ }
+ throw "Unknown operator: " + decode_op(pn.op);
+}
+function convertTOK_PLUS(pn) { return binaryNode(pn, "+"); }
+function convertTOK_MINUS(pn) { return binaryNode(pn, "-"); }
+function convertTOK_STAR(pn) { return binaryNode(pn, "*"); }
+function convertTOK_DIVOP(pn) {
+ switch (pn.op) {
+ case JSOP_MUL: return binaryNode(pn, "*");
+ case JSOP_DIV: return binaryNode(pn, "/");
+ case JSOP_MOD: return binaryNode(pn, "%");
+ }
+ throw "Unknown operator: " + decode_op(pn.op);
+}
+function convertTOK_UNARYOP(pn) {
+ let ast = shellNode(pn, "UnaryExpression");
+ ast.operand = parseToAst(pn.kids[0]);
+ switch (pn.op) {
+ case JSOP_NEG: ast.operator = "-"; break;
+ case JSOP_POS: ast.operator = "+"; break;
+ case JSOP_NOT: ast.operator = "!"; break;
+ case JSOP_BITNOT: ast.operator = "~"; break;
+ case JSOP_TYPEOF: ast.operator = "typeof"; break;
+ case JSOP_VOID: ast.operator = "void"; break;
+ case JSOP_TYPEOFEXPR: ast.operator = "typeof"; break;
+ default:
+ throw "Unknown operator: " + decode_op(pn.op);
+ }
+ return ast;
+}
+function convertTOK_INC(pn) { return convertPrePost(pn, '++'); }
+function convertTOK_DEC(pn) { return convertPrePost(pn, '--'); }
+function convertPrePost(pn, op) {
+ let ast = shellNode(pn, "UnaryExpression");
+ ast.operator = op;
+ ast.operand = parseToAst(pn.kids[0]);
+ switch (pn.op) {
+ case JSOP_INCNAME:
+ case JSOP_INCPROP:
+ case JSOP_INCELEM:
+ case JSOP_DECNAME:
+ case JSOP_DECPROP:
+ case JSOP_DECELEM:
+ /*ast.type = "PrefixExpression";*/ break;
+ case JSOP_NAMEINC:
+ case JSOP_PROPINC:
+ case JSOP_ELEMINC:
+ case JSOP_NAMEDEC:
+ case JSOP_PROPDEC:
+ case JSOP_ELEMDEC:
+ ast.type = "PostfixExpression"; break;
+ default:
+ throw "Unknown operator: " + decode_op(pn.op);
+ }
+ return ast;
+}
+
+function convertTOK_DOT(pn) {
+ let ast = shellNode(pn, "MemberExpression");
+ ast.container = parseToAst(pn.kids[0]);
+ ast.member = shellNode(pn, "Literal");
+ ast.member.objtype = "string";
+ ast.member.value = pn.atom;
+ ast.constmember = pn.atom;
+ return ast;
+}
+
+function convertTOK_LB(pn) {
+ let ast = shellNode(pn, "MemberExpression");
+ ast.container = parseToAst(pn.kids[0]);
+ ast.member = parseToAst(pn.kids[1]);
+ return ast;
+}
+
+function convertTOK_RB(pn) {
+ let ast = shellNode(pn, "ArrayLiteral");
+ ast.members = [parseToAst(x) for each (x in pn.kids)];
+ return ast;
+}
+
+/* Returns a list */
+function convertTOK_LC(pn) {
+ let ast = shellNode(pn, "BlockStatement");
+ ast.statements = [parseToAst(x) for each (x in pn.kids)];
+ if (ast.statements.length == 0) {
+ return shellNode(pn, "EmptyStatement");
+ }
+ return ast;
+}
+
+function convertTOK_RC(pn) {
+ let ast = shellNode(pn, "ObjectLiteral");
+ ast.setters = [parseToAst(x) for each (x in pn.kids)];
+ return ast;
+}
+
+function convertTOK_LP(pn) {
+ let ast = shellNode(pn, "CallExpression");
+ ast.func = parseToAst(pn.kids[0]);
+ ast.arguments = [];
+ for (let i = 1; i < pn.kids.length; i++)
+ ast.arguments[i - 1] = parseToAst(pn.kids[i]);
+ return ast;
+}
+
+function convertTOK_RP(pn) {
+ let ast = shellNode(pn, "UnaryExpression");
+ ast.expr = parseToAst(pn.kids[0]);
+ ast.operator = "()";
+ return ast;
+}
+
+function convertTOK_NAME(pn) {
+ let ast = shellNode(pn, "IdentifierExpression");
+ ast.name = pn.atom;
+ if (pn.kids.length > 0 && pn.kids[0]) {
+ ast.initializer = parseToAst(pn.kids[0]);
+ }
+ return ast;
+}
+
+
+function convertTOK_NUMBER(pn) {
+ let ast = shellNode(pn, "LiteralExpression");
+ ast.objtype = "number";
+ ast.value = pn.value;
+ return ast;
+}
+
+function convertTOK_STRING(pn) {
+ let ast = shellNode(pn, "LiteralExpression");
+ ast.objtype = "string";
+ ast.value = pn.atom;
+ return ast;
+}
+
+function convertTOK_REGEXP(pn) {
+ let ast = shellNode(pn, "LiteralExpression");
+ ast.objtype = "regex";
+ ast.value = pn.value;
+ return ast;
+}
+
+function convertTOK_PRIMARY(pn) {
+ let ast = shellNode(pn, "LiteralExpression");
+ switch (pn.op) {
+ case JSOP_ZERO: ast.objtype = "number"; ast.value = 0; break;
+ case JSOP_ONE: ast.objtype = "number"; ast.value = 1; break;
+ case JSOP_NULL: ast.objtype = "null"; ast.value = null; break;
+ case JSOP_FALSE: ast.objtype = "boolean"; ast.value = false; break;
+ case JSOP_TRUE: ast.objtype = "boolean"; ast.value = true; break;
+ case JSOP_THIS:
+ return shellNode(pn, "ThisExpression");
+ default:
+ throw "Unknown operand: " + decode_op(pn.op);
+ }
+ return ast;
+}
+
+function convertTOK_FUNCTION(pn) {
+ let ast = shellNode(pn, "FunctionDeclaration");
+ ast.name = pn.name;
+ if (pn.kids[0].type == TOK_UPVARS)
+ pn = pn.kids[0];
+ let args = [];
+ if (pn.kids[0].type == TOK_ARGSBODY) {
+ pn = pn.kids[0];
+ while (pn.kids.length > 1) {
+ let argNode = parseToAst(pn.kids.shift());
+ argNode.type = "Parameter";
+ args.push(argNode);
+ }
+ }
+ ast.arguments = args;
+ ast.body = parseToAst(pn.kids[0]);
+ return ast;
+}
+
+function convertTOK_IF(pn) {
+ let ast = shellNode(pn, "IfStatement");
+ ast.cond = parseToAst(pn.kids[0]);
+ ast.body = parseToAst(pn.kids[1]);
+ if (pn.kids[1])
+ ast.elsebody = parseToAst(pn.kids[2]);
+ return ast;
+}
+
+
+function convertTOK_SWITCH(pn) {
+ let ast = shellNode(pn, "SwitchStatement");
+ ast.expr = parseToAst(pn.kids[0]);
+ let rhs = parseToAst(pn.kids[1]);
+ if (rhs instanceof Array)
+ ast.cases = rhs;
+ else
+ throw "What if this isn't an array?";
+ return ast;
+}
+
+function convertTOK_CASE(pn) {
+ let ast = shellNode(pn, "SwitchCase");
+ ast.expr = parseToAst(pn.kids[0]);
+ ast.block = parseToAst(pn.kids[1]);
+ return ast;
+}
+function convertTOK_DEFAULT(pn) {
+ let ast = shellNode(pn, "SwitchCase");
+ ast.block = parseToAst(pn.kids[1]);
+ return ast;
+}
+
+function convertTOK_WHILE(pn) {
+ let ast = shellNode(pn, "WhileStatement");
+ ast.cond = parseToAst(pn.kids[0]);
+ ast.body = parseToAst(pn.kids[1]);
+ return ast;
+}
+function convertTOK_DO(pn) {
+ let ast = shellNode(pn, "DoWhileStatement");
+ ast.body = parseToAst(pn.kids[0]);
+ ast.cond = parseToAst(pn.kids[1]);
+ return ast;
+}
+
+function convertTOK_FOR(pn) {
+ let ast = shellNode(pn, "ForStatement");
+ let expr = parseToAst(pn.kids[0]);
+ if (expr.type == "Forehead") {
+ ast.init = expr.init;
+ ast.condition = expr.condition;
+ ast.increment = expr.increment;
+ } else {
+ ast.type = "ForInStatement";
+ ast.itervar = expr.lhs;
+ ast.iterrange = expr.rhs;
+ ast.itertype = (pn.iflags & 0x2 ? "foreach" : "for");
+ }
+ ast.body = parseToAst(pn.kids[1]);
+ return ast;
+}
+
+function convertTOK_BREAK(pn) {
+ let ast = shellNode(pn, "BreakStatement");
+ if (pn.atom)
+ ast.label = pn.atom;
+ return ast;
+}
+function convertTOK_CONTINUE(pn) {
+ let ast = shellNode(pn, "ContinueStatement");
+ if (pn.atom)
+ ast.label = pn.atom;
+ return ast;
+}
+
+function convertTOK_IN(pn) { return binaryNode(pn, "in"); }
+
+function convertTOK_VAR(pn) {
+ let ast = shellNode(pn, "VarStatement");
+ if (pn.op == JSOP_DEFCONST)
+ ast.constant = true;
+ ast.variables = [parseToAst(x) for each (x in pn.kids)];
+ for each (let x in ast.variables) {
+ x.type = "VarDeclaration";
+ }
+ return ast;
+}
+
+function convertTOK_WITH(pn) {
+ let ast = shellNode(pn, "WithStatement");
+ ast.expr = parseToAst(pn.kids[0]);
+ ast.block = parseToAst(pn.kids[1]);
+ return ast;
+}
+
+function convertTOK_RETURN(pn) {
+ let ast = shellNode(pn, "ReturnStatement");
+ ast.expr = parseToAst(pn.kids[0]);
+ return ast;
+}
+
+function convertTOK_NEW(pn) {
+ let ast = shellNode(pn, "NewExpression");
+ ast.constructor = parseToAst(pn.kids[0]);
+ ast.args = [];
+ for (let i = 1; i < pn.kids.length; i++)
+ ast.args.push(parseToAst(pn.kids[i]));
+ return ast;
+}
+
+function convertTOK_DELETE(pn) {
+ let ast = shellNode(pn, "UnaryExpression");
+ ast.operator = "delete";
+ ast.operand = parseToAst(pn.kids[0]);
+ return ast;
+}
+
+function convertTOK_DEFSHARP(pn) {
+ let ast = shellNode(pn, "SharpDefinitionExpression");
+ ast.expr = parseToAst(pn.kids[0]);
+ ast.sharpnum = pn.number;
+ return ast;
+}
+function convertTOK_USESHARP(pn) {
+ let ast = shellNode(pn, "SharpExpression");
+ ast.sharpnum = pn.number;
+ return ast;
+}
+
+function convertTOK_TRY(pn) {
+ let ast = shellNode(pn, "TryStatement");
+ ast.body = parseToAst(pn.kids[0]);
+ if (pn.kids[1])
+ ast.catchers = parseToAst(pn.kids[1]);
+ else
+ ast.catchers = [];
+ if (pn.kids[2])
+ ast.fin = parseToAst(pn.kids[2]);
+ return ast;
+}
+
+function convertTOK_CATCH(pn) {
+ let ast = shellNode(pn, "CatchStatement");
+ ast.variable = parseToAst(pn.kids[0]);
+ if (pn.kids[1])
+ ast.condition = parseToAst(pn.kids[1]);
+ ast.block = parseToAst(pn.kids[2]);
+ return ast;
+}
+
+function convertTOK_THROW(pn) {
+ let ast = shellNode(pn, "ThrowStatement");
+ ast.expr = parseToAst(pn.kids[0]);
+ return ast;
+}
+
+function convertTOK_INSTANCEOF(pn) { return binaryNode(pn, "instanceof"); }
+
+function convertTOK_DEBUGGER(pn) { return shellNode(pn, "DebuggerStatement"); }
+// XML OPS
+
+function convertTOK_YIELD(pn) {
+ let ast = shellNode(pn, "YieldStatement");
+ ast.expr = parseToAst(pn.kids[0]);
+ return ast;
+}
+
+function convertTOK_ARRAYCOMP(pn) {
+ let ast = parseToAst(pn.kids[0]);
+ ast.type = "ArrayComprehensionExpression";
+ if ("expr" in ast.body)
+ ast.element = ast.body.expr;
+ else {
+ ast.element = ast.body.body.expr;
+ ast.iterif = ast.body.cond;
+ }
+ delete ast.body;
+ return ast;
+}
+
+function convertTOK_ARRAYPUSH(pn) {
+ let ast = shellNode(pn, "ArrayPush");
+ ast.expr = parseToAst(pn.kids[0]);
+ return ast;
+}
+
+function convertTOK_LEXICALSCOPE(pn) {
+ return parseToAst(pn.kids[0]);
+}
+
+function convertTOK_LET(pn) {
+ let ast = convertTOK_VAR(pn);
+ ast.type = "LetStatement";
+ return ast;
+}
+
+function convertTOK_FORHEAD(pn) {
+ let ast = shellNode(pn, "Forehead");
+ ast.init = pn.kids[0] ? parseToAst(pn.kids[0]) :
+ shellNode(pn, "EmptyStatement");
+ ast.condition = pn.kids[1] ? parseToAst(pn.kids[1]) :
+ shellNode(pn, "EmptyStatement");
+ ast.increment = pn.kids[2] ? parseToAst(pn.kids[2]) :
+ shellNode(pn, "EmptyStatement");
+ return ast;
+}
+
+function convertTOK_RESERVED(pn) {
+ return [parseToAst(x) for each (x in pn.kids)];
+}
diff --git a/utils/dumpast.js b/utils/dumpast.js
index b2456da..ad7cffc 100644
--- a/utils/dumpast.js
+++ b/utils/dumpast.js
@@ -51,3 +51,29 @@ function decode_type(opcode) {
return toktable[opcode];
return opcode;
}
+
+function dump_trueast(ast, prefix) {
+ if (ast == null)
+ return;
+ if (!prefix)
+ prefix = "";
+ let str = prefix + "+ ";
+ _print(prefix + ast.type + " @ " + ast.location + ":");
+ for (let key in ast) {
+ if (key == 'type' || key == 'location')
+ continue;
+ let val = ast[key];
+ if (val instanceof Array) {
+ _print(prefix + " + " + key + ": [");
+ for each (let kind in val) {
+ dump_trueast(kind, prefix + " ");
+ }
+ _print(prefix + " ]");
+ } else if (val instanceof Object && "type" in val) {
+ _print(prefix + " + " + key + ":");
+ dump_trueast(val, prefix + " ");
+ } else {
+ _print(prefix + " + " + key + ": " + val);
+ }
+ }
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/adblock-plus.git
More information about the Pkg-mozext-commits
mailing list