Upgrade to version 1.03.

This commit is contained in:
Steve Price 1996-11-04 03:55:26 +00:00
parent e1384c5e2d
commit 7e0d34dec8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=19380
22 changed files with 977 additions and 3135 deletions

View File

@ -1,6 +1,10 @@
PROG= bc
SRCS= bc.c global.c scan.c util.c main.c number.c storage.c load.c execute.c
MAN1= bc.1
BCSRCS= execute.c global.c load.c main.c number.c storage.c util.c
GENSRCS= bc.c scan.c
SRCS= ${GENSRCS} ${BCSRCS}
CFLAGS+= -D_POSIX_SOURCE -I$(.CURDIR)
CLEANFILES+= ${GENSRCS} y.tab.h
.include <bsd.prog.mk>

View File

@ -1,8 +1,8 @@
.\"
.\" bc.1 - the *roff document processor source for the bc manual
.\"
.\" This file is part of bc written for MINIX.
.\" Copyright (C) 1991, 1992 Free Software Foundation, Inc.
.\" This file is part of bc written initially for MINIX.
.\" Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
.\"
.\" This program is free software; you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by
@ -25,15 +25,15 @@
.\" Western Washington University
.\" Bellingham, WA 98226-9062
.\"
.\" $Id$
.\" $Id: bc.1,v 1.3 1996/10/05 22:26:19 wosch Exp $
.\"
.TH bc 1 .\" "Command Manual" v1.02 "Feb 3, 1992"
.TH bc 1 .\" "Command Manual" v1.03 "Nov 2, 1994"
.SH NAME
bc - An arbitrary precision calculator language
.SH SYNTAX
\fBbc\fR [ \fB-lws\fR ] [ \fI file ...\fR ]
.SH VERSION
This man page documents GNU bc version 1.02.
This man page documents GNU bc version 1.03.
.SH DESCRIPTION
\fBbc\fR is a language that supports arbitrary precision numbers
with interactive execution of statements. There are some similarities
@ -317,7 +317,9 @@ last value printed without having to retype the expression that
printed the number. Assigning to \fBlast\fR is legal and will
overwrite the last printed value with the assigned value. The newly
assigned value will remain until the next number is printed or another
value is assigned to \fBlast\fR.
value is assigned to \fBlast\fR. (Some installations may allow the
use of a single period (.) which is not part of a number as a short
hand notation for for \fBlast\fR.)
.IP "string"
The string is printed to the output. Strings start with a double quote
character and contain all characters until the next double quote character.
@ -332,10 +334,9 @@ value is printed and assigned the variable \fBlast\fR. Strings
in the print statement are printed to the output and may contain
special characters. Special characters start with the backslash
character (\e). The special characters recognized by \fBbc\fR are
"b" (bell), "f" (form feed), "n" (newline), "r" (carriage return), "t"
(tab), and "\e" (backslash). Any other character following the
backslash will be ignored. This still does not allow the double quote
character to be part of any string.
"a" (alert or bell), "b" (backspace), "f" (form feed), "n" (newline),
"r" (carriage return), "q" (double quote), "t" (tab), and "\e" (backslash).
Any other character following the backslash will be ignored.
.IP "{ statement_list }"
This is the compound statement. It allows multiple statements to be
grouped together for execution.
@ -702,9 +703,9 @@ The multiply routine may yield incorrect results if a number
has more than LONG_MAX / 90 total digits. For 32 bit longs, this number is
23,860,929 digits.
.IP "code size"
Each function and the "main" program are limited to 10240 bytes of
Each function and the "main" program are limited to 16384 bytes of
compiled byte code each. This limit (BC_MAX_SEGS) can be easily changed
to have more than 10 segments of 1024 bytes.
to have more than 16 segments of 1024 bytes.
.IP "variable names"
The current limit on the number of unique names is 32767 for each of
simple variables, arrays and functions.
@ -726,6 +727,6 @@ Philip A. Nelson
phil@cs.wwu.edu
.fi
.SH ACKNOWLEDGEMENTS
The author would like to thank Steve Sommars (sesv@iwtsf.att.com) for
The author would like to thank Steve Sommars (Steve.Sommars@att.com) for
his extensive help in testing the implementation. Many great suggestions
were given. This is a much better product due to his involvement.

File diff suppressed because it is too large Load Diff

615
gnu/usr.bin/bc/bc.y Normal file
View File

@ -0,0 +1,615 @@
%{
/* bc.y: The grammar for a POSIX compatable bc processor with some
extensions to the language. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License , or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
You may contact the author by:
e-mail: phil@cs.wwu.edu
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include "bcdefs.h"
#include "global.h"
#include "proto.h"
%}
%start program
%union {
char *s_value;
char c_value;
int i_value;
arg_list *a_value;
}
/* Extensions over POSIX bc.
a) NAME was LETTER. This grammer allows longer names.
Single letter names will still work.
b) Relational_expression allowed only one comparison.
This grammar has added boolean expressions with
&& (and) || (or) and ! (not) and allowed all of them in
full expressions.
c) Added an else to the if.
d) Call by variable array parameters
e) read() procedure that reads a number under program control from stdin.
f) halt statement that halts the the program under program control. It
is an executed statement.
g) continue statement for for loops.
h) optional expressions in the for loop.
i) print statement to print multiple numbers per line.
j) warranty statement to print an extended warranty notice.
j) limits statement to print the processor's limits.
*/
%token <i_value> NEWLINE AND OR NOT
%token <s_value> STRING NAME NUMBER
/* '-', '+' are tokens themselves */
%token <c_value> MUL_OP
/* '*', '/', '%' */
%token <c_value> ASSIGN_OP
/* '=', '+=', '-=', '*=', '/=', '%=', '^=' */
%token <s_value> REL_OP
/* '==', '<=', '>=', '!=', '<', '>' */
%token <c_value> INCR_DECR
/* '++', '--' */
%token <i_value> Define Break Quit Length
/* 'define', 'break', 'quit', 'length' */
%token <i_value> Return For If While Sqrt Else
/* 'return', 'for', 'if', 'while', 'sqrt', 'else' */
%token <i_value> Scale Ibase Obase Auto Read
/* 'scale', 'ibase', 'obase', 'auto', 'read' */
%token <i_value> Warranty, Halt, Last, Continue, Print, Limits
/* 'warranty', 'halt', 'last', 'continue', 'print', 'limits' */
/* Types of all other things. */
%type <i_value> expression return_expression named_expression opt_expression
%type <c_value> '+' '-'
%type <a_value> opt_parameter_list opt_auto_define_list define_list
%type <a_value> opt_argument_list argument_list
%type <i_value> program input_item semicolon_list statement_list
%type <i_value> statement function statement_or_error
/* precedence */
%left OR
%left AND
%nonassoc NOT
%left REL_OP
%right ASSIGN_OP
%left '+' '-'
%left MUL_OP
%right '^'
%nonassoc UNARY_MINUS
%nonassoc INCR_DECR
%%
program : /* empty */
{
$$ = 0;
if (interactive)
{
printf ("%s\n", BC_VERSION);
welcome ();
}
}
| program input_item
;
input_item : semicolon_list NEWLINE
{ run_code (); }
| function
{ run_code (); }
| error NEWLINE
{
yyerrok;
init_gen ();
}
;
semicolon_list : /* empty */
{ $$ = 0; }
| statement_or_error
| semicolon_list ';' statement_or_error
| semicolon_list ';'
;
statement_list : /* empty */
{ $$ = 0; }
| statement_or_error
| statement_list NEWLINE
| statement_list NEWLINE statement_or_error
| statement_list ';'
| statement_list ';' statement
;
statement_or_error : statement
| error statement
{ $$ = $2; }
;
statement : Warranty
{ warranty (""); }
| Limits
{ limits (); }
| expression
{
if ($1 & 2)
warn ("comparison in expression");
if ($1 & 1)
generate ("W");
else
generate ("p");
}
| STRING
{
$$ = 0;
generate ("w");
generate ($1);
free ($1);
}
| Break
{
if (break_label == 0)
yyerror ("Break outside a for/while");
else
{
sprintf (genstr, "J%1d:", break_label);
generate (genstr);
}
}
| Continue
{
warn ("Continue statement");
if (continue_label == 0)
yyerror ("Continue outside a for");
else
{
sprintf (genstr, "J%1d:", continue_label);
generate (genstr);
}
}
| Quit
{ exit (0); }
| Halt
{ generate ("h"); }
| Return
{ generate ("0R"); }
| Return '(' return_expression ')'
{ generate ("R"); }
| For
{
$1 = break_label;
break_label = next_label++;
}
'(' opt_expression ';'
{
if ($4 > 1)
warn ("Comparison in first for expression");
$4 = next_label++;
if ($4 < 0)
sprintf (genstr, "N%1d:", $4);
else
sprintf (genstr, "pN%1d:", $4);
generate (genstr);
}
opt_expression ';'
{
if ($7 < 0) generate ("1");
$7 = next_label++;
sprintf (genstr, "B%1d:J%1d:", $7, break_label);
generate (genstr);
$<i_value>$ = continue_label;
continue_label = next_label++;
sprintf (genstr, "N%1d:", continue_label);
generate (genstr);
}
opt_expression ')'
{
if ($10 > 1)
warn ("Comparison in third for expression");
if ($10 < 0)
sprintf (genstr, "J%1d:N%1d:", $4, $7);
else
sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
generate (genstr);
}
statement
{
sprintf (genstr, "J%1d:N%1d:",
continue_label, break_label);
generate (genstr);
break_label = $1;
continue_label = $<i_value>9;
}
| If '(' expression ')'
{
$3 = if_label;
if_label = next_label++;
sprintf (genstr, "Z%1d:", if_label);
generate (genstr);
}
statement opt_else
{
sprintf (genstr, "N%1d:", if_label);
generate (genstr);
if_label = $3;
}
| While
{
$1 = next_label++;
sprintf (genstr, "N%1d:", $1);
generate (genstr);
}
'(' expression
{
$4 = break_label;
break_label = next_label++;
sprintf (genstr, "Z%1d:", break_label);
generate (genstr);
}
')' statement
{
sprintf (genstr, "J%1d:N%1d:", $1, break_label);
generate (genstr);
break_label = $4;
}
| '{' statement_list '}'
{ $$ = 0; }
| Print
{ warn ("print statement"); }
print_list
;
print_list : print_element
| print_element ',' print_list
;
print_element : STRING
{
generate ("O");
generate ($1);
free ($1);
}
| expression
{ generate ("P"); }
;
opt_else : /* nothing */
| Else
{
warn ("else clause in if statement");
$1 = next_label++;
sprintf (genstr, "J%d:N%1d:", $1, if_label);
generate (genstr);
if_label = $1;
}
statement
function : Define NAME '(' opt_parameter_list ')' '{'
NEWLINE opt_auto_define_list
{
/* Check auto list against parameter list? */
check_params ($4,$8);
sprintf (genstr, "F%d,%s.%s[",
lookup($2,FUNCTDEF),
arg_str ($4), arg_str ($8));
generate (genstr);
free_args ($4);
free_args ($8);
$1 = next_label;
next_label = 1;
}
statement_list /* NEWLINE */ '}'
{
generate ("0R]");
next_label = $1;
}
;
opt_parameter_list : /* empty */
{ $$ = NULL; }
| define_list
;
opt_auto_define_list : /* empty */
{ $$ = NULL; }
| Auto define_list NEWLINE
{ $$ = $2; }
| Auto define_list ';'
{ $$ = $2; }
;
define_list : NAME
{ $$ = nextarg (NULL, lookup ($1,SIMPLE)); }
| NAME '[' ']'
{ $$ = nextarg (NULL, lookup ($1,ARRAY)); }
| define_list ',' NAME
{ $$ = nextarg ($1, lookup ($3,SIMPLE)); }
| define_list ',' NAME '[' ']'
{ $$ = nextarg ($1, lookup ($3,ARRAY)); }
;
opt_argument_list : /* empty */
{ $$ = NULL; }
| argument_list
;
argument_list : expression
{
if ($1 > 1) warn ("comparison in argument");
$$ = nextarg (NULL,0);
}
| NAME '[' ']'
{
sprintf (genstr, "K%d:", -lookup ($1,ARRAY));
generate (genstr);
$$ = nextarg (NULL,1);
}
| argument_list ',' expression
{
if ($3 > 1) warn ("comparison in argument");
$$ = nextarg ($1,0);
}
| argument_list ',' NAME '[' ']'
{
sprintf (genstr, "K%d:", -lookup ($3,ARRAY));
generate (genstr);
$$ = nextarg ($1,1);
}
;
opt_expression : /* empty */
{
$$ = -1;
warn ("Missing expression in for statement");
}
| expression
;
return_expression : /* empty */
{
$$ = 0;
generate ("0");
}
| expression
{
if ($1 > 1)
warn ("comparison in return expresion");
}
;
expression : named_expression ASSIGN_OP
{
if ($2 != '=')
{
if ($1 < 0)
sprintf (genstr, "DL%d:", -$1);
else
sprintf (genstr, "l%d:", $1);
generate (genstr);
}
}
expression
{
if ($4 > 1) warn("comparison in assignment");
if ($2 != '=')
{
sprintf (genstr, "%c", $2);
generate (genstr);
}
if ($1 < 0)
sprintf (genstr, "S%d:", -$1);
else
sprintf (genstr, "s%d:", $1);
generate (genstr);
$$ = 0;
}
;
| expression AND
{
warn("&& operator");
$2 = next_label++;
sprintf (genstr, "DZ%d:p", $2);
generate (genstr);
}
expression
{
sprintf (genstr, "DZ%d:p1N%d:", $2, $2);
generate (genstr);
$$ = $1 | $4;
}
| expression OR
{
warn("|| operator");
$2 = next_label++;
sprintf (genstr, "B%d:", $2);
generate (genstr);
}
expression
{
int tmplab;
tmplab = next_label++;
sprintf (genstr, "B%d:0J%d:N%d:1N%d:",
$2, tmplab, $2, tmplab);
generate (genstr);
$$ = $1 | $4;
}
| NOT expression
{
$$ = $2;
warn("! operator");
generate ("!");
}
| expression REL_OP expression
{
$$ = 3;
switch (*($2))
{
case '=':
generate ("=");
break;
case '!':
generate ("#");
break;
case '<':
if ($2[1] == '=')
generate ("{");
else
generate ("<");
break;
case '>':
if ($2[1] == '=')
generate ("}");
else
generate (">");
break;
}
}
| expression '+' expression
{
generate ("+");
$$ = $1 | $3;
}
| expression '-' expression
{
generate ("-");
$$ = $1 | $3;
}
| expression MUL_OP expression
{
genstr[0] = $2;
genstr[1] = 0;
generate (genstr);
$$ = $1 | $3;
}
| expression '^' expression
{
generate ("^");
$$ = $1 | $3;
}
| '-' expression %prec UNARY_MINUS
{
generate ("n");
$$ = $2;
}
| named_expression
{
$$ = 1;
if ($1 < 0)
sprintf (genstr, "L%d:", -$1);
else
sprintf (genstr, "l%d:", $1);
generate (genstr);
}
| NUMBER
{
int len = strlen($1);
$$ = 1;
if (len == 1 && *$1 == '0')
generate ("0");
else if (len == 1 && *$1 == '1')
generate ("1");
else
{
generate ("K");
generate ($1);
generate (":");
}
free ($1);
}
| '(' expression ')'
{ $$ = $2 | 1; }
| NAME '(' opt_argument_list ')'
{
$$ = 1;
if ($3 != NULL)
{
sprintf (genstr, "C%d,%s:",
lookup ($1,FUNCT),
call_str ($3));
free_args ($3);
}
else
{
sprintf (genstr, "C%d:", lookup ($1,FUNCT));
}
generate (genstr);
}
| INCR_DECR named_expression
{
$$ = 1;
if ($2 < 0)
{
if ($1 == '+')
sprintf (genstr, "DA%d:L%d:", -$2, -$2);
else
sprintf (genstr, "DM%d:L%d:", -$2, -$2);
}
else
{
if ($1 == '+')
sprintf (genstr, "i%d:l%d:", $2, $2);
else
sprintf (genstr, "d%d:l%d:", $2, $2);
}
generate (genstr);
}
| named_expression INCR_DECR
{
$$ = 1;
if ($1 < 0)
{
sprintf (genstr, "DL%d:x", -$1);
generate (genstr);
if ($2 == '+')
sprintf (genstr, "A%d:", -$1);
else
sprintf (genstr, "M%d:", -$1);
}
else
{
sprintf (genstr, "l%d:", $1);
generate (genstr);
if ($2 == '+')
sprintf (genstr, "i%d:", $1);
else
sprintf (genstr, "d%d:", $1);
}
generate (genstr);
}
| Length '(' expression ')'
{ generate ("cL"); $$ = 1;}
| Sqrt '(' expression ')'
{ generate ("cR"); $$ = 1;}
| Scale '(' expression ')'
{ generate ("cS"); $$ = 1;}
| Read '(' ')'
{
warn ("read function");
generate ("cI"); $$ = 1;
}
;
named_expression : NAME
{ $$ = lookup($1,SIMPLE); }
| NAME '[' expression ']'
{
if ($3 > 1) warn("comparison in subscript");
$$ = lookup($1,ARRAY);
}
| Ibase
{ $$ = 0; }
| Obase
{ $$ = 1; }
| Scale
{ $$ = 2; }
| Last
{ $$ = 3;
warn ("Last variable");
}
;
%%

View File

@ -1,7 +1,7 @@
/* bcdefs.h: The single file to include all constants and type definitions. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* const.h: Constants for bc. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -71,9 +71,13 @@
#define FALSE 0
#define TRUE 1
#define SIMPLE 0
#define ARRAY 1
#define FUNCT 2
/* for use with lookup (). */
#define SIMPLE 0
#define ARRAY 1
#define FUNCT 2
#define FUNCTDEF 3
#define EXTERN extern
#ifdef __STDC__
#define CONST const

View File

@ -1,7 +1,7 @@
/* execute.c - run a bc program. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -213,11 +213,13 @@ execute ()
if (ch == '"') break;
switch (ch)
{
case 'n': out_char ('\n'); break;
case 't': out_char ('\t'); break;
case 'r': out_char ('\r'); break;
case 'b': out_char (007); break;
case 'a': out_char (007); break;
case 'b': out_char ('\b'); break;
case 'f': out_char ('\f'); break;
case 'n': out_char ('\n'); break;
case 'q': out_char ('"'); break;
case 'r': out_char ('\r'); break;
case 't': out_char ('\t'); break;
case '\\': out_char ('\\'); break;
default: break;
}

View File

@ -1,7 +1,7 @@
/* global.c: This defines the global variables. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* global.h: The global variables for bc. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -27,24 +27,41 @@
*************************************************************************/
/* For the current "break level" and if statements. */
/* The current break level's label. */
EXTERN int break_label;
/* The current if statement's else label or label after else. */
EXTERN int if_label;
/* The current for statement label for continuing the loop. */
EXTERN int continue_label;
/* Label numbers. */
/* Next available label number. */
EXTERN int next_label;
/* Used for "code" generation. */
/* Byte code character storage. Used in many places for generation of code. */
EXTERN char genstr[80];
/* Count of characters printed to the output in compile_only mode. */
EXTERN int out_count;
/* Have we generated any code since the last initialization of the code
generator. */
EXTERN char did_gen;
/* Interactive and other flags. */
/* Is this run an interactive execution. (Is stdin a terminal?) */
EXTERN char interactive;
/* Just generate the byte code. -c flag. */
EXTERN char compile_only;
/* Load the standard math functions. -l flag. */
EXTERN char use_math;
/* Give a warning on use of any non-standard feature (non-POSIX). -w flag. */
EXTERN char warn_not_std;
/* Accept POSIX bc only! -s flag. */
EXTERN char std_only;
/* global variables for the bc machine. All will be dynamic in size.*/

View File

@ -1,255 +0,0 @@
/* libmath.b for bc for minix. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License , or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
You may contact the author by:
e-mail: phil@cs.wwu.edu
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
scale = 20
/* Uses the fact that e^x = (e^(x/2))^2
When x is small enough, we use the series:
e^x = 1 + x + x^2/2! + x^3/3! + ...
*/
define e(x) {
auto a, d, e, f, i, m, v, z
/* Check the sign of x. */
if (x<0) {
m = 1
x = -x
}
/* Precondition x. */
z = scale;
scale = 4 + z + .44*x;
while (x > 1) {
f += 1;
x /= 2;
}
/* Initialize the variables. */
v = 1+x
a = x
d = 1
for (i=2; 1; i++) {
e = (a *= x) / (d *= i)
if (e == 0) {
if (f>0) while (f--) v = v*v;
scale = z
if (m) return (1/v);
return (v/1);
}
v += e
}
}
/* Natural log. Uses the fact that ln(x^2) = 2*ln(x)
The series used is:
ln(x) = 2(a+a^3/3+a^5/5+...) where a=(x-1)/(x+1)
*/
define l(x) {
auto e, f, i, m, n, v, z
/* return something for the special case. */
if (x <= 0) return (1 - 10^scale)
/* Precondition x to make .5 < x < 2.0. */
z = scale;
scale += 4;
f = 2;
i=0
while (x >= 2) { /* for large numbers */
f *= 2;
x = sqrt(x);
}
while (x <= .5) { /* for small numbers */
f *= 2;
x = sqrt(x);
}
/* Set up the loop. */
v = n = (x-1)/(x+1)
m = n*n
/* Sum the series. */
for (i=3; 1; i+=2) {
e = (n *= m) / i
if (e == 0) {
v = f*v
scale = z
return (v/1)
}
v += e
}
}
/* Sin(x) uses the standard series:
sin(x) = x - x^3/3! + x^5/5! - x^7/7! ... */
define s(x) {
auto e, i, m, n, s, v, z
/* precondition x. */
z = scale
scale = 1.1*z + 1;
v = a(1)
if (x < 0) {
m = 1;
x = -x;
}
scale = 0
n = (x / v + 2 )/4
x = x - 4*n*v
if (n%2) x = -x
/* Do the loop. */
scale = z + 2;
v = e = x
s = -x*x
for (i=3; 1; i+=2) {
e *= s/(i*(i-1))
if (e == 0) {
scale = z
if (m) return (-v/1);
return (v/1);
}
v += e
}
}
/* Cosine : cos(x) = sin(x+pi/2) */
define c(x) {
auto v;
scale += 1;
v = s(x+a(1)*2);
scale -= 1;
return (v/1);
}
/* Arctan: Using the formula:
atan(x) = atan(c) + atan((x-c)/(1+xc)) for a small c (.2 here)
For under .2, use the series:
atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... */
define a(x) {
auto a, e, f, i, m, n, s, v, z
/* Special case and for fast answers */
if (x==1) {
if (scale <= 25) return (.7853981633974483096156608/1)
if (scale <= 40) return (.7853981633974483096156608458198757210492/1)
if (scale <= 60) \
return (.785398163397448309615660845819875721049292349843776455243736/1)
}
if (x==.2) {
if (scale <= 25) return (.1973955598498807583700497/1)
if (scale <= 40) return (.1973955598498807583700497651947902934475/1)
if (scale <= 60) \
return (.197395559849880758370049765194790293447585103787852101517688/1)
}
/* Negative x? */
if (x<0) {
m = 1;
x = -x;
}
/* Save the scale. */
z = scale;
/* Note: a and f are known to be zero due to being auto vars. */
/* Calculate atan of a known number. */
if (x > .2) {
scale = z+4;
a = a(.2);
}
/* Precondition x. */
scale = z+2;
while (x > .2) {
f += 1;
x = (x-.2) / (1+x*.2);
}
/* Initialize the series. */
v = n = x;
s = -x*x;
/* Calculate the series. */
for (i=3; 1; i+=2) {
e = (n *= s) / i;
if (e == 0) {
scale = z;
if (m) return ((f*a+v)/-1);
return ((f*a+v)/1);
}
v += e
}
}
/* Bessel function of integer order. Uses the following:
j(-n,x) = (-1)^n*j(n,x)
j(n,x) = x^n/(2^n*n!) * (1 - x^2/(2^2*1!*(n+1)) + x^4/(2^4*2!*(n+1)*(n+2))
- x^6/(2^6*3!*(n+1)*(n+2)*(n+3)) .... )
*/
define j(n,x) {
auto a, d, e, f, i, m, s, v, z
/* Make n an integer and check for negative n. */
z = scale;
scale = 0;
n = n/1;
if (n<0) {
n = -n;
if (n%2 == 1) m = 1;
}
/* Compute the factor of x^n/(2^n*n!) */
f = 1;
for (i=2; i<=n; i++) f = f*i;
scale = 1.5*z;
f = x^n / 2^n / f;
/* Initialize the loop .*/
v = e = 1;
s = -x*x/4
scale = 1.5*z
/* The Loop.... */
for (i=1; 1; i++) {
e = e * s / i / (n+i);
if (e == 0) {
scale = z
if (m) return (-f*v/1);
return (f*v/1);
}
v += e;
}
}

View File

@ -1,7 +1,7 @@
/* load.c: This code "loads" code into the code segments. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* main.c: The main program for bc. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,40 +1,40 @@
"@iK20:s2:p@r\
@iF1,4.5,6,7,8,9,10,11,12[l4:0<Z0:1s10:pl4:ns4:pN0:l2:s12:pK4\
:l12:+K.44:l4:*+s2:pN1:l4:1>Z2:l8:1+s8:pl4:K2:/s4:pJ1:N2:1l4:\
+s11:pl4:s5:p1s6:pK2:s9:pN4:1B5:J3:N6:l9:i9:pJ4:N5:l5:l4:*s5:\
l6:l9:*s6:/s7:pl7:0=Z7:l8:0>Z8:N9:l8:d8:Z10:l11:l11:*s11:pJ9:N10:\
N8:l12:s2:pl10:Z11:1l11:/RN11:l11:1/RN7:l11:l7:+s11:pJ6:N3:0R]\
@iF1,4.5,6,7,8,9,10,11,12,13[l4:0<Z1:1s10:pl4:ns4:pN1:l2:s13:\
pK6:l13:+K.44:l4:*+s11:pl4:cS1+s2:pN2:l4:1>Z3:l8:1+s8:pl4:K2:\
/s4:pl2:1+s2:pJ2:N3:l11:s2:p1l4:+s12:pl4:s5:p1s6:pK2:s9:pN5:1\
B6:J4:N7:l9:i9:pJ5:N6:l5:l4:*s5:l6:l9:*s6:/s7:pl7:0=Z8:l8:0>Z9:\
N10:l8:d8:Z11:l12:l12:*s12:pJ10:N11:N9:l13:s2:pl10:Z12:1l12:/\
RN12:l12:1/RN8:l12:l7:+s12:pJ7:N4:0R]@r\
@iF2,4.7,8,9,10,11,12,13[l4:0{Z1:1K10:l2:^-RN1:l2:s13:pK6:l2:\
+s2:pK2:s8:p0s9:pN2:l4:K2:}Z3:l8:K2:*s8:pl4:cRs4:pJ2:N3:N4:l4:\
K.5:{Z5:l8:K2:*s8:pl4:cRs4:pJ4:N5:l4:1-l4:1+/s11:s12:pl11:l11:\
*s10:pK3:s9:pN7:1B8:J6:N9:l9:K2:+s9:pJ7:N8:l11:l10:*s11:l9:/s7:\
pl7:0=Z10:l8:l12:*s12:pl13:s2:pl12:1/RN10:l12:l7:+s12:pJ9:N6:\
0R]@r\
@iF3,4.7,9,10,11,14,12,13[l2:s13:pK1.1:l13:*K2:+s2:p1C4,0:s12:\
pl4:0<Z1:1s10:pl4:ns4:pN1:0s2:pl4:l12:/K2:+K4:/s11:pl4:K4:l11:\
*l12:*-s4:pl11:K2:%Z2:l4:ns4:pN2:l13:K2:+s2:pl4:s7:s12:pl4:nl4:\
*s14:pK3:s9:pN4:1B5:J3:N6:l9:K2:+s9:pJ4:N5:l7:l14:l9:l9:1-*/*\
s7:pl7:0=Z7:l13:s2:pl10:Z8:l12:n1/RN8:l12:1/RN7:l12:l7:+s12:p\
J6:N3:0R]@r\
@iF5,4.12[l2:1+s2:pl4:1C4,0:K2:*+C3,0:s12:pl2:1-s2:pl12:1/R0R]\
@r\
@iF2,4.7,8,9,10,13,11,12[l4:0{Z0:1K10:l2:^-RN0:l2:s12:pl2:K4:\
+s2:pK2:s8:p0s9:pN1:l4:K2:}Z2:l8:K2:*s8:pl4:cRs4:pJ1:N2:N3:l4:\
K.5:{Z4:l8:K2:*s8:pl4:cRs4:pJ3:N4:l4:1-l4:1+/s13:s11:pl13:l13:\
*s10:pK3:s9:pN6:1B7:J5:N8:l9:K2:+s9:pJ6:N7:l13:l10:*s13:l9:/s7:\
pl7:0=Z9:l8:l11:*s11:pl12:s2:pl11:1/RN9:l11:l7:+s11:pJ8:N5:0R]\
@r\
@iF3,4.7,9,10,13,14,11,12[l2:s12:pK1.1:l12:*1+s2:p1C4,0:s11:p\
l4:0<Z0:1s10:pl4:ns4:pN0:0s2:pl4:l11:/K2:+K4:/s13:pl4:K4:l13:\
*l11:*-s4:pl13:K2:%Z1:l4:ns4:pN1:l12:K2:+s2:pl4:s7:s11:pl4:nl4:\
*s14:pK3:s9:pN3:1B4:J2:N5:l9:K2:+s9:pJ3:N4:l7:l14:l9:l9:1-*/*\
s7:pl7:0=Z6:l12:s2:pl10:Z7:l11:n1/RN7:l11:1/RN6:l11:l7:+s11:p\
J5:N2:0R]@r\
@iF5,4.11[l2:1+s2:pl4:1C4,0:K2:*+C3,0:s11:pl2:1-s2:pl11:1/R0R]\
@r\
@iF4,4.5,7,8,9,10,13,14,11,12[l4:1=Z0:l2:K25:{Z1:K.7853981633974483096156608\
:1/RN1:l2:K40:{Z2:K.7853981633974483096156608458198757210492:\
1/RN2:l2:K60:{Z3:K.785398163397448309615660845819875721049292349843776455243736\
:1/RN3:N0:l4:K.2:=Z4:l2:K25:{Z5:K.1973955598498807583700497:1\
/RN5:l2:K40:{Z6:K.1973955598498807583700497651947902934475:1/\
RN6:l2:K60:{Z7:K.197395559849880758370049765194790293447585103787852101517688\
:1/RN7:N4:l4:0<Z8:1s10:pl4:ns4:pN8:l2:s12:pl4:K.2:>Z9:l12:K4:\
+s2:pK.2:C4,0:s5:pN9:l12:K2:+s2:pN10:l4:K.2:>Z11:l8:1+s8:pl4:\
K.2:-1l4:K.2:*+/s4:pJ10:N11:l4:s13:s11:pl4:nl4:*s14:pK3:s9:pN13:\
1B14:J12:N15:l9:K2:+s9:pJ13:N14:l13:l14:*s13:l9:/s7:pl7:0=Z16:\
l12:s2:pl10:Z17:l8:l5:*l11:+1n/RN17:l8:l5:*l11:+1/RN16:l11:l7:\
+s11:pJ15:N12:0R]@r\
@iF6,13,4.5,6,7,8,9,10,14,11,12[l2:s12:p0s2:pl13:1/s13:pl13:0\
<Z0:l13:ns13:pl13:K2:%1=Z1:1s10:pN1:N0:1s8:pK2:s9:pN3:l9:l13:\
{B4:J2:N5:l9:i9:pJ3:N4:l8:l9:*s8:pJ5:N2:K1.5:l12:*s2:pl4:l13:\
^K2:l13:^/l8:/s8:p1s7:s11:pl4:nl4:*K4:/s14:pK1.5:l12:*s2:p1s9:\
pN7:1B8:J6:N9:l9:i9:pJ7:N8:l7:l14:*l9:/l13:l9:+/s7:pl7:0=Z10:\
l12:s2:pl10:Z11:l8:nl11:*1/RN11:l8:l11:*1/RN10:l11:l7:+s11:pJ9:N6:\
@iF4,4.5,7,8,9,10,11,14,12,13[1s10:pl4:0<Z1:1ns10:pl4:ns4:pN1:\
l4:1=Z2:l2:K25:{Z3:K.7853981633974483096156608:l10:/RN3:l2:K40\
:{Z4:K.7853981633974483096156608458198757210492:l10:/RN4:l2:K\
60:{Z5:K.785398163397448309615660845819875721049292349843776455243736\
:l10:/RN5:N2:l4:K.2:=Z6:l2:K25:{Z7:K.1973955598498807583700497\
:l10:/RN7:l2:K40:{Z8:K.1973955598498807583700497651947902934475\
:l10:/RN8:l2:K60:{Z9:K.197395559849880758370049765194790293447585103787852101517688\
:l10:/RN9:N6:l2:s13:pl4:K.2:>Z10:l13:K5:+s2:pK.2:C4,0:s5:pN10:\
l13:K3:+s2:pN11:l4:K.2:>Z12:l8:1+s8:pl4:K.2:-1l4:K.2:*+/s4:pJ11:N12:\
l4:s11:s12:pl4:nl4:*s14:pK3:s9:pN14:1B15:J13:N16:l9:K2:+s9:pJ14:N15:\
l11:l14:*s11:l9:/s7:pl7:0=Z17:l13:s2:pl8:l5:*l12:+l10:/RN17:l12:\
l7:+s12:pJ16:N13:0R]@r\
@iF6,11,4.5,6,7,8,9,10,14,12,13[l2:s13:p0s2:pl11:1/s11:pl11:0\
<Z1:l11:ns11:pl11:K2:%1=Z2:1s10:pN2:N1:1s8:pK2:s9:pN4:l9:l11:\
{B5:J3:N6:l9:i9:pJ4:N5:l8:l9:*s8:pJ6:N3:K1.5:l13:*s2:pl4:l11:\
^K2:l11:^/l8:/s8:p1s7:s12:pl4:nl4:*K4:/s14:pK1.5:l13:*s2:p1s9:\
pN8:1B9:J7:N10:l9:i9:pJ8:N9:l7:l14:*l9:/l11:l9:+/s7:pl7:0=Z11:\
l13:s2:pl10:Z12:l8:nl12:*1/RN12:l8:l12:*1/RN11:l12:l7:+s12:pJ10:N7:\
0R]@r"

View File

@ -1,7 +1,7 @@
/* number.c: Implements arbitrary precision numbers. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -995,15 +995,23 @@ bc_raise (num1, num2, result, scale)
neg = FALSE;
rscale = MIN (num1->n_scale*exponent, MAX(scale, num1->n_scale));
}
temp = copy_num (_one_);
/* Set initial value of temp. */
power = copy_num (num1);
while ((exponent & 1) == 0)
{
bc_multiply (power, power, &power, rscale);
exponent = exponent >> 1;
}
temp = copy_num (power);
exponent = exponent >> 1;
/* Do the calculation. */
while (exponent != 0)
while (exponent > 0)
{
if (exponent & 1 != 0)
bc_multiply (temp, power, &temp, rscale);
bc_multiply (power, power, &power, rscale);
if ((exponent & 1) == 1)
bc_multiply (temp, power, &temp, rscale);
exponent = exponent >> 1;
}
@ -1057,7 +1065,6 @@ bc_sqrt (num, scale)
/* Initialize the variables. */
rscale = MAX (scale, (*num)->n_scale);
cscale = rscale + 2;
init_num (&guess);
init_num (&guess1);
point5 = new_num (1,1);
@ -1073,14 +1080,15 @@ bc_sqrt (num, scale)
/* The number is greater than 1. Guess should start at 10^(exp/2). */
int2num (&guess,10);
int2num (&guess1,(*num)->n_len);
bc_multiply (guess1, point5, &guess1, rscale);
bc_multiply (guess1, point5, &guess1, 0);
guess1->n_scale = 0;
bc_raise (guess, guess1, &guess, rscale);
bc_raise (guess, guess1, &guess, 0);
free_num (&guess1);
}
/* Find the square root using Newton's algorithm. */
done = FALSE;
cscale = 2;
while (!done)
{
free_num (&guess1);
@ -1089,7 +1097,11 @@ bc_sqrt (num, scale)
bc_add (guess,guess1,&guess);
bc_multiply (guess,point5,&guess,cscale);
cmp_res = _do_compare (guess,guess1,FALSE,TRUE);
if (cmp_res == 0) done = TRUE;
if (cmp_res == 0)
if (cscale < rscale+1)
cscale = MIN (cscale*3, rscale+1);
else
done = TRUE;
}
/* Assign the number and clean up. */
@ -1198,6 +1210,9 @@ out_num (num, o_base, out_char)
init_num (&cur_dig);
init_num (&base);
bc_sub (num, int_part, &frac_part);
/* Make the INT_PART and FRAC_PART positive. */
int_part->n_sign = PLUS;
frac_part->n_sign = PLUS;
int2num (&base, o_base);
init_num (&max_o_digit);
int2num (&max_o_digit, o_base-1);
@ -1273,7 +1288,6 @@ p_n (num)
bc_num num;
{
out_num (num, 10, out_char);
return 0;
}

View File

@ -1,7 +1,7 @@
/* number.h: Arbitrary precision numbers header file. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* proto.h: Prototype function definitions for "external" functions. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -70,7 +70,8 @@ _PROTOTYPE(void assign, (int c_code));
/* From util.c */
_PROTOTYPE(char *strcopyof, (char *str));
_PROTOTYPE(arg_list *nextarg, (arg_list *args, int val));
_PROTOTYPE(char *arg_str, (arg_list *args, int));
_PROTOTYPE(char *arg_str, (arg_list *args));
_PROTOTYPE(char *call_str, (arg_list *args));
_PROTOTYPE(void free_args, (arg_list *args));
_PROTOTYPE(void check_params, (arg_list *params, arg_list *autos));
_PROTOTYPE(void init_gen, (void));

File diff suppressed because it is too large Load Diff

196
gnu/usr.bin/bc/scan.l Normal file
View File

@ -0,0 +1,196 @@
%{
/* scan.l: the (f)lex description file for the scanner. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License , or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
You may contact the author by:
e-mail: phil@cs.wwu.edu
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include "bcdefs.h"
#include "y.tab.h"
#include "global.h"
#include "proto.h"
/* Using flex, we can ask for a smaller input buffer. With lex, this
does nothing! */
#ifdef SMALL_BUF
#undef YY_READ_BUF_SIZE
#define YY_READ_BUF_SIZE 512
#endif
/* We want to define our own yywrap. */
#undef yywrap
_PROTOTYPE(int yywrap, (void));
/* MINIX returns from read with < 0 if SIGINT is encountered.
In flex, we can redefine YY_INPUT to the following. In lex, this
does nothing! */
#include <errno.h>
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
if (errno != EINTR) \
YY_FATAL_ERROR( "read() in flex scanner failed" );
%}
DIGIT [0-9A-F]
LETTER [a-z]
%%
define return(Define);
break return(Break);
quit return(Quit);
length return(Length);
return return(Return);
for return(For);
if return(If);
while return(While);
sqrt return(Sqrt);
scale return(Scale);
ibase return(Ibase);
obase return(Obase);
auto return(Auto);
else return(Else);
read return(Read);
halt return(Halt);
last return(Last);
warranty return(Warranty);
continue return(Continue);
print return(Print);
limits return(Limits);
"." {
#ifdef DOT_IS_LAST
return(Last);
#else
yyerror ("illegal character: %s",yytext);
#endif
}
"+"|"-"|";"|"("|")"|"{"|"}"|"["|"]"|","|"^" { yylval.c_value = yytext[0];
return((int)yytext[0]); }
&& { return(AND); }
\|\| { return(OR); }
"!" { return(NOT); }
"*"|"/"|"%" { yylval.c_value = yytext[0]; return(MUL_OP); }
"="|\+=|-=|\*=|\/=|%=|\^= { yylval.c_value = yytext[0]; return(ASSIGN_OP); }
=\+|=-|=\*|=\/|=%|=\^ {
#ifdef OLD_EQ_OP
char warn_save;
warn_save = warn_not_std;
warn_not_std = TRUE;
warn ("Old fashioned =<op>");
warn_not_std = warn_save;
yylval.c_value = yytext[1];
#else
yylval.c_value = '=';
yyless (1);
#endif
return(ASSIGN_OP);
}
==|\<=|\>=|\!=|"<"|">" { yylval.s_value = strcopyof(yytext); return(REL_OP); }
\+\+|-- { yylval.c_value = yytext[0]; return(INCR_DECR); }
"\n" { line_no++; return(NEWLINE); }
\\\n { line_no++; /* ignore a "quoted" newline */ }
[ \t]+ { /* ignore spaces and tabs */ }
"/*" {
int c;
for (;;)
{
while ( ((c=input()) != '*') && (c != EOF))
/* eat it */
if (c == '\n') line_no++;
if (c == '*')
{
while ( (c=input()) == '*') /* eat it*/;
if (c == '/') break; /* at end of comment */
if (c == '\n') line_no++;
}
if (c == EOF)
{
fprintf (stderr,"EOF encountered in a comment.\n");
break;
}
}
}
[a-z][a-z0-9_]* { yylval.s_value = strcopyof(yytext); return(NAME); }
\"[^\"]*\" {
unsigned char *look;
int count = 0;
yylval.s_value = strcopyof(yytext);
for (look = yytext; *look != 0; look++)
{
if (*look == '\n') line_no++;
if (*look == '"') count++;
}
if (count != 2) yyerror ("NUL character in string.");
return(STRING);
}
{DIGIT}({DIGIT}|\\\n)*("."({DIGIT}|\\\n)*)?|"."(\\\n)*{DIGIT}({DIGIT}|\\\n)* {
unsigned char *src, *dst;
int len;
/* remove a trailing decimal point. */
len = strlen(yytext);
if (yytext[len-1] == '.')
yytext[len-1] = 0;
/* remove leading zeros. */
src = yytext;
dst = yytext;
while (*src == '0') src++;
if (*src == 0) src--;
/* Copy strings removing the newlines. */
while (*src != 0)
{
if (*src == '\\')
{
src++; src++;
line_no++;
}
else
*dst++ = *src++;
}
*dst = 0;
yylval.s_value = strcopyof(yytext);
return(NUMBER);
}
. {
if (yytext[0] < ' ')
yyerror ("illegal character: ^%c",yytext[0] + '@');
else
if (yytext[0] > '~')
yyerror ("illegal character: \\%3d", (int) yytext[0]);
else
yyerror ("illegal character: %s",yytext);
}
%%
/* This is the way to get multiple files input into lex. */
int
yywrap()
{
if (!open_new_file ()) return (1); /* EOF on standard in. */
return (0); /* We have more input. */
}

View File

@ -1,7 +1,7 @@
/* storage.c: Code and data storage manipulations. This includes labels. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -895,7 +895,6 @@ process_params (pc, func)
{
char ch;
arg_list *params;
char warned = FALSE;
int ix, ix1;
bc_var *v_temp;
bc_var_array *a_src, *a_dest;
@ -954,11 +953,8 @@ process_params (pc, func)
}
else
{
if (!warned)
{
rt_error ("Parameter number mismatch");
warned = TRUE;
}
rt_error ("Parameter number mismatch");
return;
}
params = params->next;
}

View File

@ -1,7 +1,7 @@
/* util.c: Utility routines for bc. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -56,7 +56,7 @@ strcopyof (str)
arg_list *
nextarg (args, val)
arg_list *args;
char val;
int val;
{ arg_list *temp;
temp = (arg_list *) bc_malloc (sizeof (arg_list));
@ -77,23 +77,22 @@ static char *arglist1 = NULL, *arglist2 = NULL;
/* make_arg_str does the actual construction of the argument string.
ARGS is the pointer to the list and LEN is the maximum number of
characters needed. 1 char is the minimum needed. COMMAS tells
if each number should be seperated by commas.*/
characters needed. 1 char is the minimum needed.
*/
_PROTOTYPE (static char *make_arg_str, (arg_list *args, int len, int commas));
_PROTOTYPE (static char *make_arg_str, (arg_list *args, int len));
static char *
make_arg_str (args, len, commas)
make_arg_str (args, len)
arg_list *args;
int len;
int commas;
{
char *temp;
char sval[20];
/* Recursive call. */
if (args != NULL)
temp = make_arg_str (args->next, len+11, commas);
temp = make_arg_str (args->next, len+11);
else
{
temp = (char *) bc_malloc (len);
@ -102,7 +101,7 @@ make_arg_str (args, len, commas)
}
/* Add the current number to the end of the string. */
if (len != 1 && commas)
if (len != 1)
sprintf (sval, "%d,", args->av_name);
else
sprintf (sval, "%d", args->av_name);
@ -111,17 +110,38 @@ make_arg_str (args, len, commas)
}
char *
arg_str (args, commas)
arg_str (args)
arg_list *args;
int commas;
{
if (arglist2 != NULL)
free (arglist2);
arglist2 = arglist1;
arglist1 = make_arg_str (args, 1, commas);
arglist1 = make_arg_str (args, 1);
return (arglist1);
}
char *
call_str (args)
arg_list *args;
{
arg_list *temp;
int arg_count;
int ix;
if (arglist2 != NULL)
free (arglist2);
arglist2 = arglist1;
/* Count the number of args and add the 0's and 1's. */
for (temp = args, arg_count = 0; temp != NULL; temp = temp->next)
arg_count++;
arglist1 = (char *) bc_malloc(arg_count+1);
for (temp = args, ix=0; temp != NULL; temp = temp->next)
arglist1[ix++] = ( temp->av_name ? '1' : '0');
arglist1[ix] = 0;
return (arglist1);
}
/* free_args frees an argument list ARGS. */
@ -522,9 +542,13 @@ lookup (name, namekind)
exit (1);
case FUNCT:
case FUNCTDEF:
if (id->f_name != 0)
{
free(name);
/* Check to see if we are redefining a math lib function. */
if (use_math && namekind == FUNCTDEF && id->f_name <= 6)
id->f_name = next_func++;
return (id->f_name);
}
id->f_name = next_func++;

View File

@ -1,3 +1,3 @@
#define BC_VERSION \
"bc 1.02 (Mar 3, 92) Copyright (C) 1991, 1992 Free Software Foundation, Inc."
"bc 1.03 (Nov 2, 1994)\nCopyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc."

View File

@ -1,40 +0,0 @@
#define NEWLINE 257
#define AND 258
#define OR 259
#define NOT 260
#define STRING 261
#define NAME 262
#define NUMBER 263
#define MUL_OP 264
#define ASSIGN_OP 265
#define REL_OP 266
#define INCR_DECR 267
#define Define 268
#define Break 269
#define Quit 270
#define Length 271
#define Return 272
#define For 273
#define If 274
#define While 275
#define Sqrt 276
#define Else 277
#define Scale 278
#define Ibase 279
#define Obase 280
#define Auto 281
#define Read 282
#define Warranty 283
#define Halt 284
#define Last 285
#define Continue 286
#define Print 287
#define Limits 288
#define UNARY_MINUS 289
typedef union {
char *s_value;
char c_value;
int i_value;
arg_list *a_value;
} YYSTYPE;
extern YYSTYPE yylval;