| 2588 | } |
| 2589 | |
| 2590 | static void compile_parse( PARSE * parse, compiler * c, int32_t result_location ) |
| 2591 | { |
| 2592 | compile_emit_debug(c, parse->line); |
| 2593 | if ( parse->type == PARSE_APPEND ) |
| 2594 | { |
| 2595 | compile_append_chain( parse, c ); |
| 2596 | adjust_result( c, RESULT_STACK, result_location ); |
| 2597 | } |
| 2598 | else if ( parse->type == PARSE_EVAL ) |
| 2599 | { |
| 2600 | /* FIXME: This is only needed because of the bizarre parsing of |
| 2601 | * conditions. |
| 2602 | */ |
| 2603 | if ( parse->num == EXPR_EXISTS ) |
| 2604 | compile_parse( parse->left, c, result_location ); |
| 2605 | else |
| 2606 | { |
| 2607 | int32_t f = compile_new_label( c ); |
| 2608 | int32_t end = compile_new_label( c ); |
| 2609 | |
| 2610 | out_printf( "%s:%d: Conditional used as list (check operator " |
| 2611 | "precedence).\n", object_str( parse->file ), parse->line ); |
| 2612 | |
| 2613 | /* Emit the condition */ |
| 2614 | compile_condition( parse, c, 0, f ); |
| 2615 | compile_emit( c, INSTR_PUSH_CONSTANT, compile_emit_constant( c, |
| 2616 | constant_true ) ); |
| 2617 | compile_emit_branch( c, INSTR_JUMP, end ); |
| 2618 | compile_set_label( c, f ); |
| 2619 | compile_emit( c, INSTR_PUSH_EMPTY, 0 ); |
| 2620 | compile_set_label( c, end ); |
| 2621 | adjust_result( c, RESULT_STACK, result_location ); |
| 2622 | } |
| 2623 | } |
| 2624 | else if ( parse->type == PARSE_FOREACH ) |
| 2625 | { |
| 2626 | int32_t var = compile_emit_constant( c, parse->string ); |
| 2627 | int32_t top = compile_new_label( c ); |
| 2628 | int32_t end = compile_new_label( c ); |
| 2629 | int32_t continue_ = compile_new_label( c ); |
| 2630 | |
| 2631 | /* |
| 2632 | * Evaluate the list. |
| 2633 | */ |
| 2634 | compile_parse( parse->left, c, RESULT_STACK ); |
| 2635 | |
| 2636 | /* Localize the loop variable */ |
| 2637 | if ( parse->num ) |
| 2638 | { |
| 2639 | compile_emit( c, INSTR_PUSH_EMPTY, 0 ); |
| 2640 | compile_emit( c, INSTR_PUSH_LOCAL, var ); |
| 2641 | compile_emit( c, INSTR_SWAP, 1 ); |
| 2642 | compile_push_cleanup( c, INSTR_POP_LOCAL, var ); |
| 2643 | } |
| 2644 | |
| 2645 | compile_emit( c, INSTR_FOR_INIT, 0 ); |
| 2646 | compile_set_label( c, top ); |
| 2647 | compile_emit_branch( c, INSTR_FOR_LOOP, end ); |
no test coverage detected