277 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
278 |
} |
} |
279 |
|
|
280 |
|
static void output_array_comprehension_or_generator_expression(JSParseNode * node, Stream * f) { |
281 |
|
assert(node->pn_type == TOK_LEXICALSCOPE); |
282 |
|
assert(node->pn_arity == PN_NAME); |
283 |
|
JSParseNode * for_node = node->pn_expr; |
284 |
|
assert(for_node->pn_type == TOK_FOR); |
285 |
|
assert(for_node->pn_arity == PN_BINARY); |
286 |
|
JSParseNode * p = for_node; |
287 |
|
while (p->pn_type == TOK_FOR) { |
288 |
|
p = p->pn_right; |
289 |
|
} |
290 |
|
JSParseNode * if_node = NULL; |
291 |
|
if (p->pn_type == TOK_IF) { |
292 |
|
if_node = p; |
293 |
|
assert(if_node->pn_arity == PN_TERNARY); |
294 |
|
p = if_node->pn_kid2; |
295 |
|
} |
296 |
|
assert(p->pn_arity == PN_UNARY); |
297 |
|
p = p->pn_kid; |
298 |
|
if (p->pn_type == TOK_YIELD) { |
299 |
|
/* for generator expressions */ |
300 |
|
p = p->pn_kid; |
301 |
|
} |
302 |
|
|
303 |
|
instrument_expression(p, f); |
304 |
|
p = for_node; |
305 |
|
while (p->pn_type == TOK_FOR) { |
306 |
|
Stream_write_char(f, ' '); |
307 |
|
output_for_in(p, f); |
308 |
|
p = p->pn_right; |
309 |
|
} |
310 |
|
if (if_node) { |
311 |
|
Stream_write_string(f, " if ("); |
312 |
|
instrument_expression(if_node->pn_kid1, f); |
313 |
|
Stream_write_char(f, ')'); |
314 |
|
} |
315 |
|
} |
316 |
|
|
317 |
static void instrument_function(JSParseNode * node, Stream * f, int indent, enum FunctionType type) { |
static void instrument_function(JSParseNode * node, Stream * f, int indent, enum FunctionType type) { |
318 |
assert(node->pn_type == TOK_FUNCTION); |
assert(node->pn_type == TOK_FUNCTION); |
319 |
assert(node->pn_arity == PN_FUNC); |
assert(node->pn_arity == PN_FUNC); |
383 |
|
|
384 |
if (function_node->pn_flags & TCF_GENEXP_LAMBDA) { |
if (function_node->pn_flags & TCF_GENEXP_LAMBDA) { |
385 |
/* it's a generator expression */ |
/* it's a generator expression */ |
|
JSParseNode * lexical_scope_node = function_node->pn_body; |
|
|
assert(lexical_scope_node->pn_type == TOK_LEXICALSCOPE); |
|
|
assert(lexical_scope_node->pn_arity == PN_NAME); |
|
|
JSParseNode * for_node = lexical_scope_node->pn_body; |
|
|
assert(for_node->pn_type == TOK_FOR); |
|
|
assert(for_node->pn_arity == PN_BINARY); |
|
|
JSParseNode * if_node = NULL; |
|
|
JSParseNode * semi_node; |
|
|
switch (for_node->pn_right->pn_type) { |
|
|
case TOK_SEMI: |
|
|
semi_node = for_node->pn_right; |
|
|
break; |
|
|
case TOK_IF: |
|
|
if_node = for_node->pn_right; |
|
|
assert(if_node->pn_arity == PN_TERNARY); |
|
|
semi_node = if_node->pn_kid2; |
|
|
assert(semi_node->pn_type == TOK_SEMI); |
|
|
break; |
|
|
default: |
|
|
abort(); |
|
|
break; |
|
|
} |
|
|
assert(semi_node->pn_arity == PN_UNARY); |
|
|
JSParseNode * yield_node = semi_node->pn_kid; |
|
|
assert(yield_node->pn_type == TOK_YIELD); |
|
386 |
Stream_write_char(f, '('); |
Stream_write_char(f, '('); |
387 |
instrument_expression(yield_node->pn_kid, f); |
output_array_comprehension_or_generator_expression(function_node->pn_body, f); |
|
Stream_write_char(f, ' '); |
|
|
output_for_in(for_node, f); |
|
|
if (if_node) { |
|
|
Stream_write_string(f, " if ("); |
|
|
instrument_expression(if_node->pn_kid1, f); |
|
|
Stream_write_char(f, ')'); |
|
|
} |
|
388 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
389 |
return; |
return; |
390 |
} |
} |
787 |
abort(); |
abort(); |
788 |
break; |
break; |
789 |
} |
} |
|
assert(block_node->pn_type == TOK_LEXICALSCOPE); |
|
|
assert(block_node->pn_arity == PN_NAME); |
|
|
JSParseNode * for_node = block_node->pn_expr; |
|
|
assert(for_node->pn_type == TOK_FOR); |
|
|
assert(for_node->pn_arity == PN_BINARY); |
|
|
JSParseNode * p = for_node; |
|
|
while (p->pn_type == TOK_FOR) { |
|
|
p = p->pn_right; |
|
|
} |
|
|
JSParseNode * if_node = NULL; |
|
|
JSParseNode * push_node; |
|
|
switch (p->pn_type) { |
|
|
case TOK_ARRAYPUSH: |
|
|
push_node = p; |
|
|
assert(push_node->pn_arity == PN_UNARY); |
|
|
break; |
|
|
case TOK_IF: |
|
|
if_node = p; |
|
|
assert(if_node->pn_arity == PN_TERNARY); |
|
|
push_node = if_node->pn_kid2; |
|
|
assert(push_node->pn_arity == PN_UNARY); |
|
|
break; |
|
|
default: |
|
|
abort(); |
|
|
break; |
|
|
} |
|
790 |
Stream_write_char(f, '['); |
Stream_write_char(f, '['); |
791 |
instrument_expression(push_node->pn_kid, f); |
output_array_comprehension_or_generator_expression(block_node, f); |
|
p = for_node; |
|
|
while (p->pn_type == TOK_FOR) { |
|
|
Stream_write_char(f, ' '); |
|
|
output_for_in(p, f); |
|
|
p = p->pn_right; |
|
|
} |
|
|
if (if_node) { |
|
|
Stream_write_string(f, " if ("); |
|
|
instrument_expression(if_node->pn_kid1, f); |
|
|
Stream_write_char(f, ')'); |
|
|
} |
|
792 |
Stream_write_char(f, ']'); |
Stream_write_char(f, ']'); |
793 |
} |
} |
794 |
break; |
break; |