Mercurial > hg > octave-lyh
diff src/parse.y @ 2764:2c0f259cf83d
[project @ 1997-03-01 02:30:26 by jwe]
author | jwe |
---|---|
date | Sat, 01 Mar 1997 02:30:29 +0000 |
parents | 76411ce43c05 |
children | ef422e6f6138 |
line wrap: on
line diff
--- a/src/parse.y +++ b/src/parse.y @@ -72,6 +72,9 @@ // static bool Vwarn_assign_as_truth_value; +// If TRUE, generate a warning for variable swich labels. +static bool Vwarn_variable_switch_label; + // If TRUE, generate a warning for the comma in things like // // octave> global a, b = 2 @@ -119,6 +122,9 @@ // test in a logical expression. static void maybe_warn_assign_as_truth_value (tree_expression *expr); +// Maybe print a warning about switch labels that aren't constants. +static void maybe_warn_variable_switch_label (tree_expression *expr); + // Create a plot command. static tree_plot_command *make_plot_command (token *tok, plot_limits *range, subplot_list *list); @@ -196,6 +202,15 @@ static tree_if_clause *make_elseif_clause (tree_expression *expr, tree_statement_list *list); +// Finish a switch command. +static tree_switch_command *finish_switch_command + (token *switch_tok, tree_expression *expr, + tree_switch_case_list *list, token *end_tok); + +// Build a switch case. +static tree_switch_case *make_switch_case + (tree_expression *expr, tree_statement_list *list); + // Build an assignment to a variable. static tree_expression *make_simple_assignment (tree_index_expression *var, token *eq_tok, tree_expression *expr); @@ -271,6 +286,9 @@ tree_if_command *tree_if_command_type; tree_if_clause *tree_if_clause_type; tree_if_command_list *tree_if_command_list_type; + tree_switch_command *tree_switch_command_type; + tree_switch_case *tree_switch_case_type; + tree_switch_case_list *tree_switch_case_list_type; tree_global *tree_global_type; tree_global_init_list *tree_global_init_list_type; tree_global_command *tree_global_command_type; @@ -300,6 +318,7 @@ %token <tok_val> TEXT STYLE %token <tok_val> FOR WHILE %token <tok_val> IF ELSEIF ELSE +%token <tok_val> SWITCH CASE OTHERWISE %token <tok_val> BREAK CONTINUE FUNC_RET %token <tok_val> UNWIND CLEANUP %token <tok_val> TRY CATCH @@ -333,6 +352,9 @@ %type <tree_if_command_type> if_command %type <tree_if_clause_type> elseif_clause else_clause %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list +%type <tree_switch_command_type> switch_command +%type <tree_switch_case_type> switch_case default_case +%type <tree_switch_case_list_type> case_list1 case_list %type <tree_global_type> global_decl2 %type <tree_global_init_list_type> global_decl1 %type <tree_global_command_type> global_decl @@ -618,11 +640,10 @@ { $$ = $1; } | global_decl { $$ = $1; } + | switch_command + { $$ = $1; } | if_command - { - lexer_flags.iffing--; - $$ = $1; - } + { $$ = $1; } | UNWIND opt_sep opt_list CLEANUP opt_sep opt_list END { if (! ($$ = make_unwind_command ($1, $3, $6, $7))) @@ -699,6 +720,39 @@ { $$ = new tree_if_clause ($3); } ; +switch_command : SWITCH expression opt_sep case_list END + { + if (! ($$ = finish_switch_command ($1, $2, $4, $5))) + ABORT_PARSE; + } + ; + +case_list : case_list1 + { $$ = $1; } + | case_list1 default_case + { + $1->append ($2); + $$ = $1; + } + ; + +case_list1 : switch_case + { $$ = new tree_switch_case_list ($1); } + | case_list1 switch_case + { + $1->append ($2); + $$ = $1; + } + ; + +switch_case : CASE opt_sep expression opt_sep list + { $$ = make_switch_case ($3, $5); } + ; + +default_case : OTHERWISE opt_sep opt_list + { $$ = new tree_switch_case ($3); } + ; + screwed_again : // empty { lexer_flags.maybe_screwed_again++; } ; @@ -1280,6 +1334,10 @@ end_error ("try", ettype, l, c); break; + case token::switch_end: + end_error ("switch", ettype, l, c); + break; + case token::unwind_protect_end: end_error ("unwind_protect", ettype, l, c); break; @@ -1351,6 +1409,17 @@ } } +// Maybe print a warning about switch labels that aren't constants. + +static void +maybe_warn_variable_switch_label (tree_expression *expr) +{ + if (Vwarn_variable_switch_label && ! expr->is_constant ()) + { + warning ("variable switch label"); + } +} + // Create a plot command. static tree_plot_command * @@ -1975,6 +2044,35 @@ return new tree_if_clause (expr, list); } +// Finish a switch command. + +static tree_switch_command * +finish_switch_command (token *switch_tok, tree_expression *expr, + tree_switch_case_list *list, token *end_tok) +{ + tree_switch_command *retval = 0; + + if (! check_end (end_tok, token::switch_end)) + { + int l = switch_tok->line (); + int c = switch_tok->column (); + + retval = new tree_switch_command (expr, list, l, c); + } + + return retval; +} + +// Build a switch case. + +static tree_switch_case * +make_switch_case (tree_expression *expr, tree_statement_list *list) +{ + maybe_warn_variable_switch_label (expr); + + return new tree_switch_case (expr, list); +} + // Build an assignment to a variable. static tree_expression * @@ -2274,6 +2372,15 @@ return 0; } +static int +warn_variable_switch_label (void) +{ + Vwarn_variable_switch_label + = check_preference ("warn_variable_switch_label"); + + return 0; +} + void symbols_of_parse (void) { @@ -2287,8 +2394,11 @@ "produce warning if function name conflicts with file name"); DEFVAR (warn_missing_semicolon, 0.0, 0, warn_missing_semicolon, - "produce a warning if a statement in a function file is not + "produce a warning if a statement in a function file is not\n\ terminated with a semicolon"); + + DEFVAR (warn_variable_switch_label, 0.0, 0, warn_variable_switch_label, + "produce warning for variables used as switch labels"); } /*