Branch: Tag:

2001-01-10

2001-01-10 20:00:23 by Martin Stjernholm <mast@lysator.liu.se>

Implemented labeled breaks and continues. They follow the Java approach
closely.

Rev: src/docode.c:1.90
Rev: src/language.yacc:1.221

110:   /* This is the grammar definition of Pike. */      #include "global.h" - RCSID("$Id: language.yacc,v 1.220 2000/12/01 10:00:46 hubbe Exp $"); + RCSID("$Id: language.yacc,v 1.221 2001/01/10 20:00:23 mast Exp $");   #ifdef HAVE_MEMORY_H   #include <memory.h>   #endif
296:   %type <n> gauge   %type <n> idents   %type <n> idents2 + %type <n> labeled_statement   %type <n> lambda   %type <n> local_name_list   %type <n> local_name_list2
308:   %type <n> m_expr_list2   %type <n> new_local_name   %type <n> new_local_name2 + %type <n> normal_label_statement   %type <n> optional_else_part -  + %type <n> optional_label   %type <n> return   %type <n> sscanf   %type <n> statement
1618:    ;       - statement: unused2 ';' + normal_label_statement: unused2 ';'    | import { $$=0; }    | cond -  | while -  | do -  | for -  | switch -  | case -  | default +     | return expected_semicolon    | local_constant { $$=0; }    | block -  | foreach +     | break expected_semicolon    | continue expected_semicolon    | error ';' { reset_type_stack(); $$=0; yyerrok; }
1651:    | ';' { $$=0; }    ;    + statement: normal_label_statement +  { +  Pike_compiler->compiler_frame->opt_flags &= ~OPT_CUSTOM_LABELS; +  } +  | while +  | do +  | for +  | foreach +  | switch +  | case +  | default +  | labeled_statement +  ;    - break: TOK_BREAK { $$=mknode(F_BREAK,0,0); } ; + labeled_statement: TOK_IDENTIFIER +  { +  $<number>$ = lex.current_line; +  Pike_compiler->compiler_frame->opt_flags &= ~OPT_CUSTOM_LABELS; +  } +  ':' statement +  { +  $$ = mknode(Pike_compiler->compiler_frame->opt_flags & OPT_CUSTOM_LABELS ? +  F_CUSTOM_STMT_LABEL : F_NORMAL_STMT_LABEL, +  $1, $4); +  +  /* FIXME: This won't be correct if the node happens to be shared. +  * That's an issue to be solved with shared nodes in general, +  * though. */ +  $$->line_number = $<number>2; +  } +  ; +  + optional_label: TOK_IDENTIFIER +  | /* empty */ {$$ = 0;} +  ; +  + break: TOK_BREAK optional_label { $$=mknode(F_BREAK,$2,0); } ;   default: TOK_DEFAULT ':' { $$=mknode(F_DEFAULT,0,0); }    | TOK_DEFAULT    {
1660:    }    ;    - continue: TOK_CONTINUE { $$=mknode(F_CONTINUE,0,0); } ; + continue: TOK_CONTINUE optional_label { $$=mknode(F_CONTINUE,$2,0); } ;      push_compiler_frame1: /* empty */    {
2305:    }    pop_local_variables($<number>2);    Pike_compiler->compiler_frame->last_block_level=$<number>3; +  Pike_compiler->compiler_frame->opt_flags |= OPT_CUSTOM_LABELS;    }    ;   
2312:    {    $$=mknode(F_DO,$2,$5);    $$->line_number=$1; +  Pike_compiler->compiler_frame->opt_flags |= OPT_CUSTOM_LABELS;    }    | TOK_DO statement TOK_WHILE TOK_LEX_EOF    {
2354:    lex.current_line=i;    pop_local_variables($<number>2);    Pike_compiler->compiler_frame->last_block_level=$<number>3; +  Pike_compiler->compiler_frame->opt_flags |= OPT_CUSTOM_LABELS;    }    ;   
2375:    lex.current_line=i;    pop_local_variables($<number>2);    Pike_compiler->compiler_frame->last_block_level=$<number>3; +  Pike_compiler->compiler_frame->opt_flags |= OPT_CUSTOM_LABELS;    }    ;