summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2003-10-18 19:57:11 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2003-10-18 19:57:11 +0000
commit54e128fd59038d206f8cb7a77b5ec8ee3fd447ea (patch)
tree94bff6c5ce097fad46fec9fb46b2485f5aeb1968 /usr.bin
parent2a13d998bc4a3faa40d64cff963aaf133caf795b (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.17
-rw-r--r--usr.bin/bc/bc.y57
-rw-r--r--usr.bin/bc/scan.l6
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;