Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: utils/astml.js

Issue 29350140: Issue 4353 - Remove non standard for each syntax (Closed)
Left Patch Set: Created Aug. 24, 2016, 11:08 a.m.
Right Patch Set: Removed unused code Created Aug. 24, 2016, 2:40 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « scripts/outASTML.js ('k') | utils/cleanast.js » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Output an JsonML codec for the AST
2
3 // Explanation of a node:
4 // {
5 // type: The type of the node
6 // location: "line:col-line:col"
7 // }
8 /**
9 * Node formats:
10 * Program
11 * sourceElements: Array of elements (functions, statements)
12 * FunctionDeclaration
13 * name: Name of the function
14 * arguments: Array of arguments
15 * body: Array of elements in function body
16 * VarStatement
17 * variables: Variables being initialized
18 * VarDeclaration
19 * name: Name of variable
20 * initializer: Initial value of variable
21 * CallExpression
22 * func: Name of the function being called
23 * arguments: Array of arguments
24 * IdentifierExpression
25 * name: Name of identifier
26 * LiteralExpression
27 * objtype: "null", "boolean", "numeric", "string", "regex"
28 * value: Value of the literal
29 * BinaryExpression
30 * operator: operator (e.g., '|', '+')
31 + lhs, rhs: left-hand, right-hand expressions for the operator
32 */
33 include("../utils/dumpast.js");
34
35 function makeAST(pn) {
36 let ast = shellNode(pn, "Program");
37 ast.sourceElements = parseToAst(pn).statements;
38 return ast;
39 }
40
41 // Broken things:
42 // * Generators (i for (i in foo), not array comp)
43 // * let {a: x, b: y} = baz();
44 // * let (x = 5, y = 12) {} (really!)
45 // * function ( {a: 1, b: 2} )
46 // * E4x
47
48 let structure = {
49 // Program : SourceElement*
50 "Program": [ "sourceElements" ],
51 // SourceElement : FunctionDeclaration | Statement
52 // FunctionDeclaration : function [name] ( Parameter * ) { SourceElement * }
53 "FunctionDeclaration": [ "arguments", "body" ],
54 "Parameter": [ ], // name: Parameter name
55
56 // Statements
57 "BlockStatement": [ "statements" ],
58 "VarStatement": [ "variables" ],
59 "VarDeclaration": [ "initializer" ], // name: name of variable
60 "LetStatement": [ "variables", "body" ],
61 "EmptyStatement": [],
62 "ExpressionStatement": [ "expr" ],
63 "IfStatement": [ "cond", "body", "elsebody" ],
64 "DoWhileStatement": [ "cond", "body" ],
65 "WhileStatement": [ "cond", "body" ],
66 "ForStatement": [ "init", "cond", "inc", "body" ],
67 "ForInStatement": [ "itervar", "iterrange", "body" ], // itertype: for (each)
68 "ContinueStatement": [ ], // label: label to break to
69 "BreakStatement": [ ], // label: label to break to
70 "ReturnStatement": [ "expr" ],
71 "WithStatement": [ "variable", "body" ],
72 "LabeledStatement": [ "body" ], // label: label of statement
73 "SwitchStatement": [ "expr", "cases" ],
74 "SwitchCase": [ "expr", "body"], // default: no expr
75 "ThrowStatement": [ "expr" ],
76 "TryStatement": [ "body", "catchers", "fin" ],
77 "CatchStatement": [ "variable", "cond", "body" ],
78 "DebuggerStatement": [ ],
79
80 // Expressions (all have a precedence attribute, 0 (primary) -17)
81 "ThisExpression": [],
82 "LiteralExpression": [], // objtype: typeof literal, value: value
83 "ObjectLiteral": [ "setters" ],
84 "PropertyLiteral": [ "property", "value" ], // proptype: getter, setter, not
85 "ArrayLiteral": [ "members" ],
86 "ArrayComprehensionExpression": [ "element", "itervar", "iterrange",
87 "iterif" ], // itertype
88 "IdentifierExpression": [], // name: name of node
89 "MemberExpression": [ "container", "member"], //constmember if constant
90 "NewExpression": [ "constructor", "arguments" ],
91 "CallExpression": [ "func", "arguments" ],
92 "PostfixExpression": [ "operand" ], // operator
93 // XXX: jorendorff says yield is weird precedence
94 // For now, it's an unary with precedence = 16
95 "UnaryExpression": [ "operand" ], // operator
96 "BinaryExpression": [ "lhs", "rhs" ], // operator
97 "ConditionalExpression": [ "cond", "iftrue", "iffalse" ],
98 "AssignmentExpression": [ "lhs", "rhs" ], // operator
99 };
100 function walkAST(ast, visitor) {
101 function astVisitor(node) {
102 let info = structure[node.type];
103 if (!info)
104 throw "Need to define " + node.type;
105 let cback = "visit" + node.type;
106 let deep = false;
107 if (cback in visitor)
108 deep = visitor[cback](node);
109 if (!deep) {
110 for (let part of info) {
111 let piece = node[part];
112 if (piece instanceof Array) {
113 piece.map(astVisitor);
114 } else if (piece) {
115 astVisitor(piece);
116 }
117 }
118 }
119 cback = "post" + cback;
120 if (cback in visitor)
121 visitor[cback](node);
122 }
123 astVisitor(ast);
124 }
125
126 function getLocation(pn) {
127 return pn.line + ":" + pn.column;
128 }
129 function shellNode(pn, type) {
130 function visit(visitor) {
131 return walkAST(this, visitor);
132 }
133 return {type: type, location: getLocation(pn), visit: visit };
134 }
135 function binaryNode(pn, operator, precedence) {
136 let ast = shellNode(pn, "BinaryExpression");
137 ast.precedence = precedence;
138 ast.operator = operator;
139 ast.lhs = parseToAst(pn.kids[0]);
140 ast.rhs = parseToAst(pn.kids[1]);
141 for (let i = 2; i < pn.kids.length; i++) {
142 let sup = shellNode(pn.kids[i], "BinaryExpression");
143 sup.precedence = precedence;
144 sup.operator = operator;
145 sup.lhs = ast;
146 sup.rhs = parseToAst(pn.kids[i]);
147 ast = sup;
148 }
149 return ast;
150 }
151
152 function parseToAst(pn) {
153 if (!pn)
154 return pn;
155 try {
156 return global["convert" + decode_type(pn.type)](pn);
157 } catch (e if e instanceof TypeError) {
158 dump_ast(pn);
159 throw e;
160 //throw "Unexpected token " + decode_type(pn.type);
161 }
162 }
163
164 // Nodes that I don't see in output
165 // TOK_ERROR, TOK_EOL, TOK_ELSE, TOK_FINALLY, TOK_SEQ
166 // TOK_XMLSTAGO - TOK_XMLLIST are XML and thus ignored
167
168 function convertTOK_SEMI(pn) {
169 let ast = shellNode(pn, "ExpressionStatement");
170 if (pn.kids[0])
171 ast.expr = parseToAst(pn.kids[0]);
172 else {
173 ast.type = "EmptyStatement";
174 }
175 return ast;
176 }
177
178 function convertTOK_COMMA(pn) {
179 if (pn.kids.length == 0) {
180 let ast = shellNode(pn, "EmptyExpression");
181 ast.precedence = 17;
182 return ast;
183 } else {
184 return binaryNode(pn, ",", 17);
185 }
186 }
187
188 function convertTOK_ASSIGN(pn) {
189 let ast = shellNode(pn, "AssignmentExpression");
190 ast.precedence = 16;
191 ast.lhs = parseToAst(pn.kids[0]);
192 ast.rhs = parseToAst(pn.kids[1]);
193 switch (pn.op) {
194 case JSOP_NOP: ast.operator = ''; break;
195 case JSOP_BITOR: ast.operator = '|'; break;
196 case JSOP_BITXOR: ast.operator = '^'; break;
197 case JSOP_BITAND: ast.operator = '&'; break;
198 case JSOP_LSH: ast.operator = '<<'; break;
199 case JSOP_RSH: ast.operator = '>>'; break;
200 case JSOP_URSH: ast.operator = '>>>'; break;
201 case JSOP_ADD: ast.operator = '+'; break;
202 case JSOP_SUB: ast.operator = '-'; break;
203 case JSOP_MUL: ast.operator = '*'; break;
204 case JSOP_DIV: ast.operator = '/'; break;
205 case JSOP_MOD: ast.operator = '%'; break;
206 default: throw "Unexpected operator " + decode_op(pn.op);
207 };
208 return ast;
209 }
210
211 function convertTOK_HOOK(pn) {
212 let ast = shellNode(pn, "ConditionalExpression");
213 ast.precedence = 15;
214 ast.cond = parseToAst(pn.kids[0]);
215 ast.iftrue = parseToAst(pn.kids[1]);
216 ast.iffalse = parseToAst(pn.kids[2]);
217 return ast;
218 }
219
220 function convertTOK_COLON(pn) {
221 if (pn.kids.length == 1) {
222 let ast = shellNode(pn, "LabeledStatement");
223 ast.label = pn.atom;
224 ast.body = parseToAst(pn.kids[0]);
225 return ast;
226 }
227 let ast = shellNode(pn, "PropertyLiteral");
228 ast.property = parseToAst(pn.kids[0]);
229 ast.value = parseToAst(pn.kids[1]);
230 if (pn.op == JSOP_GETTER)
231 ast.proptype = "getter";
232 else if (pn.op == JSOP_SETTER)
233 ast.proptype = "setter";
234 return ast;
235 }
236
237 function convertTOK_OR(pn) { return binaryNode(pn, "||", 14); }
238 function convertTOK_AND(pn) { return binaryNode(pn, "&&", 13); }
239 function convertTOK_BITOR(pn) { return binaryNode(pn, "|", 12); }
240 function convertTOK_BITXOR(pn) { return binaryNode(pn, "^", 11); }
241 function convertTOK_BITAND(pn) { return binaryNode(pn, "&", 10); }
242 function convertTOK_EQOP(pn) {
243 switch (pn.op) {
244 case JSOP_EQ: return binaryNode(pn, "==", 9);
245 case JSOP_NE: return binaryNode(pn, "!=", 9);
246 case JSOP_STRICTEQ: return binaryNode(pn, "===", 9);
247 case JSOP_STRICTNE: return binaryNode(pn, "!==", 9);
248 }
249 throw "Unknown operator: " + decode_op(pn.op);
250 }
251 function convertTOK_RELOP(pn) {
252 switch (pn.op) {
253 case JSOP_LT: return binaryNode(pn, "<", 8);
254 case JSOP_LE: return binaryNode(pn, "<=", 8);
255 case JSOP_GT: return binaryNode(pn, ">", 8);
256 case JSOP_GE: return binaryNode(pn, ">=", 8);
257 }
258 throw "Unknown operator: " + decode_op(pn.op);
259 }
260 function convertTOK_SHOP(pn) {
261 switch (pn.op) {
262 case JSOP_LSH: return binaryNode(pn, "<<", 7);
263 case JSOP_RSH: return binaryNode(pn, ">>", 7);
264 case JSOP_URSH: return binaryNode(pn, ">>>", 7);
265 }
266 throw "Unknown operator: " + decode_op(pn.op);
267 }
268 function convertTOK_PLUS(pn) { return binaryNode(pn, "+", 6); }
269 function convertTOK_MINUS(pn) { return binaryNode(pn, "-", 6); }
270 function convertTOK_STAR(pn) { return binaryNode(pn, "*", 5); }
271 function convertTOK_DIVOP(pn) {
272 switch (pn.op) {
273 case JSOP_MUL: return binaryNode(pn, "*", 5);
274 case JSOP_DIV: return binaryNode(pn, "/", 5);
275 case JSOP_MOD: return binaryNode(pn, "%", 5);
276 }
277 throw "Unknown operator: " + decode_op(pn.op);
278 }
279 function convertTOK_UNARYOP(pn) {
280 let ast = shellNode(pn, "UnaryExpression");
281 ast.precedence = 4;
282 ast.operand = parseToAst(pn.kids[0]);
283 switch (pn.op) {
284 case JSOP_NEG: ast.operator = "-"; break;
285 case JSOP_POS: ast.operator = "+"; break;
286 case JSOP_NOT: ast.operator = "!"; break;
287 case JSOP_BITNOT: ast.operator = "~"; break;
288 case JSOP_TYPEOF: ast.operator = "typeof"; break;
289 case JSOP_VOID: ast.operator = "void"; break;
290 case JSOP_TYPEOFEXPR: ast.operator = "typeof"; break;
291 default:
292 throw "Unknown operator: " + decode_op(pn.op);
293 }
294 return ast;
295 }
296 function convertTOK_INC(pn) { return convertPrePost(pn, '++'); }
297 function convertTOK_DEC(pn) { return convertPrePost(pn, '--'); }
298 function convertPrePost(pn, op) {
299 let ast = shellNode(pn, "UnaryExpression");
300 ast.precedence = 3;
301 ast.operator = op;
302 ast.operand = parseToAst(pn.kids[0]);
303 switch (pn.op) {
304 case JSOP_INCNAME:
305 case JSOP_INCPROP:
306 case JSOP_INCELEM:
307 case JSOP_DECNAME:
308 case JSOP_DECPROP:
309 case JSOP_DECELEM:
310 /*ast.type = "PrefixExpression";*/ break;
311 case JSOP_NAMEINC:
312 case JSOP_PROPINC:
313 case JSOP_ELEMINC:
314 case JSOP_NAMEDEC:
315 case JSOP_PROPDEC:
316 case JSOP_ELEMDEC:
317 ast.type = "PostfixExpression"; break;
318 default:
319 throw "Unknown operator: " + decode_op(pn.op);
320 }
321 return ast;
322 }
323
324 function convertTOK_DOT(pn) {
325 let ast = shellNode(pn, "MemberExpression");
326 ast.precedence = 1;
327 ast.container = parseToAst(pn.kids[0]);
328 ast.member = shellNode(pn, "LiteralExpression");
329 ast.member.objtype = "string";
330 ast.member.value = pn.atom;
331 ast.constmember = pn.atom;
332 return ast;
333 }
334
335 function convertTOK_LB(pn) {
336 let ast = shellNode(pn, "MemberExpression");
337 ast.precedence = 1;
338 ast.container = parseToAst(pn.kids[0]);
339 ast.member = parseToAst(pn.kids[1]);
340 return ast;
341 }
342
343 function convertTOK_RB(pn) {
344 let ast = shellNode(pn, "ArrayLiteral");
345 ast.precedence = 0;
346 ast.members = pn.kids.map(parseToAst);
347 return ast;
348 }
349
350 /* Returns a list */
351 function convertTOK_LC(pn) {
352 let ast = shellNode(pn, "BlockStatement");
353 ast.statements = pn.kinds.map(parseToAst);
354 if (ast.statements.length == 0) {
355 return shellNode(pn, "EmptyStatement");
356 }
357 return ast;
358 }
359
360 function convertTOK_RC(pn) {
361 let ast = shellNode(pn, "ObjectLiteral");
362 ast.setters = pn.kids.map(parseToAst);
363 return ast;
364 }
365
366 function convertTOK_LP(pn) {
367 if (pn.op != JSOP_CALL && pn.op != JSOP_APPLY) {
368 let ast = shellNode(pn, "LetStatement");
369 ast.variables = pn.kids.map(parseToAst);
370 return ast;
371 }
372 let ast = shellNode(pn, "CallExpression");
373 ast.precedence = 2;
374 ast.func = parseToAst(pn.kids[0]);
375 ast.arguments = [];
376 for (let i = 1; i < pn.kids.length; i++)
377 ast.arguments[i - 1] = parseToAst(pn.kids[i]);
378 return ast;
379 }
380
381 function convertTOK_RP(pn) {
382 let ast = shellNode(pn, "UnaryExpression");
383 ast.precedence = 2;
384 ast.operand = parseToAst(pn.kids[0]);
385 ast.operator = "()";
386 return ast;
387 }
388
389 function convertTOK_NAME(pn) {
390 let ast = shellNode(pn, "IdentifierExpression");
391 ast.precedence = 0;
392 ast.name = pn.atom;
393 if (pn.kids.length > 0 && pn.kids[0]) {
394 ast.initializer = parseToAst(pn.kids[0]);
395 }
396 return ast;
397 }
398
399
400 function convertTOK_NUMBER(pn) {
401 let ast = shellNode(pn, "LiteralExpression");
402 ast.precedence = 0;
403 ast.objtype = "number";
404 ast.value = pn.value;
405 return ast;
406 }
407
408 function convertTOK_STRING(pn) {
409 let ast = shellNode(pn, "LiteralExpression");
410 ast.precedence = 0;
411 ast.objtype = "string";
412 ast.value = pn.atom;
413 return ast;
414 }
415
416 function convertTOK_REGEXP(pn) {
417 let ast = shellNode(pn, "LiteralExpression");
418 ast.precedence = 0;
419 ast.objtype = "regex";
420 ast.value = pn.value;
421 return ast;
422 }
423
424 function convertTOK_PRIMARY(pn) {
425 let ast = shellNode(pn, "LiteralExpression");
426 ast.precedence = 0;
427 switch (pn.op) {
428 case JSOP_ZERO: ast.objtype = "number"; ast.value = 0; break;
429 case JSOP_ONE: ast.objtype = "number"; ast.value = 1; break;
430 case JSOP_NULL: ast.objtype = "null"; ast.value = null; break;
431 case JSOP_FALSE: ast.objtype = "boolean"; ast.value = false; break;
432 case JSOP_TRUE: ast.objtype = "boolean"; ast.value = true; break;
433 case JSOP_THIS:
434 return shellNode(pn, "ThisExpression");
435 default:
436 throw "Unknown operand: " + decode_op(pn.op);
437 }
438 return ast;
439 }
440
441 function convertTOK_FUNCTION(pn) {
442 let ast = shellNode(pn, "FunctionDeclaration");
443 // Precedence needs to be highest -> always wrapped
444 ast.precedence = 1.0 / 0.0;
445 ast.name = pn.name;
446 if (pn.kids[0].type == TOK_UPVARS)
447 pn = pn.kids[0];
448 let args = [];
449 if (pn.kids[0].type == TOK_ARGSBODY) {
450 pn = pn.kids[0];
451 while (pn.kids.length > 1) {
452 let argNode = parseToAst(pn.kids.shift());
453 argNode.type = "Parameter";
454 args.push(argNode);
455 }
456 }
457 ast.arguments = args;
458 ast.body = parseToAst(pn.kids[0]);
459 return ast;
460 }
461
462 function convertTOK_IF(pn) {
463 let ast = shellNode(pn, "IfStatement");
464 ast.cond = parseToAst(pn.kids[0]);
465 ast.body = parseToAst(pn.kids[1]);
466 if (pn.kids[1])
467 ast.elsebody = parseToAst(pn.kids[2]);
468 return ast;
469 }
470
471
472 function convertTOK_SWITCH(pn) {
473 let ast = shellNode(pn, "SwitchStatement");
474 ast.expr = parseToAst(pn.kids[0]);
475 let rhs = parseToAst(pn.kids[1]);
476 if (rhs instanceof Array)
477 ast.cases = rhs;
478 else
479 ast.cases = rhs.statements;
480 return ast;
481 }
482
483 function convertTOK_CASE(pn) {
484 let ast = shellNode(pn, "SwitchCase");
485 ast.expr = parseToAst(pn.kids[0]);
486 ast.body = parseToAst(pn.kids[1]);
487 return ast;
488 }
489 function convertTOK_DEFAULT(pn) {
490 let ast = shellNode(pn, "SwitchCase");
491 ast.body = parseToAst(pn.kids[1]);
492 return ast;
493 }
494
495 function convertTOK_WHILE(pn) {
496 let ast = shellNode(pn, "WhileStatement");
497 ast.cond = parseToAst(pn.kids[0]);
498 ast.body = parseToAst(pn.kids[1]);
499 return ast;
500 }
501 function convertTOK_DO(pn) {
502 let ast = shellNode(pn, "DoWhileStatement");
503 ast.body = parseToAst(pn.kids[0]);
504 ast.cond = parseToAst(pn.kids[1]);
505 return ast;
506 }
507
508 function convertTOK_FOR(pn) {
509 let ast = shellNode(pn, "ForStatement");
510 let expr = parseToAst(pn.kids[0]);
511 if (expr.type == "Forehead") {
512 ast.init = expr.init;
513 ast.cond = expr.condition;
514 ast.inc = expr.increment;
515 } else {
516 ast.type = "ForInStatement";
517 ast.itervar = expr.lhs;
518 ast.iterrange = expr.rhs;
519 ast.itertype = (pn.iflags & 0x2 ? "for each" : "for");
520 }
521 ast.body = parseToAst(pn.kids[1]);
522 return ast;
523 }
524
525 function convertTOK_BREAK(pn) {
526 let ast = shellNode(pn, "BreakStatement");
527 if (pn.atom)
528 ast.label = pn.atom;
529 return ast;
530 }
531 function convertTOK_CONTINUE(pn) {
532 let ast = shellNode(pn, "ContinueStatement");
533 if (pn.atom)
534 ast.label = pn.atom;
535 return ast;
536 }
537
538 function convertTOK_IN(pn) { return binaryNode(pn, "in", 8); }
539
540 function convertTOK_VAR(pn) {
541 let ast = shellNode(pn, "VarStatement");
542 if (pn.op == JSOP_DEFCONST)
543 ast.vartype = "const";
544 else
545 ast.vartype = "var";
546 ast.variables = pn.kids.map(parseToAst);
547 for (let x of ast.variables) {
548 if (x.type == "LetStatement")
549 return x;
550 if (x.type == "IdentifierExpression")
551 x.type = "VarDeclaration";
552 }
553 return ast;
554 }
555
556 function convertTOK_WITH(pn) {
557 let ast = shellNode(pn, "WithStatement");
558 ast.variable = parseToAst(pn.kids[0]);
559 ast.body = parseToAst(pn.kids[1]);
560 return ast;
561 }
562
563 function convertTOK_RETURN(pn) {
564 let ast = shellNode(pn, "ReturnStatement");
565 ast.expr = parseToAst(pn.kids[0]);
566 return ast;
567 }
568
569 function convertTOK_NEW(pn) {
570 let ast = shellNode(pn, "NewExpression");
571 ast.precedence = 1;
572 ast.constructor = parseToAst(pn.kids[0]);
573 ast.arguments = [];
574 for (let i = 1; i < pn.kids.length; i++)
575 ast.arguments.push(parseToAst(pn.kids[i]));
576 return ast;
577 }
578
579 function convertTOK_DELETE(pn) {
580 let ast = shellNode(pn, "UnaryExpression");
581 ast.precedence = 4;
582 ast.operator = "delete";
583 ast.operand = parseToAst(pn.kids[0]);
584 return ast;
585 }
586
587 function convertTOK_DEFSHARP(pn) {
588 let ast = shellNode(pn, "SharpDefinitionExpression");
589 ast.expr = parseToAst(pn.kids[0]);
590 ast.sharpnum = pn.number;
591 return ast;
592 }
593 function convertTOK_USESHARP(pn) {
594 let ast = shellNode(pn, "SharpExpression");
595 ast.sharpnum = pn.number;
596 return ast;
597 }
598
599 function convertTOK_TRY(pn) {
600 let ast = shellNode(pn, "TryStatement");
601 ast.body = parseToAst(pn.kids[0]);
602 if (pn.kids[1])
603 ast.catchers = parseToAst(pn.kids[1]);
604 else
605 ast.catchers = [];
606 if (pn.kids[2])
607 ast.fin = parseToAst(pn.kids[2]);
608 return ast;
609 }
610
611 function convertTOK_CATCH(pn) {
612 let ast = shellNode(pn, "CatchStatement");
613 ast.variable = parseToAst(pn.kids[0]);
614 if (pn.kids[1])
615 ast.cond = parseToAst(pn.kids[1]);
616 ast.body = parseToAst(pn.kids[2]);
617 return ast;
618 }
619
620 function convertTOK_THROW(pn) {
621 let ast = shellNode(pn, "ThrowStatement");
622 ast.expr = parseToAst(pn.kids[0]);
623 return ast;
624 }
625
626 function convertTOK_INSTANCEOF(pn) { return binaryNode(pn, "instanceof", 8); }
627
628 function convertTOK_DEBUGGER(pn) { return shellNode(pn, "DebuggerStatement"); }
629 // XML OPS
630
631 function convertTOK_YIELD(pn) {
632 let ast = shellNode(pn, "UnaryExpression");
633 ast.operand = parseToAst(pn.kids[0]);
634 ast.precedence = 16;
635 ast.operator = "yield";
636 return ast;
637 }
638
639 function convertTOK_ARRAYCOMP(pn) {
640 let ast = parseToAst(pn.kids[0]);
641 ast.precedence = 0;
642 ast.type = "ArrayComprehensionExpression";
643 if ("expr" in ast.body)
644 ast.element = ast.body.expr;
645 else {
646 ast.element = ast.body.body.expr;
647 ast.iterif = ast.body.cond;
648 }
649 delete ast.body;
650 return ast;
651 }
652
653 function convertTOK_ARRAYPUSH(pn) {
654 let ast = shellNode(pn, "ArrayPush");
655 ast.expr = parseToAst(pn.kids[0]);
656 return ast;
657 }
658
659 function convertTOK_LEXICALSCOPE(pn) {
660 return parseToAst(pn.kids[0]);
661 }
662
663 function convertTOK_LET(pn) {
664 let ast = convertTOK_VAR(pn);
665 if (ast.type == "VarStatement")
666 ast.vartype = "let";
667 return ast;
668 }
669
670 function convertTOK_FORHEAD(pn) {
671 let ast = shellNode(pn, "Forehead");
672 ast.init = pn.kids[0] ? parseToAst(pn.kids[0]) :
673 shellNode(pn, "EmptyStatement");
674 ast.condition = pn.kids[1] ? parseToAst(pn.kids[1]) :
675 shellNode(pn, "EmptyStatement");
676 ast.increment = pn.kids[2] ? parseToAst(pn.kids[2]) :
677 shellNode(pn, "EmptyStatement");
678 return ast;
679 }
680
681 function convertTOK_RESERVED(pn) {
682 return pn.kids.map(parseToAst);
683 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld