=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/bc/bc.y,v retrieving revision 1.10 retrieving revision 1.11 diff -c -r1.10 -r1.11 *** src/usr.bin/bc/bc.y 2003/09/30 18:46:11 1.10 --- src/usr.bin/bc/bc.y 2003/10/18 19:57:10 1.11 *************** *** 1,5 **** %{ ! /* $OpenBSD: bc.y,v 1.10 2003/09/30 18:46:11 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek --- 1,5 ---- %{ ! /* $OpenBSD: bc.y,v 1.11 2003/10/18 19:57:10 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek *************** *** 31,37 **** */ #ifndef lint ! static const char rcsid[] = "$OpenBSD: bc.y,v 1.10 2003/09/30 18:46:11 otto Exp $"; #endif /* not lint */ #include --- 31,37 ---- */ #ifndef lint ! static const char rcsid[] = "$OpenBSD: bc.y,v 1.11 2003/10/18 19:57:10 otto Exp $"; #endif /* not lint */ #include *************** *** 85,90 **** --- 85,91 ---- static int breaksp = 0; static ssize_t prologue; static ssize_t epilogue; + static bool st_has_continue; static char str_table[UCHAR_MAX][2]; static int sargc; static char **sargv; *************** *** 119,124 **** --- 120,126 ---- %token DEFINE BREAK QUIT LENGTH %token RETURN FOR IF WHILE SQRT %token SCALE IBASE OBASE AUTO + %token CONTINUE ELSE %nonassoc EQUALS LESS_EQ GREATER_EQ UNEQUALS LESS GREATER %right ASSIGN_OP *************** *** 160,170 **** --- 162,174 ---- macro_char = reset_macro_char; putchar('\n'); free_tree(); + st_has_continue = false; } | function { putchar('\n'); free_tree(); + st_has_continue = false; } | error NEWLINE { *************** *** 215,221 **** } | named_expression ASSIGN_OP expression { ! $$ = node($3, cs($2), $1.store, END_NODE); } | STRING { --- 219,230 ---- } | named_expression ASSIGN_OP expression { ! if ($2[0] == '\0') ! $$ = node($3, cs($2), $1.store, ! END_NODE); ! else ! $$ = node($1.load, $3, cs($2), $1.store, ! END_NODE); } | STRING { *************** *** 234,239 **** --- 243,260 ---- cs("Q"), END_NODE); } } + | CONTINUE + { + if (breaksp == 0) { + warning("continue not in for or while"); + YYERROR; + } else { + st_has_continue = true; + $$ = node(numnode(nesting - + breakstack[breaksp-1] - 1), + cs("J"), END_NODE); + } + } | QUIT { putchar('q'); *************** *** 261,268 **** relational_expression SEMICOLON expression RPAR opt_statement pop_nesting { ! int n = node($10, $8, cs("s."), $6, $3, ! END_NODE); emit_macro($3, n); $$ = node($4, cs("s."), $6, $3, cs(" "), END_NODE); --- 282,296 ---- relational_expression SEMICOLON expression RPAR opt_statement pop_nesting { ! ssize_t n; ! ! if (st_has_continue) ! n = node($10, cs("M"), $8, cs("s."), ! $6, $3, END_NODE); ! else ! n = node($10, $8, cs("s."), $6, $3, ! END_NODE); ! emit_macro($3, n); $$ = node($4, cs("s."), $6, $3, cs(" "), END_NODE); *************** *** 276,282 **** | WHILE LPAR alloc_macro relational_expression RPAR opt_statement pop_nesting { ! int n = node($6, $4, $3, END_NODE); emit_macro($3, n); $$ = node($4, $3, cs(" "), END_NODE); } --- 304,315 ---- | WHILE LPAR alloc_macro relational_expression RPAR opt_statement pop_nesting { ! ssize_t n; ! ! if (st_has_continue) ! n = node($6, cs("M"), $4, $3, END_NODE); ! else ! n = node($6, $4, $3, END_NODE); emit_macro($3, n); $$ = node($4, $3, cs(" "), END_NODE); } *************** *** 304,313 **** --- 337,349 ---- fatal("nesting too deep"); breakstack[breaksp++] = nesting++; } + ; + pop_nesting : /* empty */ { breaksp--; } + ; function : function_header opt_parameter_list RPAR LBRACE NEWLINE opt_auto_define_list *************** *** 332,337 **** --- 368,374 ---- breaksp = 0; breakstack[breaksp] = 0; } + ; opt_parameter_list : /* empty */ *************** *** 525,532 **** } | named_expression ASSIGN_OP expression { ! $$ = node($3, cs($2), cs("d"), ! $1.store, END_NODE); } | LENGTH LPAR expression RPAR { --- 562,573 ---- } | named_expression ASSIGN_OP expression { ! if ($2[0] == '\0') ! $$ = node($3, cs($2), cs("d"), $1.store, ! END_NODE); ! else ! $$ = node($1.load, $3, cs($2), cs("d"), ! $1.store, END_NODE); } | LENGTH LPAR expression RPAR {