| 2421 | } |
| 2422 | |
| 2423 | static void compile_parse( PARSE * parse, compiler * c, int result_location ) |
| 2424 | { |
| 2425 | if ( parse->type == PARSE_APPEND ) |
| 2426 | { |
| 2427 | compile_append_chain( parse, c ); |
| 2428 | adjust_result( c, RESULT_STACK, result_location ); |
| 2429 | } |
| 2430 | else if ( parse->type == PARSE_EVAL ) |
| 2431 | { |
| 2432 | /* FIXME: This is only needed because of the bizarre parsing of |
| 2433 | * conditions. |
| 2434 | */ |
| 2435 | if ( parse->num == EXPR_EXISTS ) |
| 2436 | compile_parse( parse->left, c, result_location ); |
| 2437 | else |
| 2438 | { |
| 2439 | int f = compile_new_label( c ); |
| 2440 | int end = compile_new_label( c ); |
| 2441 | |
| 2442 | out_printf( "%s:%d: Conditional used as list (check operator " |
| 2443 | "precedence).\n", object_str( parse->file ), parse->line ); |
| 2444 | |
| 2445 | /* Emit the condition */ |
| 2446 | compile_condition( parse, c, 0, f ); |
| 2447 | compile_emit( c, INSTR_PUSH_CONSTANT, compile_emit_constant( c, |
| 2448 | constant_true ) ); |
| 2449 | compile_emit_branch( c, INSTR_JUMP, end ); |
| 2450 | compile_set_label( c, f ); |
| 2451 | compile_emit( c, INSTR_PUSH_EMPTY, 0 ); |
| 2452 | compile_set_label( c, end ); |
| 2453 | adjust_result( c, RESULT_STACK, result_location ); |
| 2454 | } |
| 2455 | } |
| 2456 | else if ( parse->type == PARSE_FOREACH ) |
| 2457 | { |
| 2458 | int var = compile_emit_constant( c, parse->string ); |
| 2459 | int top = compile_new_label( c ); |
| 2460 | int end = compile_new_label( c ); |
| 2461 | int continue_ = compile_new_label( c ); |
| 2462 | |
| 2463 | /* |
| 2464 | * Evaluate the list. |
| 2465 | */ |
| 2466 | compile_parse( parse->left, c, RESULT_STACK ); |
| 2467 | |
| 2468 | /* Localize the loop variable */ |
| 2469 | if ( parse->num ) |
| 2470 | { |
| 2471 | compile_emit( c, INSTR_PUSH_EMPTY, 0 ); |
| 2472 | compile_emit( c, INSTR_PUSH_LOCAL, var ); |
| 2473 | compile_emit( c, INSTR_SWAP, 1 ); |
| 2474 | compile_push_cleanup( c, INSTR_POP_LOCAL, var ); |
| 2475 | } |
| 2476 | |
| 2477 | compile_emit( c, INSTR_FOR_INIT, 0 ); |
| 2478 | compile_set_label( c, top ); |
| 2479 | compile_emit_branch( c, INSTR_FOR_LOOP, end ); |
| 2480 | compile_emit( c, INSTR_SET, var ); |
no test coverage detected