backing out due to red

This commit is contained in:
Dave Herman 2011-01-03 16:46:25 -08:00
parent f1fe5f6fd2
commit 8d44347d5f
6 changed files with 186 additions and 913 deletions

View File

@ -39,81 +39,80 @@
/* AST_ERROR = -1 */
ASTDEF(AST_PROGRAM, "Program", "program")
ASTDEF(AST_PROGRAM, "Program")
ASTDEF(AST_IDENTIFIER, "Identifier", "identifier")
ASTDEF(AST_LITERAL, "Literal", "literal")
ASTDEF(AST_PROPERTY, "Property", "property")
ASTDEF(AST_IDENTIFIER, "Identifier")
ASTDEF(AST_LITERAL, "Literal")
ASTDEF(AST_PROPERTY, "Property")
ASTDEF(AST_FUNC_DECL, "FunctionDeclaration", "functionDeclaration")
ASTDEF(AST_VAR_DECL, "VariableDeclaration", "variableDeclaration")
ASTDEF(AST_VAR_DTOR, "VariableDeclarator", "variableDeclarator")
ASTDEF(AST_FUNC_DECL, "FunctionDeclaration")
ASTDEF(AST_VAR_DECL, "VariableDeclaration")
ASTDEF(AST_VAR_DTOR, "VariableDeclarator")
ASTDEF(AST_LIST_EXPR, "SequenceExpression", "sequenceExpression")
ASTDEF(AST_COND_EXPR, "ConditionalExpression", "conditionalExpression")
ASTDEF(AST_UNARY_EXPR, "UnaryExpression", "unaryExpression")
ASTDEF(AST_BINARY_EXPR, "BinaryExpression", "binaryExpression")
ASTDEF(AST_ASSIGN_EXPR, "AssignmentExpression", "assignmentExpression")
ASTDEF(AST_LOGICAL_EXPR, "LogicalExpression", "logicalExpression")
ASTDEF(AST_UPDATE_EXPR, "UpdateExpression", "updateExpression")
ASTDEF(AST_NEW_EXPR, "NewExpression", "newExpression")
ASTDEF(AST_CALL_EXPR, "CallExpression", "callExpression")
ASTDEF(AST_MEMBER_EXPR, "MemberExpression", "memberExpression")
ASTDEF(AST_FUNC_EXPR, "FunctionExpression", "functionExpression")
ASTDEF(AST_ARRAY_EXPR, "ArrayExpression", "arrayExpression")
ASTDEF(AST_OBJECT_EXPR, "ObjectExpression", "objectExpression")
ASTDEF(AST_THIS_EXPR, "ThisExpression", "thisExpression")
ASTDEF(AST_GRAPH_EXPR, "GraphExpression", "graphExpression")
ASTDEF(AST_GRAPH_IDX_EXPR, "GraphIndexExpression", "graphIndexExpression")
ASTDEF(AST_COMP_EXPR, "ComprehensionExpression", "comprehensionExpression")
ASTDEF(AST_GENERATOR_EXPR, "GeneratorExpression", "generatorExpression")
ASTDEF(AST_YIELD_EXPR, "YieldExpression", "yieldExpression")
ASTDEF(AST_LET_EXPR, "LetExpression", "letExpression")
ASTDEF(AST_LIST_EXPR, "SequenceExpression")
ASTDEF(AST_COND_EXPR, "ConditionalExpression")
ASTDEF(AST_UNARY_EXPR, "UnaryExpression")
ASTDEF(AST_BINARY_EXPR, "BinaryExpression")
ASTDEF(AST_ASSIGN_EXPR, "AssignmentExpression")
ASTDEF(AST_LOGICAL_EXPR, "LogicalExpression")
ASTDEF(AST_UPDATE_EXPR, "UpdateExpression")
ASTDEF(AST_NEW_EXPR, "NewExpression")
ASTDEF(AST_CALL_EXPR, "CallExpression")
ASTDEF(AST_MEMBER_EXPR, "MemberExpression")
ASTDEF(AST_FUNC_EXPR, "FunctionExpression")
ASTDEF(AST_ARRAY_EXPR, "ArrayExpression")
ASTDEF(AST_OBJECT_EXPR, "ObjectExpression")
ASTDEF(AST_THIS_EXPR, "ThisExpression")
ASTDEF(AST_GRAPH_EXPR, "GraphExpression")
ASTDEF(AST_GRAPH_IDX_EXPR, "GraphIndexExpression")
ASTDEF(AST_COMP_EXPR, "ComprehensionExpression")
ASTDEF(AST_GENERATOR_EXPR, "GeneratorExpression")
ASTDEF(AST_YIELD_EXPR, "YieldExpression")
ASTDEF(AST_LET_EXPR, "LetExpression")
ASTDEF(AST_EMPTY_STMT, "EmptyStatement", "emptyStatement")
ASTDEF(AST_BLOCK_STMT, "BlockStatement", "blockStatement")
ASTDEF(AST_EXPR_STMT, "ExpressionStatement", "expressionStatement")
ASTDEF(AST_LAB_STMT, "LabeledStatement", "labeledStatement")
ASTDEF(AST_IF_STMT, "IfStatement", "ifStatement")
ASTDEF(AST_SWITCH_STMT, "SwitchStatement", "switchStatement")
ASTDEF(AST_WHILE_STMT, "WhileStatement", "whileStatement")
ASTDEF(AST_DO_STMT, "DoWhileStatement", "doWhileStatement")
ASTDEF(AST_FOR_STMT, "ForStatement", "forStatement")
ASTDEF(AST_FOR_IN_STMT, "ForInStatement", "forInStatement")
ASTDEF(AST_BREAK_STMT, "BreakStatement", "breakStatement")
ASTDEF(AST_CONTINUE_STMT, "ContinueStatement", "continueStatement")
ASTDEF(AST_WITH_STMT, "WithStatement", "withStatement")
ASTDEF(AST_RETURN_STMT, "ReturnStatement", "returnStatement")
ASTDEF(AST_TRY_STMT, "TryStatement", "tryStatement")
ASTDEF(AST_THROW_STMT, "ThrowStatement", "throwStatement")
ASTDEF(AST_DEBUGGER_STMT, "DebuggerStatement", "debuggerStatement")
ASTDEF(AST_LET_STMT, "LetStatement", "letStatement")
ASTDEF(AST_EMPTY_STMT, "EmptyStatement")
ASTDEF(AST_BLOCK_STMT, "BlockStatement")
ASTDEF(AST_EXPR_STMT, "ExpressionStatement")
ASTDEF(AST_LAB_STMT, "LabeledStatement")
ASTDEF(AST_IF_STMT, "IfStatement")
ASTDEF(AST_SWITCH_STMT, "SwitchStatement")
ASTDEF(AST_WHILE_STMT, "WhileStatement")
ASTDEF(AST_DO_STMT, "DoWhileStatement")
ASTDEF(AST_FOR_STMT, "ForStatement")
ASTDEF(AST_FOR_IN_STMT, "ForInStatement")
ASTDEF(AST_BREAK_STMT, "BreakStatement")
ASTDEF(AST_CONTINUE_STMT, "ContinueStatement")
ASTDEF(AST_WITH_STMT, "WithStatement")
ASTDEF(AST_RETURN_STMT, "ReturnStatement")
ASTDEF(AST_TRY_STMT, "TryStatement")
ASTDEF(AST_THROW_STMT, "ThrowStatement")
ASTDEF(AST_DEBUGGER_STMT, "DebuggerStatement")
ASTDEF(AST_LET_STMT, "LetStatement")
ASTDEF(AST_CASE, "SwitchCase", "switchCase")
ASTDEF(AST_CATCH, "CatchClause", "catchClause")
ASTDEF(AST_COMP_BLOCK, "ComprehensionBlock", "comprehensionBlock")
ASTDEF(AST_CASE, "SwitchCase")
ASTDEF(AST_CATCH, "CatchClause")
ASTDEF(AST_COMP_BLOCK, "ComprehensionBlock")
ASTDEF(AST_ARRAY_PATT, "ArrayPattern", "arrayPattern")
ASTDEF(AST_OBJECT_PATT, "ObjectPattern", "objectPattern")
ASTDEF(AST_PROP_PATT, "Property", "propertyPattern")
ASTDEF(AST_ARRAY_PATT, "ArrayPattern")
ASTDEF(AST_OBJECT_PATT, "ObjectPattern")
ASTDEF(AST_XMLANYNAME, "XMLAnyName", "xmlAnyName")
ASTDEF(AST_XMLATTR_SEL, "XMLAttributeSelector", "xmlAttributeSelector")
ASTDEF(AST_XMLESCAPE, "XMLEscape", "xmlEscape")
ASTDEF(AST_XMLFILTER, "XMLFilterExpression", "xmlFilterExpression")
ASTDEF(AST_XMLDEFAULT, "XMLDefaultDeclaration", "xmlDefaultDeclaration")
ASTDEF(AST_XMLQUAL, "XMLQualifiedIdentifier", "xmlQualifiedIdentifier")
ASTDEF(AST_XMLFUNCQUAL, "XMLFunctionQualifiedIdentifier", "xmlFunctionQualifiedIdentifier")
ASTDEF(AST_XMLELEM, "XMLElement", "xmlElement")
ASTDEF(AST_XMLTEXT, "XMLText", "xmlText")
ASTDEF(AST_XMLLIST, "XMLList", "xmlList")
ASTDEF(AST_XMLSTART, "XMLStartTag", "xmlStartTag")
ASTDEF(AST_XMLEND, "XMLEndTag", "xmlEndTag")
ASTDEF(AST_XMLPOINT, "XMLPointTag", "xmlPointTag")
ASTDEF(AST_XMLNAME, "XMLName", "xmlName")
ASTDEF(AST_XMLATTR, "XMLAttribute", "xmlAttribute")
ASTDEF(AST_XMLCDATA, "XMLCdata", "xmlCdata")
ASTDEF(AST_XMLCOMMENT, "XMLComment", "xmlComment")
ASTDEF(AST_XMLPI, "XMLProcessingInstruction", "xmlProcessingInstruction")
ASTDEF(AST_XMLANYNAME, "XMLAnyName")
ASTDEF(AST_XMLATTR_SEL, "XMLAttributeSelector")
ASTDEF(AST_XMLESCAPE, "XMLEscape")
ASTDEF(AST_XMLFILTER, "XMLFilterExpression")
ASTDEF(AST_XMLDEFAULT, "XMLDefaultDeclaration")
ASTDEF(AST_XMLQUAL, "XMLQualifiedIdentifier")
ASTDEF(AST_XMLFUNCQUAL, "XMLFunctionQualifiedIdentifier")
ASTDEF(AST_XMLELEM, "XMLElement")
ASTDEF(AST_XMLTEXT, "XMLText")
ASTDEF(AST_XMLLIST, "XMLList")
ASTDEF(AST_XMLSTART, "XMLStartTag")
ASTDEF(AST_XMLEND, "XMLEndTag")
ASTDEF(AST_XMLPOINT, "XMLPointTag")
ASTDEF(AST_XMLNAME, "XMLName")
ASTDEF(AST_XMLATTR, "XMLAttribute")
ASTDEF(AST_XMLCDATA, "XMLCdata")
ASTDEF(AST_XMLCOMMENT, "XMLComment")
ASTDEF(AST_XMLPI, "XMLProcessingInstruction")
/* AST_LIMIT = last + 1 */

View File

@ -183,7 +183,6 @@ const char *const js_common_atom_names[] = {
"line", /* lineAtom */
"Infinity", /* InfinityAtom */
"NaN", /* NaNAtom */
"builder", /* builderAtom */
#if JS_HAS_XML_SUPPORT
js_etago_str, /* etagoAtom */

View File

@ -375,7 +375,6 @@ struct JSAtomState
JSAtom *lineAtom;
JSAtom *InfinityAtom;
JSAtom *NaNAtom;
JSAtom *builderAtom;
#if JS_HAS_XML_SUPPORT
JSAtom *etagoAtom;

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,7 @@ namespace js {
enum ASTType {
AST_ERROR = -1,
#define ASTDEF(ast, str, method) ast,
#define ASTDEF(ast, str) ast,
#include "jsast.tbl"
#undef ASTDEF
AST_LIMIT

View File

@ -116,8 +116,8 @@ function assertBlockExpr(src, patt) {
assertBlockStmt(src, exprStmt(patt));
}
function assertBlockDecl(src, patt, builder) {
blockPatt(patt).assert(Reflect.parse(blockSrc(src), {builder: builder}));
function assertBlockDecl(src, patt) {
blockPatt(patt).assert(Reflect.parse(blockSrc(src)));
}
function assertLocalStmt(src, patt) {
@ -132,13 +132,12 @@ function assertLocalDecl(src, patt) {
localPatt(patt).assert(Reflect.parse(localSrc(src)));
}
function assertGlobalStmt(src, patt, builder) {
program([patt]).assert(Reflect.parse(src, {builder: builder}));
function assertGlobalStmt(src, patt) {
program([patt]).assert(Reflect.parse(src));
}
function assertGlobalExpr(src, patt, builder) {
program([exprStmt(patt)]).assert(Reflect.parse(src, {builder: builder}));
//assertStmt(src, exprStmt(patt));
function assertGlobalExpr(src, patt) {
assertStmt(src, exprStmt(patt));
}
function assertGlobalDecl(src, patt) {
@ -172,7 +171,6 @@ function assertError(src, errorType) {
throw new Error("expected " + errorType.name + " for " + uneval(src));
}
// general tests
// NB: These are useful but for now jit-test doesn't do I/O reliably.
@ -291,17 +289,17 @@ assertExpr("[]", arrExpr([]));
assertExpr("[1]", arrExpr([lit(1)]));
assertExpr("[1,2]", arrExpr([lit(1),lit(2)]));
assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)]));
assertExpr("[1,,2,3]", arrExpr([lit(1),,lit(2),lit(3)]));
assertExpr("[1,,,2,3]", arrExpr([lit(1),,,lit(2),lit(3)]));
assertExpr("[1,,,2,,3]", arrExpr([lit(1),,,lit(2),,lit(3)]));
assertExpr("[1,,,2,,,3]", arrExpr([lit(1),,,lit(2),,,lit(3)]));
assertExpr("[,1,2,3]", arrExpr([,lit(1),lit(2),lit(3)]));
assertExpr("[,,1,2,3]", arrExpr([,,lit(1),lit(2),lit(3)]));
assertExpr("[,,,1,2,3]", arrExpr([,,,lit(1),lit(2),lit(3)]));
assertExpr("[,,,1,2,3,]", arrExpr([,,,lit(1),lit(2),lit(3)]));
assertExpr("[,,,1,2,3,,]", arrExpr([,,,lit(1),lit(2),lit(3),]));
assertExpr("[,,,1,2,3,,,]", arrExpr([,,,lit(1),lit(2),lit(3),,]));
assertExpr("[,,,,,]", arrExpr([,,,,]));
assertExpr("[1,,2,3]", arrExpr([lit(1),null,lit(2),lit(3)]));
assertExpr("[1,,,2,3]", arrExpr([lit(1),null,null,lit(2),lit(3)]));
assertExpr("[1,,,2,,3]", arrExpr([lit(1),null,null,lit(2),null,lit(3)]));
assertExpr("[1,,,2,,,3]", arrExpr([lit(1),null,null,lit(2),null,null,lit(3)]));
assertExpr("[,1,2,3]", arrExpr([null,lit(1),lit(2),lit(3)]));
assertExpr("[,,1,2,3]", arrExpr([null,null,lit(1),lit(2),lit(3)]));
assertExpr("[,,,1,2,3]", arrExpr([null,null,null,lit(1),lit(2),lit(3)]));
assertExpr("[,,,1,2,3,]", arrExpr([null,null,null,lit(1),lit(2),lit(3)]));
assertExpr("[,,,1,2,3,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null]));
assertExpr("[,,,1,2,3,,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null,null]));
assertExpr("[,,,,,]", arrExpr([null,null,null,null,null]));
assertExpr("({})", objExpr([]));
assertExpr("({x:1})", objExpr([{ key: ident("x"), value: lit(1) }]));
assertExpr("({x:1, y:2})", objExpr([{ key: ident("x"), value: lit(1) },
@ -908,315 +906,4 @@ assertEq(Reflect.parse("42", {loc:false}).loc, null);
program([exprStmt(lit(42))]).assert(Reflect.parse("42", {loc:false}));
// Builder tests
Pattern("program").match(Reflect.parse("42", {builder:{program:function()"program"}}));
assertGlobalStmt("throw 42", 1, { throwStatement: function() 1 });
assertGlobalStmt("for (;;);", 2, { forStatement: function() 2 });
assertGlobalStmt("for (x in y);", 3, { forInStatement: function() 3 });
assertGlobalStmt("{ }", 4, { blockStatement: function() 4 });
assertGlobalStmt("foo: { }", 5, { labeledStatement: function() 5 });
assertGlobalStmt("with (o) { }", 6, { withStatement: function() 6 });
assertGlobalStmt("while (x) { }", 7, { whileStatement: function() 7 });
assertGlobalStmt("do { } while(false);", 8, { doWhileStatement: function() 8 });
assertGlobalStmt("switch (x) { }", 9, { switchStatement: function() 9 });
assertGlobalStmt("try { } catch(e) { }", 10, { tryStatement: function() 10 });
assertGlobalStmt(";", 11, { emptyStatement: function() 11 });
assertGlobalStmt("debugger;", 12, { debuggerStatement: function() 12 });
assertGlobalStmt("42;", 13, { expressionStatement: function() 13 });
assertGlobalStmt("for (;;) break", forStmt(null, null, null, 14), { breakStatement: function() 14 });
assertGlobalStmt("for (;;) continue", forStmt(null, null, null, 15), { continueStatement: function() 15 });
assertBlockDecl("var x", "var", { variableDeclaration: function(kind) kind });
assertBlockDecl("let x", "let", { variableDeclaration: function(kind) kind });
assertBlockDecl("const x", "const", { variableDeclaration: function(kind) kind });
assertBlockDecl("function f() { }", "function", { functionDeclaration: function() "function" });
assertGlobalExpr("(x,y,z)", 1, { sequenceExpression: function() 1 });
assertGlobalExpr("(x ? y : z)", 2, { conditionalExpression: function() 2 });
assertGlobalExpr("x + y", 3, { binaryExpression: function() 3 });
assertGlobalExpr("delete x", 4, { unaryExpression: function() 4 });
assertGlobalExpr("x = y", 5, { assignmentExpression: function() 5 });
assertGlobalExpr("x || y", 6, { logicalExpression: function() 6 });
assertGlobalExpr("x++", 7, { updateExpression: function() 7 });
assertGlobalExpr("new x", 8, { newExpression: function() 8 });
assertGlobalExpr("x()", 9, { callExpression: function() 9 });
assertGlobalExpr("x.y", 10, { memberExpression: function() 10 });
assertGlobalExpr("(function() { })", 11, { functionExpression: function() 11 });
assertGlobalExpr("[1,2,3]", 12, { arrayExpression: function() 12 });
assertGlobalExpr("({ x: y })", 13, { objectExpression: function() 13 });
assertGlobalExpr("this", 14, { thisExpression: function() 14 });
assertGlobalExpr("#1={ }", 15, { graphExpression: function() 15 });
assertGlobalExpr("#1={ self: #1# }", graphExpr(1, objExpr([{ key: ident("self"), value: 16 }])), { graphIndexExpression: function() 16 });
assertGlobalExpr("[x for (x in y)]", 17, { comprehensionExpression: function() 17 });
assertGlobalExpr("(x for (x in y))", 18, { generatorExpression: function() 18 });
assertGlobalExpr("(function() { yield 42 })", genFunExpr(null, [], blockStmt([exprStmt(19)])), { yieldExpression: function() 19 });
assertGlobalExpr("(let (x) x)", 20, { letExpression: function() 20 });
assertGlobalStmt("switch (x) { case y: }", switchStmt(ident("x"), [1]), { switchCase: function() 1 });
assertGlobalStmt("try { } catch (e) { }", tryStmt(blockStmt([]), 2, null), { catchClause: function() 2 });
assertGlobalStmt("try { } catch (e if e instanceof A) { } catch (e if e instanceof B) { }",
tryStmt(blockStmt([]), [2, 2], null),
{ catchClause: function() 2 });
assertGlobalExpr("[x for (y in z) for (x in y)]", compExpr(ident("x"), [3, 3], null), { comprehensionBlock: function() 3 });
assertGlobalExpr("({ x: y } = z)", aExpr("=", 1, ident("z")), { objectPattern: function() 1 });
assertGlobalExpr("({ x: y } = z)", aExpr("=", objPatt([2]), ident("z")), { propertyPattern: function() 2 });
assertGlobalExpr("[ x ] = y", aExpr("=", 3, ident("y")), { arrayPattern: function() 3 });
assertGlobalExpr("({a:x::y}) = foo", aExpr("=", singletonObjPatt("a", 1), ident("foo")), { xmlQualifiedIdentifier: function() 1 });
assertGlobalExpr("({a:function::x}) = foo", aExpr("=", singletonObjPatt("a", 2), ident("foo")), { xmlFunctionQualifiedIdentifier: function() 2 });
assertGlobalExpr("({a:@x}) = foo", aExpr("=", singletonObjPatt("a", 3), ident("foo")), { xmlAttributeSelector: function() 3 });
assertGlobalExpr("({a:x.*}) = foo", aExpr("=", singletonObjPatt("a", memExpr(ident("x"), 4)), ident("foo")), { xmlAnyName: function() 4 });
assertGlobalExpr("(<x> </x>)()", callExpr(xmlElt([5, xmlText(" "), xmlEndTag([xmlName("x")])]), []), { xmlStartTag: function() 5 });
assertGlobalExpr("(<x> </x>)()", callExpr(xmlElt([xmlStartTag([6]), xmlText(" "), xmlEndTag([6])]), []), { xmlName: function() 6 });
assertGlobalExpr("(<x> </x>)()", callExpr(xmlElt([xmlStartTag([xmlName("x")]), 7, xmlEndTag([xmlName("x")])]), []), { xmlText: function() 7 });
assertGlobalExpr("(<x> </x>)()", callExpr(xmlElt([xmlStartTag([xmlName("x")]), xmlText(" "), 8]), []), { xmlEndTag: function() 8 });
assertGlobalExpr("(<x><![CDATA[hello, world]]></x>)()", callExpr(xmlElt([xmlStartTag([xmlName("x")]), 9, xmlEndTag([xmlName("x")])]), []), { xmlCdata: function() 9 });
assertGlobalExpr("(<x><!-- hello, world --></x>)()", callExpr(xmlElt([xmlStartTag([xmlName("x")]), 10, xmlEndTag([xmlName("x")])]), []), { xmlComment: function() 10 });
// Ensure that exceptions thrown by builder methods propagate.
var thrown = false;
try {
Reflect.parse("42", { builder: { program: function() { throw "expected" } } });
} catch (e if e === "expected") {
thrown = true;
}
if (!thrown)
throw new Error("builder exception not propagated");
// A simple proof-of-concept that the builder API can be used to generate other
// formats, such as JsonMLAst:
//
// http://code.google.com/p/es-lab/wiki/JsonMLASTFormat
//
// It's incomplete (e.g., it doesn't convert source-location information and
// doesn't use all the direct-eval rules), but I think it proves the point.
var JsonMLAst = (function() {
function reject() {
throw new SyntaxError("node type not supported");
}
function isDirectEval(expr) {
// an approximation to the actual rules. you get the idea
return (expr[0] === "IdExpr" && expr[1].name === "eval");
}
function functionNode(type) {
return function(id, args, body, isGenerator, isExpression) {
if (isExpression)
body = ["ReturnStmt", {}, body];
if (!id)
id = ["Empty"];
// Patch up the argument node types: s/IdExpr/IdPatt/g
for (var i = 0; i < args.length; i++) {
args[i][0] = "IdPatt";
}
args.unshift("ParamDecl", {});
return [type, {}, id, args, body];
}
}
return {
program: function(stmts) {
stmts.unshift("Program", {});
return stmts;
},
identifier: function(name) {
return ["IdExpr", { name: name }];
},
literal: function(val) {
return ["LiteralExpr", { value: val }];
},
expressionStatement: function(expr) expr,
conditionalExpression: function(test, cons, alt) {
return ["ConditionalExpr", {}, test, cons, alt];
},
unaryExpression: function(op, expr) {
return ["UnaryExpr", {op: op}, expr];
},
binaryExpression: function(op, left, right) {
return ["BinaryExpr", {op: op}, left, right];
},
property: function(kind, key, val) {
return [kind === "init"
? "DataProp"
: kind === "get"
? "GetterProp"
: "SetterProp",
{name: key[1].name}, val];
},
functionDeclaration: functionNode("FunctionDecl"),
variableDeclaration: function(kind, elts) {
if (kind === "let" || kind === "const")
throw new SyntaxError("let and const not supported");
elts.unshift("VarDecl", {});
return elts;
},
variableDeclarator: function(id, init) {
id[0] = "IdPatt";
if (!init)
return id;
return ["InitPatt", {}, id, init];
},
sequenceExpression: function(exprs) {
var length = exprs.length;
var result = ["BinaryExpr", {op:","}, exprs[exprs.length - 2], exprs[exprs.length - 1]];
for (var i = exprs.length - 3; i >= 0; i--) {
result = ["BinaryExpr", {op:","}, exprs[i], result];
}
return result;
},
assignmentExpression: function(op, lhs, expr) {
return ["AssignExpr", {op: op}, lhs, expr];
},
logicalExpression: function(op, left, right) {
return [op === "&&" ? "LogicalAndExpr" : "LogicalOrExpr", {}, left, right];
},
updateExpression: function(expr, op, isPrefix) {
return ["CountExpr", {isPrefix:isPrefix, op:op}, expr];
},
newExpression: function(callee, args) {
args.unshift("NewExpr", {}, callee);
return args;
},
callExpression: function(callee, args) {
args.unshift(isDirectEval(callee) ? "EvalExpr" : "CallExpr", {}, callee);
return args;
},
memberExpression: function(isComputed, expr, member) {
return ["MemberExpr", {}, expr, isComputed ? member : ["LiteralExpr", {type: "string", value: member[1].name}]];
},
functionExpression: functionNode("FunctionExpr"),
arrayExpression: function(elts) {
for (var i = 0; i < elts.length; i++) {
if (!elts[i])
elts[i] = ["Empty"];
}
elts.unshift("ArrayExpr", {});
return elts;
},
objectExpression: function(props) {
props.unshift("ObjectExpr", {});
return props;
},
thisExpression: function() {
return ["ThisExpr", {}];
},
graphExpression: reject,
graphIndexExpression: reject,
comprehensionExpression: reject,
generatorExpression: reject,
yieldExpression: reject,
letExpression: reject,
emptyStatement: function() ["EmptyStmt", {}],
blockStatement: function(stmts) {
stmts.unshift("BlockStmt", {});
return stmts;
},
labeledStatement: function(lab, stmt) {
return ["LabelledStmt", {label: lab}, stmt];
},
ifStatement: function(test, cons, alt) {
return ["IfStmt", {}, test, cons, alt || ["EmptyStmt", {}]];
},
switchStatement: function(test, clauses, isLexical) {
clauses.unshift("SwitchStmt", {}, test);
return clauses;
},
whileStatement: function(expr, stmt) {
return ["WhileStmt", {}, expr, stmt];
},
doWhileStatement: function(stmt, expr) {
return ["DoWhileStmt", {}, stmt, expr];
},
forStatement: function(init, test, update, body) {
return ["ForStmt", {}, init || ["Empty"], test || ["Empty"], update || ["Empty"], body];
},
forInStatement: function(lhs, rhs, body) {
return ["ForInStmt", {}, lhs, rhs, body];
},
breakStatement: function(lab) {
return lab ? ["BreakStmt", {}, lab] : ["BreakStmt", {}];
},
continueStatement: function(lab) {
return lab ? ["ContinueStmt", {}, lab] : ["ContinueStmt", {}];
},
withStatement: function(expr, stmt) {
return ["WithStmt", {}, expr, stmt];
},
returnStatement: function(expr) {
return expr ? ["ReturnStmt", {}, expr] : ["ReturnStmt", {}];
},
tryStatement: function(body, catches, fin) {
if (catches.length > 1)
throw new SyntaxError("multiple catch clauses not supported");
var node = ["TryStmt", body, catches[0] || ["Empty"]];
if (fin)
node.push(fin);
return node;
},
throwStatement: function(expr) {
return ["ThrowStmt", {}, expr];
},
debuggerStatement: function() ["DebuggerStmt", {}],
letStatement: reject,
switchCase: function(expr, stmts) {
if (expr)
stmts.unshift("SwitchCase", {}, expr);
else
stmts.unshift("DefaultCase", {});
return stmts;
},
catchClause: function(param, guard, body) {
if (guard)
throw new SyntaxError("catch guards not supported");
param[0] = "IdPatt";
return ["CatchClause", {}, param, body];
},
comprehensionBlock: reject,
arrayPattern: reject,
objectPattern: reject,
propertyPattern: reject,
xmlAnyName: reject,
xmlAttributeSelector: reject,
xmlEscape: reject,
xmlFilterExpression: reject,
xmlDefaultDeclaration: reject,
xmlQualifiedIdentifier: reject,
xmlFunctionQualifiedIdentifier: reject,
xmlElement: reject,
xmlText: reject,
xmlList: reject,
xmlStartTag: reject,
xmlEndTag: reject,
xmlPointTag: reject,
xmlName: reject,
xmlAttribute: reject,
xmlCdata: reject,
xmlComment: reject,
xmlProcessingInstruction: reject
};
})();
Pattern(["Program", {},
["BinaryExpr", {op: "+"},
["LiteralExpr", {value: 2}],
["BinaryExpr", {op: "*"},
["UnaryExpr", {op: "-"}, ["IdExpr", {name: "x"}]],
["IdExpr", {name: "y"}]]]]).match(Reflect.parse("2 + (-x * y)", {loc: false, builder: JsonMLAst}));
reportCompare(true, true);