diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2003-10-18 19:57:11 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2003-10-18 19:57:11 +0000 |
commit | 54e128fd59038d206f8cb7a77b5ec8ee3fd447ea (patch) | |
tree | 94bff6c5ce097fad46fec9fb46b2485f5aeb1968 /usr.bin | |
parent | 2a13d998bc4a3faa40d64cff963aaf133caf795b (diff) |
o Fix assignment operators (+=, -=, ... )
o Implement "continue" in loops. If continue is not used, generated code is
still "classic" dc(1) compatible. If continue is used, you'll need a dc(1)
that implements the J and M operators.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/bc/bc.1 | 7 | ||||
-rw-r--r-- | usr.bin/bc/bc.y | 57 | ||||
-rw-r--r-- | usr.bin/bc/scan.l | 6 |
3 files changed, 57 insertions, 13 deletions
diff --git a/usr.bin/bc/bc.1 b/usr.bin/bc/bc.1 index f3736132f92..d6734a810fc 100644 --- a/usr.bin/bc/bc.1 +++ b/usr.bin/bc/bc.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bc.1,v 1.5 2003/09/26 13:47:16 otto Exp $ +.\" $OpenBSD: bc.1,v 1.6 2003/10/18 19:57:10 otto Exp $ .\" .\" Copyright (C) Caldera International Inc. 2001-2002. .\" All rights reserved. @@ -120,8 +120,9 @@ while ( E ) S for ( E ; E ; E ) S null statement break +continue quit -a string of letters, enclosed in double quotes +a string of characters, enclosed in double quotes .Ed .Pp Function definitions @@ -136,7 +137,7 @@ define L ( L ,..., L ) { The sequence .Sq \e\<newline><whitespace> is ignored within numbers. -The newline character may be part part of a string. +A string may contain any character, except double quote. .Pp Functions in .Fl lm diff --git a/usr.bin/bc/bc.y b/usr.bin/bc/bc.y index 25a40adf9eb..df52e14aaee 100644 --- a/usr.bin/bc/bc.y +++ b/usr.bin/bc/bc.y @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: bc.y,v 1.10 2003/09/30 18:46:11 otto Exp $ */ +/* $OpenBSD: bc.y,v 1.11 2003/10/18 19:57:10 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> @@ -31,7 +31,7 @@ */ #ifndef lint -static const char rcsid[] = "$OpenBSD: bc.y,v 1.10 2003/09/30 18:46:11 otto Exp $"; +static const char rcsid[] = "$OpenBSD: bc.y,v 1.11 2003/10/18 19:57:10 otto Exp $"; #endif /* not lint */ #include <ctype.h> @@ -85,6 +85,7 @@ static int breakstack[16]; 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,6 +120,7 @@ extern char *__progname; %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 <str> ASSIGN_OP @@ -160,11 +162,13 @@ input_item : semicolon_list NEWLINE 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,7 +219,12 @@ statement : expression } | named_expression ASSIGN_OP expression { - $$ = node($3, cs($2), $1.store, END_NODE); + 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,6 +243,18 @@ statement : expression 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,8 +282,15 @@ statement : expression relational_expression SEMICOLON expression RPAR opt_statement pop_nesting { - int n = node($10, $8, cs("s."), $6, $3, - END_NODE); + 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,7 +304,12 @@ statement : expression | WHILE LPAR alloc_macro relational_expression RPAR opt_statement pop_nesting { - int n = node($6, $4, $3, END_NODE); + 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,10 +337,13 @@ alloc_macro : /* empty */ 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,6 +368,7 @@ function_header : DEFINE LETTER LPAR breaksp = 0; breakstack[breaksp] = 0; } + ; opt_parameter_list : /* empty */ @@ -525,8 +562,12 @@ expression : named_expression } | named_expression ASSIGN_OP expression { - $$ = node($3, cs($2), cs("d"), - $1.store, END_NODE); + 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 { diff --git a/usr.bin/bc/scan.l b/usr.bin/bc/scan.l index a8b0179a302..598ab015426 100644 --- a/usr.bin/bc/scan.l +++ b/usr.bin/bc/scan.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scan.l,v 1.7 2003/09/30 18:46:11 otto Exp $ */ +/* $OpenBSD: scan.l,v 1.8 2003/10/18 19:57:10 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> @@ -18,7 +18,7 @@ */ #ifndef lint -static const char rcsid[] = "$OpenBSD: scan.l,v 1.7 2003/09/30 18:46:11 otto Exp $"; +static const char rcsid[] = "$OpenBSD: scan.l,v 1.8 2003/10/18 19:57:10 otto Exp $"; #endif /* not lint */ #include <err.h> @@ -104,7 +104,9 @@ DIGIT [0-9A-F] "auto" return AUTO; "break" return BREAK; +"continue" return CONTINUE; "define" return DEFINE; +"else" return ELSE; "ibase" return IBASE; "if" return IF; "for" return FOR; |