diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1998-06-29 00:51:30 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1998-06-29 00:51:30 +0000 |
commit | ecd2252f547ee1e4c798be74469378b7e333f8e4 (patch) | |
tree | 1a8a9be32843405a0b4e446b153453604a89b79d /gnu/usr.bin/bc | |
parent | 17f40ae3b5d3f09b1f529164b0ced8f5b95f2388 (diff) |
remove files from old dir setup
Diffstat (limited to 'gnu/usr.bin/bc')
-rw-r--r-- | gnu/usr.bin/bc/Install | 85 | ||||
-rw-r--r-- | gnu/usr.bin/bc/Makefile | 17 | ||||
-rw-r--r-- | gnu/usr.bin/bc/README.NetBSD | 8 | ||||
-rw-r--r-- | gnu/usr.bin/bc/VERSION | 1 | ||||
-rw-r--r-- | gnu/usr.bin/bc/bc.1 | 733 | ||||
-rw-r--r-- | gnu/usr.bin/bc/bc.y | 617 | ||||
-rw-r--r-- | gnu/usr.bin/bc/bcdefs.h | 156 | ||||
-rw-r--r-- | gnu/usr.bin/bc/config.h | 47 | ||||
-rw-r--r-- | gnu/usr.bin/bc/const.h | 93 | ||||
-rw-r--r-- | gnu/usr.bin/bc/execute.c | 788 | ||||
-rw-r--r-- | gnu/usr.bin/bc/fix_libmath.h | 8 | ||||
-rw-r--r-- | gnu/usr.bin/bc/global.c | 44 | ||||
-rw-r--r-- | gnu/usr.bin/bc/global.h | 125 | ||||
-rw-r--r-- | gnu/usr.bin/bc/libmath.b | 281 | ||||
-rw-r--r-- | gnu/usr.bin/bc/libmath.h | 40 | ||||
-rw-r--r-- | gnu/usr.bin/bc/load.c | 335 | ||||
-rw-r--r-- | gnu/usr.bin/bc/main.c | 206 | ||||
-rw-r--r-- | gnu/usr.bin/bc/number.c | 1422 | ||||
-rw-r--r-- | gnu/usr.bin/bc/number.h | 60 | ||||
-rw-r--r-- | gnu/usr.bin/bc/proto.h | 168 | ||||
-rw-r--r-- | gnu/usr.bin/bc/sbc.y | 450 | ||||
-rw-r--r-- | gnu/usr.bin/bc/scan.l | 198 | ||||
-rw-r--r-- | gnu/usr.bin/bc/storage.c | 965 | ||||
-rw-r--r-- | gnu/usr.bin/bc/util.c | 820 | ||||
-rw-r--r-- | gnu/usr.bin/bc/version.h | 5 | ||||
-rw-r--r-- | gnu/usr.bin/bc/vfprintf.c | 13 |
26 files changed, 0 insertions, 7685 deletions
diff --git a/gnu/usr.bin/bc/Install b/gnu/usr.bin/bc/Install deleted file mode 100644 index d8afa09b211..00000000000 --- a/gnu/usr.bin/bc/Install +++ /dev/null @@ -1,85 +0,0 @@ - -INSTALLATION for GNU bc version 1.03 (Including GNU dc.) ---------------------------------------------------------- - - a) Make sure you have a working vsprintf and vfprintf in your library. - (If your system does not have them in your library, you can get - one of several stdio packages that are freely copyable. The GNU - libc has a complete stdio package. For Minix 1.5 systems, - a vsprintf.c is included.) - - b) run "configure" with the "standard" options for a configure of gnu - products. The major parameter for bc is the "--prefix=path" - option to find the executable and manual directories. For more help, - give the command "configure --help". - - c) "make derived" (If you need it.) - The distribution contains the files bc.c.dist y.tab.h.dist and - scan.c.dist. These are provided so that you do not need a working - yacc and flex (lex). This program was designed to work with the free - programs byacc (berkeley yacc) and flex. It should work with other - versions of yacc and lex, but it is not guaranteed to work. - - If you do not have yacc or flex, give the command "make derived" to - get the *.dist files to their proper place. This insures that make - will not try to make these derived files from their original source. - Use the "make derived" before trying to compile bc and dc. - - e) "make" - compiles bc and dc. - - f) "make install" - installs bc, dc, libmath.b (if needed), bc.1, dc.1 and dc.info - in their proper directories. - - g) Use bc and dc! - - -DEFINES -------- - - The following defines you may or may not want. To delete one standardly on, - edit the Makefile.in. If you want add their definitions, put their - definition in an environment variable "CFLAGS" for the configure script. - - -DOLD_EQ_OP - Causes bc to recognize =<op> as the same as <op>=. The =<op> is - the old style. It makes "a =- 1" ambiguous. With OLD_EQ_OP defined - it is equivalent to "a -= 1" and with OLD_EQ_OP undefined it is - equivalent to "a = -1". - - -DDOT_IS_LAST - Causes bc to recognize a single period (".") as a shorthand notation - for the standard variable "last". (This is standardly defined.) - - -DSMALL_BUF - Use this IF you are using flex AND you have a systems with limited - memory space. - - -DSHORTNAMES - If your compiler keeps a limited number of characters from names, - you should include this define. It is needed for the K&R compiler - on MINIX. - - -DDEBUG=n - Compile the debugging code. The higher the number, the more - debugging code. The degugging code is not very good. - - -POSSIBLE PROBLEMS ------------------ - - There might be some possible problems compiling due to different - versions of the header files. scan.c may require to edit out some - definitions of malloc and free. Others should compile with the - correct set of defines. - - Hopefully, the autoconf/configure system should remove all problems. - - If you do a "make realclean", it removes all files that can be derived - from some other files. This also removes the file "libmath.h" that - is used by the configure script. Without it there, the configure - script makes wrong assumptions about the abilities of your compiler. - To get things back to the point where configure works well you will - need to "make libmath.h", "make distclean" and then run configure again. - diff --git a/gnu/usr.bin/bc/Makefile b/gnu/usr.bin/bc/Makefile deleted file mode 100644 index 4185bdeb4bf..00000000000 --- a/gnu/usr.bin/bc/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $NetBSD: Makefile,v 1.9 1994/12/02 00:43:17 phil Exp $ - -SUBDIR= bcwrap - -PROG= gnubc -CFLAGS+=-D_POSIX_SOURCE -DDOT_IS_LAST -I. -I${.CURDIR} -LFLAGS+=-I8 -SRCS= bc.c scan.c util.c main.c number.c storage.c load.c execute.c global.c -MAN= bc.1 - -LDADD+= -ll -DPADD+= ${LIBL} - -CLEANFILES+= bc.c scan.c y.tab.h - -.include <bsd.prog.mk> -.include <bsd.subdir.mk> diff --git a/gnu/usr.bin/bc/README.NetBSD b/gnu/usr.bin/bc/README.NetBSD deleted file mode 100644 index 4c4185d44c5..00000000000 --- a/gnu/usr.bin/bc/README.NetBSD +++ /dev/null @@ -1,8 +0,0 @@ -This is GNU bc 1.03. - -The original GNU distribution included GNU dc in the same distribution. -GNU dc part is found in the NetBSD source tree in /usr/src/gnu/usr.bin/dc. - -With all the files located in the bc and dc directories, an "original" -bc-1.03 distribution could be regenerated. (It require GNU autoconf 2.0.) - diff --git a/gnu/usr.bin/bc/VERSION b/gnu/usr.bin/bc/VERSION deleted file mode 100644 index f1ad6a77cb6..00000000000 --- a/gnu/usr.bin/bc/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.03 diff --git a/gnu/usr.bin/bc/bc.1 b/gnu/usr.bin/bc/bc.1 deleted file mode 100644 index 5fc6296ab77..00000000000 --- a/gnu/usr.bin/bc/bc.1 +++ /dev/null @@ -1,733 +0,0 @@ -.\" -*- nroff -*- -.\" $NetBSD: bc.1,v 1.4 1994/12/02 00:43:22 phil Exp $ -.\" -.\" bc.1 - the *roff document processor source for the bc manual -.\" -.\" 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 -.\" 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 -.\" -.\" -.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.03. -.SH DESCRIPTION -\fBbc\fR is a language that supports arbitrary precision numbers -with interactive execution of statements. There are some similarities -in the syntax to the C programming language. -A standard math library is available by command line option. -If requested, the math library is defined before processing any files. -\fBbc\fR starts by processing code from all the files listed -on the command line in the order listed. After all files have been -processed, \fBbc\fR reads from the standard input. All code is -executed as it is read. (If a file contains a command to halt the -processor, \fBbc\fR will never read from the standard input.) -.PP -This version of \fBbc\fR contains several extensions beyond -traditional \fBbc\fR implementations and the POSIX draft standard. -Command line options can cause these extensions to print a warning -or to be rejected. This -document describes the language accepted by this processor. -Extensions will be identified as such. -.SS OPTIONS -.IP -l -Define the standard math library. -.IP -w -Give warnings for extensions to POSIX \fBbc\fR. -.IP -s -Process exactly the POSIX \fBbc\fR language. -.SS NUMBERS -The most basic element in \fBbc\fR is the number. Numbers are -arbitrary precision numbers. This precision is both in the integer -part and the fractional part. All numbers are represented internally -in decimal and all computation is done in decimal. (This version -truncates results from divide and multiply operations.) There are two -attributes of numbers, the length and the scale. The length is the -total number of significant decimal digits in a number and the scale -is the total number of decimal digits after the decimal point. For -example: -.nf -.RS - .000001 has a length of 6 and scale of 6. - 1935.000 has a length of 7 and a scale of 3. -.RE -.fi -.SS VARIABLES -Numbers are stored in two types of variables, simple variables and -arrays. Both simple variables and array variables are named. Names -begin with a letter followed by any number of letters, digits and -underscores. All letters must be lower case. (Full alpha-numeric -names are an extension. In POSIX \fBbc\fR all names are a single -lower case letter.) The type of variable is clear by the context -because all array variable names will be followed by brackets ([]). -.PP -There are four special variables, \fBscale, ibase, obase,\fR and -\fBlast\fR. \fBscale\fR defines how some operations use digits after the -decimal point. The default value of \fBscale\fR is 0. \fBibase\fR -and \fBobase\fR define the conversion base for input and output -numbers. The default for both input and output is base 10. -\fBlast\fR (an extension) is a variable that has the value of the last -printed number. These will be discussed in further detail where -appropriate. All of these variables may have values assigned to them -as well as used in expressions. -.SS COMMENTS -Comments in \fBbc\fR start with the characters \fB/*\fR and end with -the characters \fB*/\fR. Comments may start anywhere and appear as a -single space in the input. (This causes comments to delimit other -input items. For example, a comment can not be found in the middle of -a variable name.) Comments include any newlines (end of line) between -the start and the end of the comment. -.SS EXPRESSIONS -The numbers are manipulated by expressions and statements. Since -the language was designed to be interactive, statements and expressions -are executed as soon as possible. There is no "main" program. Instead, -code is executed as it is encountered. (Functions, discussed in -detail later, are defined when encountered.) -.PP -A simple expression is just a constant. \fBbc\fR converts constants -into internal decimal numbers using the current input base, specified -by the variable \fBibase\fR. (There is an exception in functions.) -The legal values of \fBibase\fR are 2 through 16 (F). Assigning a -value outside this range to \fBibase\fR will result in a value of 2 -or 16. Input numbers may contain the characters 0-9 and A-F. (Note: -They must be capitals. Lower case letters are variable names.) -Single digit numbers always have the value of the digit regardless of -the value of \fBibase\fR. (i.e. A = 10.) For multi-digit numbers, -\fBbc\fR changes all input digits greater or equal to ibase to the -value of \fBibase\fR-1. This makes the number \fBFFF\fR always be -the largest 3 digit number of the input base. -.PP -Full expressions are similar to many other high level languages. -Since there is only one kind of number, there are no rules for mixing -types. Instead, there are rules on the scale of expressions. Every -expression has a scale. This is derived from the scale of original -numbers, the operation performed and in many cases, the value of the -variable \fBscale\fR. Legal values of the variable \fBscale\fR are -0 to the maximum number representable by a C integer. -.PP -In the following descriptions of legal expressions, "expr" refers to a -complete expression and "var" refers to a simple or an array variable. -A simple variable is just a -.RS -\fIname\fR -.RE -and an array variable is specified as -.RS -\fIname\fR[\fIexpr\fR] -.RE -Unless specifically -mentioned the scale of the result is the maximum scale of the -expressions involved. -.IP "- expr" -The result is the negation of the expression. -.IP "++ var" -The variable is incremented by one and the new value is the result of -the expression. -.IP "-- var" -The variable -is decremented by one and the new value is the result of the -expression. -.IP "var ++" - The result of the expression is the value of -the variable and then the variable is incremented by one. -.IP "var --" -The result of the expression is the value of the variable and then -the variable is decremented by one. -.IP "expr + expr" -The result of the expression is the sum of the two expressions. -.IP "expr - expr" -The result of the expression is the difference of the two expressions. -.IP "expr * expr" -The result of the expression is the product of the two expressions. -.IP "expr / expr" -The result of the expression is the quotient of the two expressions. -The scale of the result is the value of the variable \fBscale\fR. -.IP "expr % expr" -The result of the expression is the "remainder" and it is computed in the -following way. To compute a%b, first a/b is computed to \fBscale\fR -digits. That result is used to compute a-(a/b)*b to the scale of the -maximum of \fBscale\fR+scale(b) and scale(a). If \fBscale\fR is set -to zero and both expressions are integers this expression is the -integer remainder function. -.IP "expr ^ expr" -The result of the expression is the value of the first raised to the -second. The second expression must be an integer. (If the second -expression is not an integer, a warning is generated and the -expression is truncated to get an integer value.) The scale of the -result is \fBscale\fR if the exponent is negative. If the exponent -is positive the scale of the result is the minimum of the scale of the -first expression times the value of the exponent and the maximum of -\fBscale\fR and the scale of the first expression. (e.g. scale(a^b) -= min(scale(a)*b, max( \fBscale,\fR scale(a))).) It should be noted -that expr^0 will always return the value of 1. -.IP "( expr )" -This alters the standard precedence to force the evaluation of the -expression. -.IP "var = expr" -The variable is assigned the value of the expression. -.IP "var <op>= expr" -This is equivalent to "var = var <op> expr" with the exception that -the "var" part is evaluated only once. This can make a difference if -"var" is an array. -.PP - Relational expressions are a special kind of expression -that always evaluate to 0 or 1, 0 if the relation is false and 1 if -the relation is true. These may appear in any legal expression. -(POSIX bc requires that relational expressions are used only in if, -while, and for statements and that only one relational test may be -done in them.) The relational operators are -.IP "expr1 < expr2" -The result is 1 if expr1 is strictly less than expr2. -.IP "expr1 <= expr2" -The result is 1 if expr1 is less than or equal to expr2. -.IP "expr1 > expr2" -The result is 1 if expr1 is strictly greater than expr2. -.IP "expr1 >= expr2" -The result is 1 if expr1 is greater than or equal to expr2. -.IP "expr1 == expr2" -The result is 1 if expr1 is equal to expr2. -.IP "expr1 != expr2" -The result is 1 if expr1 is not equal to expr2. -.PP -Boolean operations are also legal. (POSIX \fBbc\fR does NOT have -boolean operations). The result of all boolean operations are 0 and 1 -(for false and true) as in relational expressions. The boolean -operators are: -.IP "!expr" -The result is 1 if expr is 0. -.IP "expr && expr" -The result is 1 if both expressions are non-zero. -.IP "expr || expr" -The result is 1 if either expression is non-zero. -.PP -The expression precedence is as follows: (lowest to highest) -.nf -.RS -|| operator, left associative -&& operator, left associative -! operator, nonassociative -Relational operators, left associative -Assignment operator, right associative -+ and - operators, left associative -*, / and % operators, left associative -^ operator, right associative -unary - operator, nonassociative -++ and -- operators, nonassociative -.RE -.fi -.PP -This precedence was chosen so that POSIX compliant \fBbc\fR programs -will run correctly. This will cause the use of the relational and -logical operators to have some unusual behavior when used with -assignment expressions. Consider the expression: -.RS -a = 3 < 5 -.RE -.PP -Most C programmers would assume this would assign the result of "3 < -5" (the value 1) to the variable "a". What this does in \fBbc\fR is -assign the value 3 to the variable "a" and then compare 3 to 5. It is -best to use parenthesis when using relational and logical operators -with the assignment operators. -.PP -There are a few more special expressions that are provided in \fBbc\fR. -These have to do with user defined functions and standard -functions. They all appear as "\fIname\fB(\fIparameters\fB)\fR". -See the section on functions for user defined functions. The standard -functions are: -.IP "length ( expression )" -The value of the length function is the number of significant digits in the -expression. -.IP "read ( )" -The read function (an extension) will read a number from the standard -input, regardless of where the function occurs. Beware, this can -cause problems with the mixing of data and program in the standard input. -The best use for this function is in a previously written program that -needs input from the user, but never allows program code to be input -from the user. The value of the read function is the number read from -the standard input using the current value of the variable -\fBibase\fR for the conversion base. -.IP "scale ( expression )" -The value of the scale function is the number of digits after the decimal -point in the expression. -.IP "sqrt ( expression )" -The value of the sqrt function is the square root of the expression. If -the expression is negative, a run time error is generated. -.SS STATEMENTS -Statements (as in most algebraic languages) provide the sequencing of -expression evaluation. In \fBbc\fR statements are executed "as soon -as possible." Execution happens when a newline in encountered and -there is one or more complete statements. Due to this immediate -execution, newlines are very important in \fBbc\fR. In fact, both a -semicolon and a newline are used as statement separators. An -improperly placed newline will cause a syntax error. Because newlines -are statement separators, it is possible to hide a newline by using -the backslash character. The sequence "\e<nl>", where <nl> is the -newline appears to \fBbc\fR as whitespace instead of a newline. A -statement list is a series of statements separated by semicolons and -newlines. The following is a list of \fBbc\fR statements and what -they do: (Things enclosed in brackets ([]) are optional parts of the -statement.) -.IP "expression" -This statement does one of two things. If the expression starts with -"<variable> <assignment> ...", it is considered to be an assignment -statement. If the expression is not an assignment statement, the -expression is evaluated and printed to the output. After the number -is printed, a newline is printed. For example, "a=1" is an assignment -statement and "(a=1)" is an expression that has an embedded -assignment. All numbers that are printed are printed in the base -specified by the variable \fBobase\fR. The legal values for \fB -obase\fR are 2 through BC_BASE_MAX. (See the section LIMITS.) For -bases 2 through 16, the usual method of writing numbers is used. For -bases greater than 16, \fBbc\fR uses a multi-character digit method -of printing the numbers where each higher base digit is printed as a -base 10 number. The multi-character digits are separated by spaces. -Each digit contains the number of characters required to represent the -base ten value of "obase-1". Since numbers are of arbitrary -precision, some numbers may not be printable on a single output line. -These long numbers will be split across lines using the "\e" as the -last character on a line. The maximum number of characters printed -per line is 70. Due to the interactive nature of \fBbc\fR printing -a number cause the side effect of assigning the printed value the -special variable \fBlast\fR. This allows the user to recover the -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. (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. -All characters are take literally, including any newline. No newline -character is printed after the string. -.IP "\fBprint\fR list" -The print statement (an extension) provides another method of output. -The "list" is a list of strings and expressions separated by commas. -Each string or expression is printed in the order of the list. No -terminating newline is printed. Expressions are evaluated and their -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 -"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. -.IP "\fBif\fR ( expression ) \fBthen\fR statement1 [\fBelse\fR statement2]" -The if statement evaluates the expression and executes statement1 or -statement2 depending on the value of the expression. If the expression -is non-zero, statement1 is executed. If statement2 is present and -the value of the expression is 0, then statement2 is executed. (The -else clause is an extension.) -.IP "\fBwhile\fR ( expression ) statement" -The while statement will execute the statement while the expression -is non-zero. It evaluates the expression before each execution of -the statement. Termination of the loop is caused by a zero -expression value or the execution of a break statement. -.IP "\fBfor\fR ( [expression1] ; [expression2] ; [expression3] ) statement" -The for statement controls repeated execution of the statement. -Expression1 is evaluated before the loop. Expression2 is evaluated -before each execution of the statement. If it is non-zero, the statement -is evaluated. If it is zero, the loop is terminated. After each -execution of the statement, expression3 is evaluated before the reevaluation -of expression2. If expression1 or expression3 are missing, nothing is -evaluated at the point they would be evaluated. -If expression2 is missing, it is the same as substituting -the value 1 for expression2. (The optional expressions are an -extension. POSIX \fBbc\fR requires all three expressions.) -The following is equivalent code for the for statement: -.nf -.RS -expression1; -while (expression2) { - statement; - expression3; -} -.RE -.fi -.IP "\fBbreak\fR" -This statement causes a forced exit of the most recent enclosing while -statement or for statement. -.IP "\fBcontinue\fR" -The continue statement (an extension) causes the most recent enclosing -for statement to start the next iteration. -.IP "\fBhalt\fR" -The halt statement (an extension) is an executed statement that causes -the \fBbc\fR processor to quit only when it is executed. For example, -"if (0 == 1) halt" will not cause \fBbc\fR to terminate because the halt is -not executed. -.IP "\fBreturn\fR" -Return the value 0 from a function. (See the section on functions.) -.IP "\fBreturn\fR ( expression )" -Return the value of the expression from a function. (See the section on -functions.) -.SS PSEUDO STATEMENTS -These statements are not statements in the traditional sense. They are -not executed statements. Their function is performed at "compile" time. -.IP "\fBlimits\fR" -Print the local limits enforced by the local version of \fBbc\fR. This -is an extension. -.IP "\fBquit\fR" -When the quit statement is read, the \fBbc\fR processor -is terminated, regardless of where the quit statement is found. For -example, "if (0 == 1) quit" will cause \fBbc\fR to terminate. -.IP "\fBwarranty\fR" -Print a longer warranty notice. This is an extension. -.SS FUNCTIONS -Functions provide a method of defining a computation that can be executed -later. Functions in -.B bc -always compute a value and return it to the caller. Function definitions -are "dynamic" in the sense that a function is undefined until a definition -is encountered in the input. That definition is then used until another -definition function for the same name is encountered. The new definition -then replaces the older definition. A function is defined as follows: -.nf -.RS -\fBdefine \fIname \fB( \fIparameters \fB) { \fInewline -\fI auto_list statement_list \fB}\fR -.RE -.fi -A function call is just an expression of the form -"\fIname\fB(\fIparameters\fB)\fR". -.PP -Parameters are numbers or arrays (an extension). In the function definition, -zero or more parameters are defined by listing their names separated by -commas. Numbers are only call by value parameters. Arrays are only -call by variable. Arrays are specified in the parameter definition by -the notation "\fIname\fB[]\fR". In the function call, actual parameters -are full expressions for number parameters. The same notation is used -for passing arrays as for defining array parameters. The named array is -passed by variable to the function. Since function definitions are dynamic, -parameter numbers and types are checked when a function is called. Any -mismatch in number or types of parameters will cause a runtime error. -A runtime error will also occur for the call to an undefined function. -.PP -The \fIauto_list\fR is an optional list of variables that are for -"local" use. The syntax of the auto list (if present) is "\fBauto -\fIname \fR, ... ;". (The semicolon is optional.) Each \fIname\fR is -the name of an auto variable. Arrays may be specified by using the -same notation as used in parameters. These variables have their -values pushed onto a stack at the start of the function. The -variables are then initialized to zero and used throughout the -execution of the function. At function exit, these variables are -popped so that the original value (at the time of the function call) -of these variables are restored. The parameters are really auto -variables that are initialized to a value provided in the function -call. Auto variables are different than traditional local variables -in the fact that if function A calls function B, B may access function -A's auto variables by just using the same name, unless function B has -called them auto variables. Due to the fact that auto variables and -parameters are pushed onto a stack, \fBbc\fR supports recursive functions. -.PP -The function body is a list of \fBbc\fR statements. Again, statements -are separated by semicolons or newlines. Return statements cause the -termination of a function and the return of a value. There are two -versions of the return statement. The first form, "\fBreturn\fR", returns -the value 0 to the calling expression. The second form, -"\fBreturn ( \fIexpression \fB)\fR", computes the value of the expression -and returns that value to the calling expression. There is an implied -"\fBreturn (0)\fR" at the end of every function. This allows a function -to terminate and return 0 without an explicit return statement. -.PP -Functions also change the usage of the variable \fBibase\fR. All -constants in the function body will be converted using the value of -\fBibase\fR at the time of the function call. Changes of \fBibase\fR -will be ignored during the execution of the function except for the -standard function \fBread\fR, which will always use the current value -of \fBibase\fR for conversion of numbers. -.SS MATH LIBRARY -If \fBbc\fR is invoked with the \fB-l\fR option, a math library is preloaded -and the default scale is set to 20. The math functions will calculate their -results to the scale set at the time of their call. -The math library defines the following functions: -.IP "s (\fIx\fR)" -The sine of x in radians. -.IP "c (\fIx\fR)" -The cosine of x in radians. -.IP "a (\fIx\fR)" -The arctangent of x. -.IP "l (\fIx\fR)" -The natural logarithm of x. -.IP "e (\fIx\fR)" -The exponential function of raising e to the value x. -.IP "j (\fIn,x\fR)" -The bessel function of integer order n of x. -.SS EXAMPLES -In /bin/sh, the following will assign the value of "pi" to the shell -variable \fBpi\fR. -.RS -\f(CW -pi=$(echo "scale=10; 4*a(1)" | bc -l) -\fR -.RE -.PP -The following is the definition of the exponential function used in the -math library. This function is written in POSIX \fBbc\fR. -.nf -.RS -\f(CW -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 - } -} -\fR -.RE -.fi -.PP -The following is code that uses the extended features of \fBbc\fR to -implement a simple program for calculating checkbook balances. This -program is best kept in a file so that it can be used many times -without having to retype it at every use. -.nf -.RS -\f(CW -scale=2 -print "\enCheck book program!\en" -print " Remember, deposits are negative transactions.\en" -print " Exit by a 0 transaction.\en\en" - -print "Initial balance? "; bal = read() -bal /= 1 -print "\en" -while (1) { - "current balance = "; bal - "transaction? "; trans = read() - if (trans == 0) break; - bal -= trans - bal /= 1 -} -quit -\fR -.RE -.fi -.PP -The following is the definition of the recursive factorial function. -.nf -.RS -\f(CW -define f (x) { - if (x <= 1) return (1); - return (f(x-1) * x); -} -\fR -.RE -.fi -.SS DIFFERENCES -This version of -.B bc -was implemented from the POSIX P1003.2/D11 draft and contains -several differences and extensions relative to the draft and -traditional implementations. -It is not implemented in the traditional way using -.I dc(1). -This version is a single process which parses and runs a byte code -translation of the program. There is an "undocumented" option (-c) -that causes the program to output the byte code to -the standard output instead of running it. It was mainly used for -debugging the parser and preparing the math library. -.PP -A major source of differences is -extensions, where a feature is extended to add more functionality and -additions, where new features are added. -The following is the list of differences and extensions. -.IP LANG environment -This version does not conform to the POSIX standard in the processing -of the LANG environment variable and all environment variables starting -with LC_. -.IP names -Traditional and POSIX -.B bc -have single letter names for functions, variables and arrays. They have -been extended to be multi-character names that start with a letter and -may contain letters, numbers and the underscore character. -.IP Strings -Strings are not allowed to contain NUL characters. POSIX says all characters -must be included in strings. -.IP last -POSIX \fBbc\fR does not have a \fBlast\fR variable. Some implementations -of \fBbc\fR use the period (.) in a similar way. -.IP comparisons -POSIX \fBbc\fR allows comparisons only in the if statement, the while -statement, and the second expression of the for statement. Also, only -one relational operation is allowed in each of those statements. -.IP "if statement, else clause" -POSIX \fBbc\fR does not have an else clause. -.IP "for statement" -POSIX \fBbc\fR requires all expressions to be present in the for statement. -.IP "&&, ||, !" -POSIX \fBbc\fR does not have the logical operators. -.IP "read function" -POSIX \fBbc\fR does not have a read function. -.IP "print statement" -POSIX \fBbc\fR does not have a print statement . -.IP "continue statement" -POSIX \fBbc\fR does not have a continue statement. -.IP "array parameters" -POSIX \fBbc\fR does not have array parameters. Other implementations -of \fBbc\fR may have call by value array parameters. -.IP "=+, =-, =*, =/, =%, =^" -POSIX \fBbc\fR does not require these "old style" assignment operators to -be defined. This version may allow these "old style" assignments. Use -the limits statement to see if the installed version supports them. If -it does support the "old style" assignment operators, the statement -"a =- 1" will decrement \fBa\fR by 1 instead of setting \fBa\fR to the -value -1. -.IP "spaces in numbers" -Other implementations of \fBbc\fR allow spaces in numbers. For example, -"x=1 3" would assign the value 13 to the variable x. The same statement -would cause a syntax error in this version of \fBbc\fR. -.IP "errors and execution" -This implementation varies from other implementations in terms of what -code will be executed when syntax and other errors are found in the -program. If a syntax error is found in a function definition, error -recovery tries to find the beginning of a statement and continue to -parse the function. Once a syntax error is found in the function, the -function will not be callable and becomes undefined. -Syntax errors in the interactive execution code will invalidate the -current execution block. The execution block is terminated by an -end of line that appears after a complete sequence of statements. -For example, -.nf -.RS -a = 1 -b = 2 -.RE -.fi -has two execution blocks and -.nf -.RS -{ a = 1 - b = 2 } -.RE -.fi -has one execution block. Any runtime error will terminate the execution -of the current execution block. A runtime warning will not terminate the -current execution block. -.IP "Interrupts" -During an interactive session, the SIGINT signal (usually generated by -the control-C character from the terminal) will cause execution of the -current execution block to be interrupted. It will display a "runtime" -error indicating which function was interrupted. After all runtime -structures have been cleaned up, a message will be printed to notify the -user that \fBbc\fR is ready for more input. All previously defined functions -remain defined and the value of all non-auto variables are the value at -the point of interruption. All auto variables and function parameters -are removed during the -clean up process. During a non-interactive -session, the SIGINT signal will terminate the entire run of \fBbc\fR. -.SS LIMITS -The following are the limits currently in place for this -.B bc -processor. Some of them may have been changed by an installation. -Use the limits statement to see the actual values. -.IP BC_BASE_MAX -The maximum output base is currently set at 999. The maximum input base -is 16. -.IP BC_DIM_MAX -This is currently an arbitrary limit of 65535 as distributed. Your -installation may be different. -.IP BC_SCALE_MAX -The number of digits after the decimal point is limited to INT_MAX digits. -Also, the number of digits before the decimal point is limited to INT_MAX -digits. -.IP BC_STRING_MAX -The limit on the number of characters in a string is INT_MAX characters. -.IP exponent -The value of the exponent in the raise operation (^) is limited to LONG_MAX. -.IP multiply -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 16384 bytes of -compiled byte code each. This limit (BC_MAX_SEGS) can be easily changed -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. -.SH FILES -In most installations, \fBbc\fR is completely self-contained. -Where executable size is of importance or the C compiler does -not deal with very long strings, \fBbc\fR will read -the standard math library from the file /usr/local/lib/libmath.b. -(The actual location may vary. It may be /lib/libmath.b.) -.SH DIAGNOSTICS -If any file on the command line can not be opened, \fBbc\fR will report -that the file is unavailable and terminate. Also, there are compile -and run time diagnostics that should be self-explanatory. -.SH BUGS -Error recovery is not very good yet. -.SH AUTHOR -.nf -Philip A. Nelson -phil@cs.wwu.edu -.fi -.SH ACKNOWLEDGEMENTS -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. diff --git a/gnu/usr.bin/bc/bc.y b/gnu/usr.bin/bc/bc.y deleted file mode 100644 index f5ba1617bf0..00000000000 --- a/gnu/usr.bin/bc/bc.y +++ /dev/null @@ -1,617 +0,0 @@ -%{ -/* $NetBSD: bc.y,v 1.2 1994/12/02 00:43:23 phil Exp $ */ - -/* 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"); - } - ; -%% diff --git a/gnu/usr.bin/bc/bcdefs.h b/gnu/usr.bin/bc/bcdefs.h deleted file mode 100644 index 1b4dee3fc0e..00000000000 --- a/gnu/usr.bin/bc/bcdefs.h +++ /dev/null @@ -1,156 +0,0 @@ -/* $NetBSD: bcdefs.h,v 1.3 1994/12/02 00:43:25 phil Exp $ */ - -/* 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, 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 the configuration file. */ -#include "config.h" - -/* Standard includes for all files. */ -#include <stdio.h> -#include <sys/types.h> -#include <ctype.h> -#ifdef STRINGS_H -#include <strings.h> -#else -#include <string.h> -#endif -#ifndef NO_LIMITS -#include <limits.h> -#endif - -/* Include the other definitions. */ -#include "const.h" -#include "number.h" - - -/* These definitions define all the structures used in - code and data storage. This includes the representation of - labels. The "guiding" principle is to make structures that - take a minimum of space when unused but can be built to contain - the full structures. */ - -/* Labels are first. Labels are generated sequentially in functions - and full code. They just "point" to a single bye in the code. The - "address" is the byte number. The byte number is used to get an - actual character pointer. */ - -typedef struct bc_label_group - { - long l_adrs [ BC_LABEL_GROUP ]; - struct bc_label_group *l_next; - } bc_label_group; - - -/* Each function has its own code segments and labels. There can be - no jumps between functions so labels are unique to a function. */ - -typedef struct arg_list - { - int av_name; - struct arg_list *next; - } arg_list; - -typedef struct - { - char f_defined; /* Is this function defined yet. */ - char *f_body[BC_MAX_SEGS]; - int f_code_size; - bc_label_group *f_label; - arg_list *f_params; - arg_list *f_autos; - } bc_function; - -/* Code addresses. */ -typedef struct { - int pc_func; - int pc_addr; - } program_counter; - - -/* Variables are "pushable" (auto) and thus we need a stack mechanism. - This is built into the variable record. */ - -typedef struct bc_var - { - bc_num v_value; - struct bc_var *v_next; - } bc_var; - - -/* bc arrays can also be "auto" variables and thus need the same - kind of stacking mechanisms. */ - -typedef struct bc_array_node - { - union - { - bc_num n_num [NODE_SIZE]; - struct bc_array_node *n_down [NODE_SIZE]; - } n_items; - } bc_array_node; - -typedef struct bc_array - { - bc_array_node *a_tree; - short a_depth; - } bc_array; - -typedef struct bc_var_array - { - bc_array *a_value; - char a_param; - struct bc_var_array *a_next; - } bc_var_array; - - -/* For the stacks, execution and function, we need records to allow - for arbitrary size. */ - -typedef struct estack_rec { - bc_num s_num; - struct estack_rec *s_next; -} estack_rec; - -typedef struct fstack_rec { - int s_val; - struct fstack_rec *s_next; -} fstack_rec; - - -/* The following are for the name tree. */ - -typedef struct id_rec { - char *id; /* The program name. */ - /* A name == 0 => nothing assigned yet. */ - int a_name; /* The array variable name (number). */ - int f_name; /* The function name (number). */ - int v_name; /* The variable name (number). */ - short balance; /* For the balanced tree. */ - struct id_rec *left, *right; /* Tree pointers. */ -} id_rec; diff --git a/gnu/usr.bin/bc/config.h b/gnu/usr.bin/bc/config.h deleted file mode 100644 index 2e0e9aa399d..00000000000 --- a/gnu/usr.bin/bc/config.h +++ /dev/null @@ -1,47 +0,0 @@ -/* $NetBSD: config.h,v 1.3 1994/12/02 00:43:26 phil Exp $ */ - -/* config.h. Generated automatically by configure. */ -/* config.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define to empty if the keyword does not work. */ -/* #undef const */ - -/* Define if on MINIX. */ -/* #undef _MINIX */ - -/* Define if the system does not provide POSIX.1 features except - with this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define if you need to in order for stat and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define to `unsigned' if <sys/types.h> doesn't define. */ -/* #undef size_t */ - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* define if the math lib is to be loaded from a file. */ -/* #undef BC_MATH_FILE */ - -/* Define if you have the isgraph function. */ -/* #undef HAVE_ISGRAPH */ - -/* Define if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H 1 - -/* Define if you have the <stddef.h> header file. */ -#define HAVE_STDDEF_H 1 - -/* Define if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 diff --git a/gnu/usr.bin/bc/const.h b/gnu/usr.bin/bc/const.h deleted file mode 100644 index 893a29f424a..00000000000 --- a/gnu/usr.bin/bc/const.h +++ /dev/null @@ -1,93 +0,0 @@ -/* $NetBSD: const.h,v 1.3 1994/12/02 00:43:28 phil Exp $ */ - -/* const.h: Constants for bc. */ - -/* 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 - -*************************************************************************/ - - -/* Define INT_MAX and LONG_MAX if not defined. Assuming 32 bits... */ - -#ifdef NO_LIMITS -#define INT_MAX 0x7FFFFFFF -#define LONG_MAX 0x7FFFFFFF -#endif - - -/* Define constants in some reasonable size. The next 4 constants are - POSIX constants. */ - -#define BC_BASE_MAX INT_MAX -#define BC_SCALE_MAX INT_MAX -#define BC_STRING_MAX INT_MAX - - -/* Definitions for arrays. */ - -#define BC_DIM_MAX 65535 /* this should be NODE_SIZE^NODE_DEPTH-1 */ - -#define NODE_SIZE 16 /* Must be a power of 2. */ -#define NODE_MASK 0xf /* Must be NODE_SIZE-1. */ -#define NODE_SHIFT 4 /* Number of 1 bits in NODE_MASK. */ -#define NODE_DEPTH 4 - - -/* Other BC limits defined but not part of POSIX. */ - -#define BC_LABEL_GROUP 64 -#define BC_LABEL_LOG 6 -#define BC_MAX_SEGS 16 /* Code segments. */ -#define BC_SEG_SIZE 1024 -#define BC_SEG_LOG 10 - -/* Maximum number of variables, arrays and functions and the - allocation increment for the dynamic arrays. */ - -#define MAX_STORE 32767 -#define STORE_INCR 32 - -/* Other interesting constants. */ - -#define FALSE 0 -#define TRUE 1 - -/* for use with lookup (). */ -#define SIMPLE 0 -#define ARRAY 1 -#define FUNCT 2 -#define FUNCTDEF 3 - -#define EXTERN extern -#ifdef __STDC__ -#define CONST const -#define VOID void -#else -#define CONST -#define VOID -#endif - -/* Include the version definition. */ -#include "version.h" diff --git a/gnu/usr.bin/bc/execute.c b/gnu/usr.bin/bc/execute.c deleted file mode 100644 index f2d8b5a19b7..00000000000 --- a/gnu/usr.bin/bc/execute.c +++ /dev/null @@ -1,788 +0,0 @@ -/* $NetBSD: execute.c,v 1.4 1995/10/10 00:22:54 phil Exp $ */ - -/* execute.c - run a bc program. */ - -/* 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 <signal.h> -#include "global.h" -#include "proto.h" - - -/* The SIGINT interrupt handling routine. */ - -int had_sigint; - -void -stop_execution (sig) - int sig; -{ - had_sigint = TRUE; - printf ("\n"); - rt_error ("interrupted execution"); -} - - -/* Get the current byte and advance the PC counter. */ - -unsigned char -byte (pc) - program_counter *pc; -{ - int seg, offset; - - seg = pc->pc_addr >> BC_SEG_LOG; - offset = pc->pc_addr++ % BC_SEG_SIZE; - return (functions[pc->pc_func].f_body[seg][offset]); -} - - -/* The routine that actually runs the machine. */ - -void -execute () -{ - int label_num, l_gp, l_off; - bc_label_group *gp; - - char inst, ch; - int new_func; - int var_name; - - int const_base; - - bc_num temp_num; - arg_list *auto_list; - - /* Initialize this run... */ - pc.pc_func = 0; - pc.pc_addr = 0; - runtime_error = FALSE; - init_num (&temp_num); - - /* Set up the interrupt mechanism for an interactive session. */ - if (interactive) - { - signal (SIGINT, stop_execution); - had_sigint = FALSE; - } - - while (pc.pc_addr < functions[pc.pc_func].f_code_size && !runtime_error) - { - inst = byte(&pc); - -#if DEBUG > 3 - { /* Print out address and the stack before each instruction.*/ - int depth; estack_rec *temp = ex_stack; - - printf ("func=%d addr=%d inst=%c\n",pc.pc_func, pc.pc_addr, inst); - if (temp == NULL) printf ("empty stack.\n", inst); - else - { - depth = 1; - while (temp != NULL) - { - printf (" %d = ", depth); - out_num (temp->s_num, 10, out_char); - depth++; - temp = temp->s_next; - } - } - } -#endif - - switch ( inst ) - { - - case 'A' : /* increment array variable (Add one). */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); - incr_array (var_name); - break; - - case 'B' : /* Branch to a label if TOS != 0. Remove value on TOS. */ - case 'Z' : /* Branch to a label if TOS == 0. Remove value on TOS. */ - c_code = !is_zero (ex_stack->s_num); - pop (); - case 'J' : /* Jump to a label. */ - label_num = byte(&pc); /* Low order bits first. */ - label_num += byte(&pc) << 8; - if (inst == 'J' || (inst == 'B' && c_code) - || (inst == 'Z' && !c_code)) { - gp = functions[pc.pc_func].f_label; - l_gp = label_num >> BC_LABEL_LOG; - l_off = label_num % BC_LABEL_GROUP; - while (l_gp-- > 0) gp = gp->l_next; - pc.pc_addr = gp->l_adrs[l_off]; - } - break; - - case 'C' : /* Call a function. */ - /* Get the function number. */ - new_func = byte(&pc); - if ((new_func & 0x80) != 0) - new_func = ((new_func << 8) & 0x7f) + byte(&pc); - - /* Check to make sure it is defined. */ - if (!functions[new_func].f_defined) - { - rt_error ("Function %s not defined.", f_names[new_func]); - break; - } - - /* Check and push parameters. */ - process_params (&pc, new_func); - - /* Push auto variables. */ - for (auto_list = functions[new_func].f_autos; - auto_list != NULL; - auto_list = auto_list->next) - auto_var (auto_list->av_name); - - /* Push pc and ibase. */ - fpush (pc.pc_func); - fpush (pc.pc_addr); - fpush (i_base); - - /* Reset pc to start of function. */ - pc.pc_func = new_func; - pc.pc_addr = 0; - break; - - case 'D' : /* Duplicate top of stack */ - push_copy (ex_stack->s_num); - break; - - case 'K' : /* Push a constant */ - /* Get the input base and convert it to a bc number. */ - if (pc.pc_func == 0) - const_base = i_base; - else - const_base = fn_stack->s_val; - if (const_base == 10) - push_b10_const (&pc); - else - push_constant (prog_char, const_base); - break; - - case 'L' : /* load array variable */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); - load_array (var_name); - break; - - case 'M' : /* decrement array variable (Minus!) */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); - decr_array (var_name); - break; - - case 'O' : /* Write a string to the output with processing. */ - while ((ch = byte(&pc)) != '"') - if (ch != '\\') - out_char (ch); - else - { - ch = byte(&pc); - if (ch == '"') break; - switch (ch) - { - 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; - } - } - if (interactive) fflush (stdout); - break; - - case 'R' : /* Return from function */ - if (pc.pc_func != 0) - { - /* "Pop" autos and parameters. */ - pop_vars(functions[pc.pc_func].f_autos); - pop_vars(functions[pc.pc_func].f_params); - /* reset the pc. */ - fpop (); - pc.pc_addr = fpop (); - pc.pc_func = fpop (); - } - else - rt_error ("Return from main program."); - break; - - case 'S' : /* store array variable */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); - store_array (var_name); - break; - - case 'T' : /* Test tos for zero */ - c_code = is_zero (ex_stack->s_num); - assign (c_code); - break; - - case 'W' : /* Write the value on the top of the stack. */ - case 'P' : /* Write the value on the top of the stack. No newline. */ - out_num (ex_stack->s_num, o_base, out_char); - if (inst == 'W') out_char ('\n'); - store_var (3); /* Special variable "last". */ - if (interactive) fflush (stdout); - pop (); - break; - - case 'c' : /* Call special function. */ - new_func = byte(&pc); - - switch (new_func) - { - case 'L': /* Length function. */ - /* For the number 0.xxxx, 0 is not significant. */ - if (ex_stack->s_num->n_len == 1 && - ex_stack->s_num->n_scale != 0 && - ex_stack->s_num->n_value[0] == 0 ) - int2num (&ex_stack->s_num, ex_stack->s_num->n_scale); - else - int2num (&ex_stack->s_num, ex_stack->s_num->n_len - + ex_stack->s_num->n_scale); - break; - - case 'S': /* Scale function. */ - int2num (&ex_stack->s_num, ex_stack->s_num->n_scale); - break; - - case 'R': /* Square Root function. */ - if (!bc_sqrt (&ex_stack->s_num, scale)) - rt_error ("Square root of a negative number"); - break; - - case 'I': /* Read function. */ - push_constant (input_char, i_base); - break; - } - break; - - case 'd' : /* Decrement number */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); - decr_var (var_name); - break; - - case 'h' : /* Halt the machine. */ - exit (0); - - case 'i' : /* increment number */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); - incr_var (var_name); - break; - - case 'l' : /* load variable */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); - load_var (var_name); - break; - - case 'n' : /* Negate top of stack. */ - bc_sub (_zero_, ex_stack->s_num, &ex_stack->s_num); - break; - - case 'p' : /* Pop the execution stack. */ - pop (); - break; - - case 's' : /* store variable */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); - store_var (var_name); - break; - - case 'w' : /* Write a string to the output. */ - while ((ch = byte(&pc)) != '"') out_char (ch); - if (interactive) fflush (stdout); - break; - - case 'x' : /* Exchange Top of Stack with the one under the tos. */ - if (check_stack(2)) { - bc_num temp = ex_stack->s_num; - ex_stack->s_num = ex_stack->s_next->s_num; - ex_stack->s_next->s_num = temp; - } - break; - - case '0' : /* Load Constant 0. */ - push_copy (_zero_); - break; - - case '1' : /* Load Constant 0. */ - push_copy (_one_); - break; - - case '!' : /* Negate the boolean value on top of the stack. */ - c_code = is_zero (ex_stack->s_num); - assign (c_code); - break; - - case '&' : /* compare greater than */ - if (check_stack(2)) - { - c_code = !is_zero (ex_stack->s_next->s_num) - && !is_zero (ex_stack->s_num); - pop (); - assign (c_code); - } - break; - - case '|' : /* compare greater than */ - if (check_stack(2)) - { - c_code = !is_zero (ex_stack->s_next->s_num) - || !is_zero (ex_stack->s_num); - pop (); - assign (c_code); - } - break; - - case '+' : /* add */ - if (check_stack(2)) - { - bc_add (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num); - pop(); - pop(); - push_num (temp_num); - init_num (&temp_num); - } - break; - - case '-' : /* subtract */ - if (check_stack(2)) - { - bc_sub (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num); - pop(); - pop(); - push_num (temp_num); - init_num (&temp_num); - } - break; - - case '*' : /* multiply */ - if (check_stack(2)) - { - bc_multiply (ex_stack->s_next->s_num, ex_stack->s_num, - &temp_num, scale); - pop(); - pop(); - push_num (temp_num); - init_num (&temp_num); - } - break; - - case '/' : /* divide */ - if (check_stack(2)) - { - if (bc_divide (ex_stack->s_next->s_num, - ex_stack->s_num, &temp_num, scale) == 0) - { - pop(); - pop(); - push_num (temp_num); - init_num (&temp_num); - } - else - rt_error ("Divide by zero"); - } - break; - - case '%' : /* remainder */ - if (check_stack(2)) - { - if (is_zero (ex_stack->s_num)) - rt_error ("Modulo by zero"); - else - { - bc_modulo (ex_stack->s_next->s_num, - ex_stack->s_num, &temp_num, scale); - pop(); - pop(); - push_num (temp_num); - init_num (&temp_num); - } - } - break; - - case '^' : /* raise */ - if (check_stack(2)) - { - bc_raise (ex_stack->s_next->s_num, - ex_stack->s_num, &temp_num, scale); - if (is_zero (ex_stack->s_next->s_num) && is_neg (ex_stack->s_num)) - rt_error ("divide by zero"); - pop(); - pop(); - push_num (temp_num); - init_num (&temp_num); - } - break; - - case '=' : /* compare equal */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) == 0; - pop (); - assign (c_code); - } - break; - - case '#' : /* compare not equal */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) != 0; - pop (); - assign (c_code); - } - break; - - case '<' : /* compare less than */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) == -1; - pop (); - assign (c_code); - } - break; - - case '{' : /* compare less than or equal */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) <= 0; - pop (); - assign (c_code); - } - break; - - case '>' : /* compare greater than */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) == 1; - pop (); - assign (c_code); - } - break; - - case '}' : /* compare greater than or equal */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) >= 0; - pop (); - assign (c_code); - } - break; - - default : /* error! */ - rt_error ("bad instruction: inst=%c", inst); - } - } - - /* Clean up the function stack and pop all autos/parameters. */ - while (pc.pc_func != 0) - { - pop_vars(functions[pc.pc_func].f_autos); - pop_vars(functions[pc.pc_func].f_params); - fpop (); - pc.pc_addr = fpop (); - pc.pc_func = fpop (); - } - - /* Clean up the execution stack. */ - while (ex_stack != NULL) pop(); - - /* Clean up the interrupt stuff. */ - if (interactive) - { - signal (SIGINT, use_quit); - if (had_sigint) - printf ("Interruption completed.\n"); - } -} - - -/* Prog_char gets another byte from the program. It is used for - conversion of text constants in the code to numbers. */ - -char -prog_char () -{ - return byte(&pc); -} - - -/* Read a character from the standard input. This function is used - by the "read" function. */ - -char -input_char () -{ - char in_ch; - - /* Get a character from the standard input for the read function. */ - in_ch = getchar(); - - /* Check for a \ quoted newline. */ - if (in_ch == '\\') - { - in_ch = getchar(); - if (in_ch == '\n') - in_ch = getchar(); - } - - /* Classify and preprocess the input character. */ - if (isdigit(in_ch)) - return (in_ch - '0'); - if (in_ch >= 'A' && in_ch <= 'F') - return (in_ch + 10 - 'A'); - if (in_ch >= 'a' && in_ch <= 'f') - return (in_ch + 10 - 'a'); - if (in_ch == '.' || in_ch == '+' || in_ch == '-') - return (in_ch); - if (in_ch <= ' ') - return (' '); - - return (':'); -} - - -/* Push_constant converts a sequence of input characters as returned - by IN_CHAR into a number. The number is pushed onto the execution - stack. The number is converted as a number in base CONV_BASE. */ - -void -push_constant (in_char, conv_base) - char (*in_char)(VOID); - int conv_base; -{ - int digits; - bc_num build, temp, result, mult, divisor; - char in_ch, first_ch; - char negative; - - /* Initialize all bc numbers */ - init_num (&temp); - init_num (&result); - init_num (&mult); - build = copy_num (_zero_); - negative = FALSE; - - /* The conversion base. */ - int2num (&mult, conv_base); - - /* Get things ready. */ - in_ch = in_char(); - while (in_ch == ' ') - in_ch = in_char(); - - if (in_ch == '+') - in_ch = in_char(); - else - if (in_ch == '-') - { - negative = TRUE; - in_ch = in_char(); - } - - /* Check for the special case of a single digit. */ - if (in_ch < 16) - { - first_ch = in_ch; - in_ch = in_char(); - if (in_ch < 16 && first_ch >= conv_base) - first_ch = conv_base - 1; - int2num (&build, (int) first_ch); - } - - /* Convert the integer part. */ - while (in_ch < 16) - { - if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1; - bc_multiply (build, mult, &result, 0); - int2num (&temp, (int) in_ch); - bc_add (result, temp, &build); - in_ch = in_char(); - } - if (in_ch == '.') - { - in_ch = in_char(); - if (in_ch >= conv_base) in_ch = conv_base-1; - free_num (&result); - free_num (&temp); - divisor = copy_num (_one_); - result = copy_num (_zero_); - digits = 0; - while (in_ch < 16) - { - bc_multiply (result, mult, &result, 0); - int2num (&temp, (int) in_ch); - bc_add (result, temp, &result); - bc_multiply (divisor, mult, &divisor, 0); - digits++; - in_ch = in_char(); - if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1; - } - bc_divide (result, divisor, &result, digits); - bc_add (build, result, &build); - } - - /* Final work. */ - if (negative) - bc_sub (_zero_, build, &build); - - push_num (build); - free_num (&temp); - free_num (&result); - free_num (&mult); -} - - -/* When converting base 10 constants from the program, we use this - more efficient way to convert them to numbers. PC tells where - the constant starts and is expected to be advanced to after - the constant. */ - -void -push_b10_const (pc) - program_counter *pc; -{ - bc_num build; - program_counter look_pc; - int kdigits, kscale; - char inchar; - char *ptr; - - /* Count the digits and get things ready. */ - look_pc = *pc; - kdigits = 0; - kscale = 0; - inchar = byte (&look_pc); - while (inchar != '.' && inchar != ':') - { - kdigits++; - inchar = byte(&look_pc); - } - if (inchar == '.' ) - { - inchar = byte(&look_pc); - while (inchar != ':') - { - kscale++; - inchar = byte(&look_pc); - } - } - - /* Get the first character again and move the pc. */ - inchar = byte(pc); - - /* Secial cases of 0, 1, and A-F single inputs. */ - if (kdigits == 1 && kscale == 0) - { - if (inchar == 0) - { - push_copy (_zero_); - inchar = byte(pc); - return; - } - if (inchar == 1) { - push_copy (_one_); - inchar = byte(pc); - return; - } - if (inchar > 9) - { - init_num (&build); - int2num (&build, inchar); - push_num (build); - inchar = byte(pc); - return; - } - } - - /* Build the new number. */ - if (kdigits == 0) - { - build = new_num (1,kscale); - ptr = build->n_value; - *ptr++ = 0; - } - else - { - build = new_num (kdigits,kscale); - ptr = build->n_value; - } - - while (inchar != ':') - { - if (inchar != '.') - if (inchar > 9) - *ptr++ = 9; - else - *ptr++ = inchar; - inchar = byte(pc); - } - push_num (build); -} - - -/* Put the correct value on the stack for C_CODE. Frees TOS num. */ - -void -assign (c_code) - char c_code; -{ - free_num (&ex_stack->s_num); - if (c_code) - ex_stack->s_num = copy_num (_one_); - else - ex_stack->s_num = copy_num (_zero_); -} diff --git a/gnu/usr.bin/bc/fix_libmath.h b/gnu/usr.bin/bc/fix_libmath.h deleted file mode 100644 index 5a002c4f324..00000000000 --- a/gnu/usr.bin/bc/fix_libmath.h +++ /dev/null @@ -1,8 +0,0 @@ -ed libmath.h <<EOS-EOS -1,1s/^/"/ -1,\$s/\$/\\\\/ -\$,\$d -\$,\$s/\\\\\$/"/ -w -q -EOS-EOS diff --git a/gnu/usr.bin/bc/global.c b/gnu/usr.bin/bc/global.c deleted file mode 100644 index d581a239039..00000000000 --- a/gnu/usr.bin/bc/global.c +++ /dev/null @@ -1,44 +0,0 @@ -/* $NetBSD: global.c,v 1.3 1994/12/02 00:43:31 phil Exp $ */ - -/* global.c: This defines the global variables. */ - -/* 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" - -/* Since we want to define them here, we use the following define. */ -#undef EXTERN -#define EXTERN - -/* Define all the global variables for bc. */ -#include "global.h" - -#ifndef BC_MATH_FILE -CONST char libmath[] = -#include "libmath.h" -; -#endif diff --git a/gnu/usr.bin/bc/global.h b/gnu/usr.bin/bc/global.h deleted file mode 100644 index 986865a458f..00000000000 --- a/gnu/usr.bin/bc/global.h +++ /dev/null @@ -1,125 +0,0 @@ -/* global.h: The global variables for bc. */ - -/* 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 - -*************************************************************************/ - - -/* The current break level's lable. */ -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; - -/* Next available label number. */ -EXTERN int next_label; - -/* 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; - -/* 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.*/ -/* Function storage. main is (0) and functions (1-f_count) */ - -EXTERN bc_function *functions; -EXTERN char **f_names; -EXTERN int f_count; - -/* Variable stoarge and reverse names. */ - -EXTERN bc_var **variables; -EXTERN char **v_names; -EXTERN int v_count; - -/* Array Variable storage and reverse names. */ - -EXTERN bc_var_array **arrays; -EXTERN char **a_names; -EXTERN int a_count; - -/* Execution stack. */ -EXTERN estack_rec *ex_stack; - -/* Function return stack. */ -EXTERN fstack_rec *fn_stack; - -/* Other "storage". */ -EXTERN int i_base; -EXTERN int o_base; -EXTERN int scale; -EXTERN char c_code; -EXTERN int out_col; -EXTERN char runtime_error; -EXTERN program_counter pc; - -/* Input Line numbers and other error information. */ -EXTERN int line_no; -EXTERN int had_error; - -/* For larger identifiers, a tree, and how many "storage" locations - have been allocated. */ - -EXTERN int next_array; -EXTERN int next_func; -EXTERN int next_var; - -EXTERN id_rec *name_tree; - -/* For error message production */ -EXTERN char **g_argv; -EXTERN int g_argc; -EXTERN char is_std_in; - -/* defined in number.c */ -extern bc_num _zero_; -extern bc_num _one_; - -/* For use with getopt. Do not declare them here.*/ -extern int optind; - diff --git a/gnu/usr.bin/bc/libmath.b b/gnu/usr.bin/bc/libmath.b deleted file mode 100644 index d6fa9152a45..00000000000 --- a/gnu/usr.bin/bc/libmath.b +++ /dev/null @@ -1,281 +0,0 @@ -/* $NetBSD: libmath.b,v 1.2 1994/12/02 00:43:33 phil Exp $ */ - -/* libmath.b for bc for minix. */ - -/* This file is part of bc written for MINIX. - Copyright (C) 1991, 1992, 1993 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, n, v, z - - /* a - holds x^y of x^y/y! */ - /* d - holds y! */ - /* e - is the value x^y/y! */ - /* v - is the sum of the e's */ - /* f - number of times x was divided by 2. */ - /* m - is 1 if x was minus. */ - /* i - iteration count. */ - /* n - the scale to compute the sum. */ - /* z - orignal scale. */ - - /* Check the sign of x. */ - if (x<0) { - m = 1 - x = -x - } - - /* Precondition x. */ - z = scale; - n = 6 + z + .44*x; - scale = scale(x)+1; - while (x > 1) { - f += 1; - x /= 2; - scale += 1; - } - - /* Initialize the variables. */ - scale = n; - 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 = 6 + scale; - 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 + 2; - 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 - - /* a is the value of a(.2) if it is needed. */ - /* f is the value to multiply by a in the return. */ - /* e is the value of the current term in the series. */ - /* v is the accumulated value of the series. */ - /* m is 1 or -1 depending on x (-x -> -1). results are divided by m. */ - /* i is the denominator value for series element. */ - /* n is the numerator value for the series element. */ - /* s is -x*x. */ - /* z is the saved user's scale. */ - - /* Negative x? */ - m = 1; - if (x<0) { - m = -1; - x = -x; - } - - /* Special case and for fast answers */ - if (x==1) { - if (scale <= 25) return (.7853981633974483096156608/m) - if (scale <= 40) return (.7853981633974483096156608458198757210492/m) - if (scale <= 60) \ - return (.785398163397448309615660845819875721049292349843776455243736/m) - } - if (x==.2) { - if (scale <= 25) return (.1973955598498807583700497/m) - if (scale <= 40) return (.1973955598498807583700497651947902934475/m) - if (scale <= 60) \ - return (.197395559849880758370049765194790293447585103787852101517688/m) - } - - - /* 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+5; - a = a(.2); - } - - /* Precondition x. */ - scale = z+3; - 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; - return ((f*a+v)/m); - } - 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; - } -} diff --git a/gnu/usr.bin/bc/libmath.h b/gnu/usr.bin/bc/libmath.h deleted file mode 100644 index fb5b03b8f9c..00000000000 --- a/gnu/usr.bin/bc/libmath.h +++ /dev/null @@ -1,40 +0,0 @@ -"@iK20:s2:p@r\ -@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\ -@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" diff --git a/gnu/usr.bin/bc/load.c b/gnu/usr.bin/bc/load.c deleted file mode 100644 index e4732d2d5b5..00000000000 --- a/gnu/usr.bin/bc/load.c +++ /dev/null @@ -1,335 +0,0 @@ -/* $NetBSD: load.c,v 1.3 1994/12/02 00:43:35 phil Exp $ */ - -/* load.c: This code "loads" code into the code segments. */ - -/* 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" - -/* Load variables. */ - -program_counter load_adr; -char load_str; -char load_const; - -/* Initialize the load sequence. */ -void -init_load () -{ - clear_func(0); - load_adr.pc_func = 0; - load_adr.pc_addr = 0; - load_str = FALSE; - load_const = FALSE; -} - -/* addbyte adds one BYTE to the current code segment. */ -void -addbyte (byte) - char byte; -{ - int seg, offset, func; - - /* If there was an error, don't continue. */ - if (had_error) return; - - /* Calculate the segment and offset. */ - seg = load_adr.pc_addr >> BC_SEG_LOG; - offset = load_adr.pc_addr++ % BC_SEG_SIZE; - func = load_adr.pc_func; - - if (seg >= BC_MAX_SEGS) - { - yyerror ("Function too big."); - return; - } - - if (functions[func].f_body[seg] == NULL) - functions[func].f_body[seg] = (char *) bc_malloc (BC_SEG_SIZE); - - /* Store the byte. */ - functions[func].f_body[seg][offset] = byte; - functions[func].f_code_size++; -} - - -/* Define a label LAB to be the current program counter. */ - -void -def_label (lab) - long lab; -{ - bc_label_group *temp; - int group, offset, func; - - /* Get things ready. */ - group = lab >> BC_LABEL_LOG; - offset = lab % BC_LABEL_GROUP; - func = load_adr.pc_func; - - /* Make sure there is at least one label group. */ - if (functions[func].f_label == NULL) - { - functions[func].f_label = - (bc_label_group *) bc_malloc (sizeof(bc_label_group)); - functions[func].f_label->l_next = NULL; - } - - /* Add the label group. */ - temp = functions[func].f_label; - while (group > 0) - { - if (temp->l_next == NULL) - { - temp->l_next = (bc_label_group *) bc_malloc (sizeof(bc_label_group)); - temp->l_next->l_next = NULL; - } - temp = temp->l_next; - group --; - } - - /* Define it! */ - temp->l_adrs [offset] = load_adr.pc_addr; -} - -/* Several instructions have integers in the code. They - are all known to be legal longs. So, no error code - is added. STR is the pointer to the load string and - must be moved to the last non-digit character. */ - -long -long_val (str) - char **str; -{ int val = 0; - char neg = FALSE; - - if (**str == '-') - { - neg = TRUE; - (*str)++; - } - while (isdigit(**str)) - val = val*10 + *(*str)++ - '0'; - - if (neg) - return -val; - else - return val; -} - - -/* load_code loads the CODE into the machine. */ - -void -load_code (code) - char *code; -{ - char *str; - long ap_name; /* auto or parameter name. */ - long label_no; - long vaf_name; /* variable, array or function number. */ - long func; - program_counter save_adr; - - /* Initialize. */ - str = code; - - /* Scan the code. */ - while (*str != 0) - { - /* If there was an error, don't continue. */ - if (had_error) return; - - if (load_str) - { - if (*str == '"') load_str = FALSE; - addbyte (*str++); - } - else - if (load_const) - { - if (*str == '\n') - str++; - else - { - if (*str == ':') - { - load_const = FALSE; - addbyte (*str++); - } - else - if (*str == '.') - addbyte (*str++); - else - if (*str >= 'A') - addbyte (*str++ + 10 - 'A'); - else - addbyte (*str++ - '0'); - } - } - else - { - switch (*str) - { - - case '"': /* Starts a string. */ - load_str = TRUE; - break; - - case 'N': /* A label */ - str++; - label_no = long_val (&str); - def_label (label_no); - break; - - case 'B': /* Branch to label. */ - case 'J': /* Jump to label. */ - case 'Z': /* Branch Zero to label. */ - addbyte(*str++); - label_no = long_val (&str); - if (label_no > 65535L) - { /* Better message? */ - fprintf (stderr,"Program too big.\n"); - exit(1); - } - addbyte ( (char) label_no & 0xFF); - addbyte ( (char) label_no >> 8); - break; - - case 'F': /* A function, get the name and initialize it. */ - str++; - func = long_val (&str); - clear_func (func); -#if DEBUG > 2 - printf ("Loading function number %d\n", func); -#endif - /* get the parameters */ - while (*str++ != '.') - { - if (*str == '.') - { - str++; - break; - } - ap_name = long_val (&str); -#if DEBUG > 2 - printf ("parameter number %d\n", ap_name); -#endif - functions[(int)func].f_params = - nextarg (functions[(int)func].f_params, ap_name); - } - - /* get the auto vars */ - while (*str != '[') - { - if (*str == ',') str++; - ap_name = long_val (&str); -#if DEBUG > 2 - printf ("auto number %d\n", ap_name); -#endif - functions[(int)func].f_autos = - nextarg (functions[(int)func].f_autos, ap_name); - } - save_adr = load_adr; - load_adr.pc_func = func; - load_adr.pc_addr = 0; - break; - - case ']': /* A function end */ - functions[load_adr.pc_func].f_defined = TRUE; - load_adr = save_adr; - break; - - case 'C': /* Call a function. */ - addbyte (*str++); - func = long_val (&str); - if (func < 128) - addbyte ( (char) func); - else - { - addbyte ((func >> 8) & 0xff | 0x80); - addbyte (func & 0xff); - } - if (*str == ',') str++; - while (*str != ':') - addbyte (*str++); - addbyte (':'); - break; - - case 'c': /* Call a special function. */ - addbyte (*str++); - addbyte (*str); - break; - - case 'K': /* A constant.... may have an "F" in it. */ - addbyte (*str); - load_const = TRUE; - break; - - case 'd': /* Decrement. */ - case 'i': /* Increment. */ - case 'l': /* Load. */ - case 's': /* Store. */ - case 'A': /* Array Increment */ - case 'M': /* Array Decrement */ - case 'L': /* Array Load */ - case 'S': /* Array Store */ - addbyte (*str++); - vaf_name = long_val (&str); - if (vaf_name < 128) - addbyte (vaf_name); - else - { - addbyte ((vaf_name >> 8) & 0xff | 0x80); - addbyte (vaf_name & 0xff); - } - break; - - case '@': /* A command! */ - switch (*(++str)) - { - case 'i': - init_load (); - break; - case 'r': - execute (); - break; - } - break; - - case '\n': /* Ignore the newlines */ - break; - - default: /* Anything else */ - addbyte (*str); - } - str++; - } - } -} diff --git a/gnu/usr.bin/bc/main.c b/gnu/usr.bin/bc/main.c deleted file mode 100644 index 0aefcc32115..00000000000 --- a/gnu/usr.bin/bc/main.c +++ /dev/null @@ -1,206 +0,0 @@ -/* $NetBSD: main.c,v 1.3 1994/12/02 00:43:36 phil Exp $ */ - -/* main.c: The main program for bc. */ - -/* 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 <signal.h> -#include "global.h" -#include "proto.h" - -/* Variables for processing multiple files. */ -char first_file; -extern FILE *yyin; - - -/* The main program for bc. */ -int -main (argc, argv) - int argc; - char *argv[]; -{ - int ch; - - /* Initialize many variables. */ - compile_only = FALSE; - use_math = FALSE; - warn_not_std = FALSE; - std_only = FALSE; - if (isatty(0) && isatty(1)) - interactive = TRUE; - else - interactive = FALSE; - - /* Parse the command line */ - ch = getopt (argc, argv, "lcisvw"); - while (ch != EOF) - { - switch (ch) - { - case 'c': /* compile only */ - compile_only = TRUE; - break; - case 'l': /* math lib */ - use_math = TRUE; - break; - case 'i': /* force interactive */ - interactive = TRUE; - break; - case 'w': /* Non standard features give warnings. */ - warn_not_std = TRUE; - break; - case 's': /* Non standard features give errors. */ - std_only = TRUE; - break; - case 'v': /* Print the version. */ - printf ("%s\n", BC_VERSION); - break; - } - ch = getopt (argc, argv, "lcisvw"); - } - - /* Initialize the machine. */ - init_storage(); - init_load(); - - /* Set up interrupts to print a message. */ - if (interactive) - signal (SIGINT, use_quit); - - /* Initialize the front end. */ - init_tree(); - init_gen (); - g_argv = argv; - g_argc = argc; - is_std_in = FALSE; - first_file = TRUE; - if (!open_new_file ()) - exit (1); - - /* Do the parse. */ - yyparse (); - - /* End the compile only output with a newline. */ - if (compile_only) - printf ("\n"); - - exit (0); -} - - -/* This is the function that opens all the files. - It returns TRUE if the file was opened, otherwise - it returns FALSE. */ - -int -open_new_file () -{ - FILE *new_file; - - /* Set the line number. */ - line_no = 1; - - /* Check to see if we are done. */ - if (is_std_in) return (FALSE); - - /* Open the other files. */ - if (use_math && first_file) - { -#ifdef BC_MATH_FILE - /* Make the first file be the math library. */ - new_file = fopen (BC_MATH_FILE, "r"); - use_math = FALSE; - if (new_file != NULL) - { - new_yy_file (new_file); - return TRUE; - } - else - { - fprintf (stderr, "Math Library unavailable.\n"); - exit (1); - } -#else - /* Load the code from a precompiled version of the math libarary. */ - extern char libmath[]; - char tmp; - /* These MUST be in the order of first mention of each function. - That is why "a" comes before "c" even though "a" is defined after - after "c". "a" is used in "s"! */ - tmp = lookup ("e", FUNCT); - tmp = lookup ("l", FUNCT); - tmp = lookup ("s", FUNCT); - tmp = lookup ("a", FUNCT); - tmp = lookup ("c", FUNCT); - tmp = lookup ("j", FUNCT); - load_code (libmath); -#endif - } - - /* One of the argv values. */ - while (optind < g_argc) - { - new_file = fopen (g_argv[optind], "r"); - if (new_file != NULL) - { - new_yy_file (new_file); - optind++; - return TRUE; - } - fprintf (stderr, "File %s is unavailable.\n", g_argv[optind++]); - exit (1); - } - - /* If we fall through to here, we should return stdin. */ - new_yy_file (stdin); - is_std_in = TRUE; - return TRUE; -} - - -/* Set yyin to the new file. */ - -void -new_yy_file (file) - FILE *file; -{ - if (!first_file) fclose (yyin); - yyin = file; - first_file = FALSE; -} - - -/* Message to use quit. */ - -void -use_quit (sig) - int sig; -{ - printf ("\n(interrupt) use quit to exit.\n"); - signal (SIGINT, use_quit); -} diff --git a/gnu/usr.bin/bc/number.c b/gnu/usr.bin/bc/number.c deleted file mode 100644 index b436fc54402..00000000000 --- a/gnu/usr.bin/bc/number.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* $NetBSD: number.c,v 1.3 1994/12/02 00:43:37 phil Exp $ */ - -/* number.c: Implements arbitrary precision numbers. */ - -/* 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 "proto.h" - -/* Storage used for special numbers. */ -bc_num _zero_; -bc_num _one_; -bc_num _two_; - - -/* "Frees" a bc_num NUM. Actually decreases reference count and only - frees the storage if reference count is zero. */ - -void -free_num (num) - bc_num *num; -{ - if (*num == NULL) return; - (*num)->n_refs--; - if ((*num)->n_refs == 0) free(*num); - *num = NULL; -} - - -/* new_num allocates a number and sets fields to known values. */ - -bc_num -new_num (length, scale) - int length, scale; -{ - bc_num temp; - - temp = (bc_num) malloc (sizeof(bc_struct)+length+scale); - if (temp == NULL) out_of_memory (); - temp->n_sign = PLUS; - temp->n_len = length; - temp->n_scale = scale; - temp->n_refs = 1; - temp->n_value[0] = 0; - return temp; -} - - -/* Intitialize the number package! */ - -void -init_numbers () -{ - _zero_ = new_num (1,0); - _one_ = new_num (1,0); - _one_->n_value[0] = 1; - _two_ = new_num (1,0); - _two_->n_value[0] = 2; -} - - -/* Make a copy of a number! Just increments the reference count! */ - -bc_num -copy_num (num) - bc_num num; -{ - num->n_refs++; - return num; -} - - -/* Initialize a number NUM by making it a copy of zero. */ - -void -init_num (num) - bc_num *num; -{ - *num = copy_num (_zero_); -} - - -/* Convert an integer VAL to a bc number NUM. */ - -void -int2num (num, val) - bc_num *num; - int val; -{ - char buffer[30]; - char *bptr, *vptr; - int ix = 1; - char neg = 0; - - /* Sign. */ - if (val < 0) - { - neg = 1; - val = -val; - } - - /* Get things going. */ - bptr = buffer; - *bptr++ = val % 10; - val = val / 10; - - /* Extract remaining digits. */ - while (val != 0) - { - *bptr++ = val % 10; - val = val / 10; - ix++; /* Count the digits. */ - } - - /* Make the number. */ - free_num (num); - *num = new_num (ix, 0); - if (neg) (*num)->n_sign = MINUS; - - /* Assign the digits. */ - vptr = (*num)->n_value; - while (ix-- > 0) - *vptr++ = *--bptr; -} - - -/* Convert a number NUM to a long. The function returns only the integer - part of the number. For numbers that are too large to represent as - a long, this function returns a zero. This can be detected by checking - the NUM for zero after having a zero returned. */ - -long -num2long (num) - bc_num num; -{ - long val; - char *nptr; - int index; - - /* Extract the int value, ignore the fraction. */ - val = 0; - nptr = num->n_value; - for (index=num->n_len; (index>0) && (val<=(LONG_MAX/10)); index--) - val = val*10 + *nptr++; - - /* Check for overflow. If overflow, return zero. */ - if (index>0) val = 0; - if (val < 0) val = 0; - - /* Return the value. */ - if (num->n_sign == PLUS) - return (val); - else - return (-val); -} - - -/* The following are some math routines for numbers. */ -_PROTOTYPE(static int _do_compare, (bc_num n1, bc_num n2, int use_sign, - int ignore_last)); -_PROTOTYPE(static void _rm_leading_zeros, (bc_num num)); -_PROTOTYPE(static bc_num _do_add, (bc_num n1, bc_num n2)); -_PROTOTYPE(static bc_num _do_sub, (bc_num n1, bc_num n2)); -_PROTOTYPE(static void _one_mult, (unsigned char *num, int size, int digit, - unsigned char *result)); - - - -/* Compare two bc numbers. Return value is 0 if equal, -1 if N1 is less - than N2 and +1 if N1 is greater than N2. If USE_SIGN is false, just - compare the magnitudes. */ - -static int -_do_compare (n1, n2, use_sign, ignore_last) - bc_num n1, n2; - int use_sign; - int ignore_last; -{ - char *n1ptr, *n2ptr; - int count; - - /* First, compare signs. */ - if (use_sign && n1->n_sign != n2->n_sign) - { - if (n1->n_sign == PLUS) - return (1); /* Positive N1 > Negative N2 */ - else - return (-1); /* Negative N1 < Positive N1 */ - } - - /* Now compare the magnitude. */ - if (n1->n_len != n2->n_len) - { - if (n1->n_len > n2->n_len) - { - /* Magnitude of n1 > n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (1); - else - return (-1); - } - else - { - /* Magnitude of n1 < n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (-1); - else - return (1); - } - } - - /* If we get here, they have the same number of integer digits. - check the integer part and the equal length part of the fraction. */ - count = n1->n_len + MIN (n1->n_scale, n2->n_scale); - n1ptr = n1->n_value; - n2ptr = n2->n_value; - - while ((count > 0) && (*n1ptr == *n2ptr)) - { - n1ptr++; - n2ptr++; - count--; - } - if (ignore_last && count == 1 && n1->n_scale == n2->n_scale) - return (0); - if (count != 0) - { - if (*n1ptr > *n2ptr) - { - /* Magnitude of n1 > n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (1); - else - return (-1); - } - else - { - /* Magnitude of n1 < n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (-1); - else - return (1); - } - } - - /* They are equal up to the last part of the equal part of the fraction. */ - if (n1->n_scale != n2->n_scale) - if (n1->n_scale > n2->n_scale) - { - for (count = n1->n_scale-n2->n_scale; count>0; count--) - if (*n1ptr++ != 0) - { - /* Magnitude of n1 > n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (1); - else - return (-1); - } - } - else - { - for (count = n2->n_scale-n1->n_scale; count>0; count--) - if (*n2ptr++ != 0) - { - /* Magnitude of n1 < n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (-1); - else - return (1); - } - } - - /* They must be equal! */ - return (0); -} - - -/* This is the "user callable" routine to compare numbers N1 and N2. */ - -int -bc_compare (n1, n2) - bc_num n1, n2; -{ - return _do_compare (n1, n2, TRUE, FALSE); -} - - -/* In some places we need to check if the number NUM is zero. */ - -char -is_zero (num) - bc_num num; -{ - int count; - char *nptr; - - /* Quick check. */ - if (num == _zero_) return TRUE; - - /* Initialize */ - count = num->n_len + num->n_scale; - nptr = num->n_value; - - /* The check */ - while ((count > 0) && (*nptr++ == 0)) count--; - - if (count != 0) - return FALSE; - else - return TRUE; -} - - -/* In some places we need to check if the number is negative. */ - -char -is_neg (num) - bc_num num; -{ - return num->n_sign == MINUS; -} - - -/* For many things, we may have leading zeros in a number NUM. - _rm_leading_zeros just moves the data to the correct - place and adjusts the length. */ - -static void -_rm_leading_zeros (num) - bc_num num; -{ - int bytes; - char *dst, *src; - - /* Do a quick check to see if we need to do it. */ - if (*num->n_value != 0) return; - - /* The first digit is 0, find the first non-zero digit in the 10's or - greater place. */ - bytes = num->n_len; - src = num->n_value; - while (bytes > 1 && *src == 0) src++, bytes--; - num->n_len = bytes; - bytes += num->n_scale; - dst = num->n_value; - while (bytes-- > 0) *dst++ = *src++; - -} - - -/* Perform addition: N1 is added to N2 and the value is - returned. The signs of N1 and N2 are ignored. */ - -static bc_num -_do_add (n1, n2) - bc_num n1, n2; -{ - bc_num sum; - int sum_scale, sum_digits; - char *n1ptr, *n2ptr, *sumptr; - int carry, n1bytes, n2bytes; - - /* Prepare sum. */ - sum_scale = MAX (n1->n_scale, n2->n_scale); - sum_digits = MAX (n1->n_len, n2->n_len) + 1; - sum = new_num (sum_digits,sum_scale); - - /* Start with the fraction part. Initialize the pointers. */ - n1bytes = n1->n_scale; - n2bytes = n2->n_scale; - n1ptr = (char *) (n1->n_value + n1->n_len + n1bytes - 1); - n2ptr = (char *) (n2->n_value + n2->n_len + n2bytes - 1); - sumptr = (char *) (sum->n_value + sum_scale + sum_digits - 1); - - /* Add the fraction part. First copy the longer fraction.*/ - if (n1bytes != n2bytes) - { - if (n1bytes > n2bytes) - while (n1bytes>n2bytes) - { *sumptr-- = *n1ptr--; n1bytes--;} - else - while (n2bytes>n1bytes) - { *sumptr-- = *n2ptr--; n2bytes--;} - } - - /* Now add the remaining fraction part and equal size integer parts. */ - n1bytes += n1->n_len; - n2bytes += n2->n_len; - carry = 0; - while ((n1bytes > 0) && (n2bytes > 0)) - { - *sumptr = *n1ptr-- + *n2ptr-- + carry; - if (*sumptr > 9) - { - carry = 1; - *sumptr -= 10; - } - else - carry = 0; - sumptr--; - n1bytes--; - n2bytes--; - } - - /* Now add carry the longer integer part. */ - if (n1bytes == 0) - { n1bytes = n2bytes; n1ptr = n2ptr; } - while (n1bytes-- > 0) - { - *sumptr = *n1ptr-- + carry; - if (*sumptr > 9) - { - carry = 1; - *sumptr -= 10; - } - else - carry = 0; - sumptr--; - } - - /* Set final carry. */ - if (carry == 1) - *sumptr += 1; - - /* Adjust sum and return. */ - _rm_leading_zeros (sum); - return sum; -} - - -/* Perform subtraction: N2 is subtracted from N1 and the value is - returned. The signs of N1 and N2 are ignored. Also, N1 is - assumed to be larger than N2. */ - -static bc_num -_do_sub (n1, n2) - bc_num n1, n2; -{ - bc_num diff; - int diff_scale, diff_len; - int min_scale, min_len; - char *n1ptr, *n2ptr, *diffptr; - int borrow, count, val; - - /* Allocate temporary storage. */ - diff_len = MAX (n1->n_len, n2->n_len); - diff_scale = MAX (n1->n_scale, n2->n_scale); - min_len = MIN (n1->n_len, n2->n_len); - min_scale = MIN (n1->n_scale, n2->n_scale); - diff = new_num (diff_len, diff_scale); - - /* Initialize the subtract. */ - n1ptr = (char *) (n1->n_value + n1->n_len + n1->n_scale -1); - n2ptr = (char *) (n2->n_value + n2->n_len + n2->n_scale -1); - diffptr = (char *) (diff->n_value + diff_len + diff_scale -1); - - /* Subtract the numbers. */ - borrow = 0; - - /* Take care of the longer scaled number. */ - if (n1->n_scale != min_scale) - { - /* n1 has the longer scale */ - for (count = n1->n_scale - min_scale; count > 0; count--) - *diffptr-- = *n1ptr--; - } - else - { - /* n2 has the longer scale */ - for (count = n2->n_scale - min_scale; count > 0; count--) - { - val = - *n2ptr-- - borrow; - if (val < 0) - { - val += 10; - borrow = 1; - } - else - borrow = 0; - *diffptr-- = val; - } - } - - /* Now do the equal length scale and integer parts. */ - - for (count = 0; count < min_len + min_scale; count++) - { - val = *n1ptr-- - *n2ptr-- - borrow; - if (val < 0) - { - val += 10; - borrow = 1; - } - else - borrow = 0; - *diffptr-- = val; - } - - /* If n1 has more digits then n2, we now do that subtract. */ - if (diff_len != min_len) - { - for (count = diff_len - min_len; count > 0; count--) - { - val = *n1ptr-- - borrow; - if (val < 0) - { - val += 10; - borrow = 1; - } - else - borrow = 0; - *diffptr-- = val; - } - } - - /* Clean up and return. */ - _rm_leading_zeros (diff); - return diff; -} - - -/* Here is the full add routine that takes care of negative numbers. - N1 is added to N2 and the result placed into RESULT. */ - -void -bc_add ( n1, n2, result) - bc_num n1, n2, *result; -{ - bc_num sum; - int cmp_res; - - if (n1->n_sign == n2->n_sign) - { - sum = _do_add (n1, n2); - sum->n_sign = n1->n_sign; - } - else - { - /* subtraction must be done. */ - cmp_res = _do_compare (n1, n2, FALSE, FALSE); /* Compare magnitudes. */ - switch (cmp_res) - { - case -1: - /* n1 is less than n2, subtract n1 from n2. */ - sum = _do_sub (n2, n1); - sum->n_sign = n2->n_sign; - break; - case 0: - /* They are equal! return zero! */ - sum = copy_num (_zero_); - break; - case 1: - /* n2 is less than n1, subtract n2 from n1. */ - sum = _do_sub (n1, n2); - sum->n_sign = n1->n_sign; - } - } - - /* Clean up and return. */ - free_num (result); - *result = sum; -} - - -/* Here is the full subtract routine that takes care of negative numbers. - N2 is subtracted from N1 and the result placed in RESULT. */ - -void -bc_sub ( n1, n2, result) - bc_num n1, n2, *result; -{ - bc_num diff; - int cmp_res; - - if (n1->n_sign != n2->n_sign) - { - diff = _do_add (n1, n2); - diff->n_sign = n1->n_sign; - } - else - { - /* subtraction must be done. */ - cmp_res = _do_compare (n1, n2, FALSE, FALSE); /* Compare magnitudes. */ - switch (cmp_res) - { - case -1: - /* n1 is less than n2, subtract n1 from n2. */ - diff = _do_sub (n2, n1); - diff->n_sign = (n2->n_sign == PLUS ? MINUS : PLUS); - break; - case 0: - /* They are equal! return zero! */ - diff = copy_num (_zero_); - break; - case 1: - /* n2 is less than n1, subtract n2 from n1. */ - diff = _do_sub (n1, n2); - diff->n_sign = n1->n_sign; - break; - } - } - - /* Clean up and return. */ - free_num (result); - *result = diff; -} - - -/* The multiply routine. N2 time N1 is put int PROD with the scale of - the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)). - */ - -void -bc_multiply (n1, n2, prod, scale) - bc_num n1, n2, *prod; - int scale; -{ - bc_num pval; /* For the working storage. */ - char *n1ptr, *n2ptr, *pvptr; /* Work pointers. */ - char *n1end, *n2end; /* To the end of n1 and n2. */ - - int indx; - int len1, len2, total_digits; - long sum; - int full_scale, prod_scale; - int toss; - - /* Initialize things. */ - len1 = n1->n_len + n1->n_scale; - len2 = n2->n_len + n2->n_scale; - total_digits = len1 + len2; - full_scale = n1->n_scale + n2->n_scale; - prod_scale = MIN(full_scale,MAX(scale,MAX(n1->n_scale,n2->n_scale))); - toss = full_scale - prod_scale; - pval = new_num (total_digits-full_scale, prod_scale); - pval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS ); - n1end = (char *) (n1->n_value + len1 - 1); - n2end = (char *) (n2->n_value + len2 - 1); - pvptr = (char *) (pval->n_value + total_digits - toss - 1); - sum = 0; - - /* Here are the loops... */ - for (indx = 0; indx < toss; indx++) - { - n1ptr = (char *) (n1end - MAX(0, indx-len2+1)); - n2ptr = (char *) (n2end - MIN(indx, len2-1)); - while ((n1ptr >= n1->n_value) && (n2ptr <= n2end)) - sum += *n1ptr-- * *n2ptr++; - sum = sum / 10; - } - for ( ; indx < total_digits-1; indx++) - { - n1ptr = (char *) (n1end - MAX(0, indx-len2+1)); - n2ptr = (char *) (n2end - MIN(indx, len2-1)); - while ((n1ptr >= n1->n_value) && (n2ptr <= n2end)) - sum += *n1ptr-- * *n2ptr++; - *pvptr-- = sum % 10; - sum = sum / 10; - } - *pvptr-- = sum; - - /* Assign to prod and clean up the number. */ - free_num (prod); - *prod = pval; - _rm_leading_zeros (*prod); - if (is_zero (*prod)) - (*prod)->n_sign = PLUS; -} - - -/* Some utility routines for the divide: First a one digit multiply. - NUM (with SIZE digits) is multiplied by DIGIT and the result is - placed into RESULT. It is written so that NUM and RESULT can be - the same pointers. */ - -static void -_one_mult (num, size, digit, result) - unsigned char *num; - int size, digit; - unsigned char *result; -{ - int carry, value; - unsigned char *nptr, *rptr; - - if (digit == 0) - memset (result, 0, size); - else - { - if (digit == 1) - memcpy (result, num, size); - else - { - /* Initialize */ - nptr = (unsigned char *) (num+size-1); - rptr = (unsigned char *) (result+size-1); - carry = 0; - - while (size-- > 0) - { - value = *nptr-- * digit + carry; - *rptr-- = value % 10; - carry = value / 10; - } - - if (carry != 0) *rptr = carry; - } - } -} - - -/* The full division routine. This computes N1 / N2. It returns - 0 if the division is ok and the result is in QUOT. The number of - digits after the decimal point is SCALE. It returns -1 if division - by zero is tried. The algorithm is found in Knuth Vol 2. p237. */ - -int -bc_divide (n1, n2, quot, scale) - bc_num n1, n2, *quot; - int scale; -{ - bc_num qval; - unsigned char *num1, *num2; - unsigned char *ptr1, *ptr2, *n2ptr, *qptr; - int scale1, val; - unsigned int len1, len2, scale2, qdigits, extra, count; - unsigned int qdig, qguess, borrow, carry; - unsigned char *mval; - char zero; - unsigned int norm; - - /* Test for divide by zero. */ - if (is_zero (n2)) return -1; - - /* Test for divide by 1. If it is we must truncate. */ - if (n2->n_scale == 0) - { - if (n2->n_len == 1 && *n2->n_value == 1) - { - qval = new_num (n1->n_len, scale); - qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS); - memset (&qval->n_value[n1->n_len],0,scale); - memcpy (qval->n_value, n1->n_value, - n1->n_len + MIN(n1->n_scale,scale)); - free_num (quot); - *quot = qval; - } - } - - /* Set up the divide. Move the decimal point on n1 by n2's scale. - Remember, zeros on the end of num2 are wasted effort for dividing. */ - scale2 = n2->n_scale; - n2ptr = (unsigned char *) n2->n_value+n2->n_len+scale2-1; - while ((scale2 > 0) && (*n2ptr-- == 0)) scale2--; - - len1 = n1->n_len + scale2; - scale1 = n1->n_scale - scale2; - if (scale1 < scale) - extra = scale - scale1; - else - extra = 0; - num1 = (unsigned char *) malloc (n1->n_len+n1->n_scale+extra+2); - if (num1 == NULL) out_of_memory(); - memset (num1, 0, n1->n_len+n1->n_scale+extra+2); - memcpy (num1+1, n1->n_value, n1->n_len+n1->n_scale); - - len2 = n2->n_len + scale2; - num2 = (unsigned char *) malloc (len2+1); - if (num2 == NULL) out_of_memory(); - memcpy (num2, n2->n_value, len2); - *(num2+len2) = 0; - n2ptr = num2; - while (*n2ptr == 0) - { - n2ptr++; - len2--; - } - - /* Calculate the number of quotient digits. */ - if (len2 > len1+scale) - { - qdigits = scale+1; - zero = TRUE; - } - else - { - zero = FALSE; - if (len2>len1) - qdigits = scale+1; /* One for the zero integer part. */ - else - qdigits = len1-len2+scale+1; - } - - /* Allocate and zero the storage for the quotient. */ - qval = new_num (qdigits-scale,scale); - memset (qval->n_value, 0, qdigits); - - /* Allocate storage for the temporary storage mval. */ - mval = (unsigned char *) malloc (len2+1); - if (mval == NULL) out_of_memory (); - - /* Now for the full divide algorithm. */ - if (!zero) - { - /* Normalize */ - norm = 10 / ((int)*n2ptr + 1); - if (norm != 1) - { - _one_mult (num1, len1+scale1+extra+1, norm, num1); - _one_mult (n2ptr, len2, norm, n2ptr); - } - - /* Initialize divide loop. */ - qdig = 0; - if (len2 > len1) - qptr = (unsigned char *) qval->n_value+len2-len1; - else - qptr = (unsigned char *) qval->n_value; - - /* Loop */ - while (qdig <= len1+scale-len2) - { - /* Calculate the quotient digit guess. */ - if (*n2ptr == num1[qdig]) - qguess = 9; - else - qguess = (num1[qdig]*10 + num1[qdig+1]) / *n2ptr; - - /* Test qguess. */ - if (n2ptr[1]*qguess > - (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10 - + num1[qdig+2]) - { - qguess--; - /* And again. */ - if (n2ptr[1]*qguess > - (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10 - + num1[qdig+2]) - qguess--; - } - - /* Multiply and subtract. */ - borrow = 0; - if (qguess != 0) - { - *mval = 0; - _one_mult (n2ptr, len2, qguess, mval+1); - ptr1 = (unsigned char *) num1+qdig+len2; - ptr2 = (unsigned char *) mval+len2; - for (count = 0; count < len2+1; count++) - { - val = (int) *ptr1 - (int) *ptr2-- - borrow; - if (val < 0) - { - val += 10; - borrow = 1; - } - else - borrow = 0; - *ptr1-- = val; - } - } - - /* Test for negative result. */ - if (borrow == 1) - { - qguess--; - ptr1 = (unsigned char *) num1+qdig+len2; - ptr2 = (unsigned char *) n2ptr+len2-1; - carry = 0; - for (count = 0; count < len2; count++) - { - val = (int) *ptr1 + (int) *ptr2-- + carry; - if (val > 9) - { - val -= 10; - carry = 1; - } - else - carry = 0; - *ptr1-- = val; - } - if (carry == 1) *ptr1 = (*ptr1 + 1) % 10; - } - - /* We now know the quotient digit. */ - *qptr++ = qguess; - qdig++; - } - } - - /* Clean up and return the number. */ - qval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS ); - if (is_zero (qval)) qval->n_sign = PLUS; - _rm_leading_zeros (qval); - free_num (quot); - *quot = qval; - - /* Clean up temporary storage. */ - free (mval); - free (num1); - free (num2); - - return 0; /* Everything is OK. */ -} - - -/* Modulo for numbers. This computes NUM1 % NUM2 and puts the - result in RESULT. */ - -int -bc_modulo (num1, num2, result, scale) - bc_num num1, num2, *result; - int scale; -{ - bc_num temp; - int rscale; - - /* Check for correct numbers. */ - if (is_zero (num2)) return -1; - - /* Calculate final scale. */ - rscale = MAX (num1->n_scale, num2->n_scale+scale); - init_num (&temp); - - /* Calculate it. */ - bc_divide (num1, num2, &temp, scale); - bc_multiply (temp, num2, &temp, rscale); - bc_sub (num1, temp, result); - free_num (&temp); - - return 0; /* Everything is OK. */ -} - - -/* Raise NUM1 to the NUM2 power. The result is placed in RESULT. - Maximum exponent is LONG_MAX. If a NUM2 is not an integer, - only the integer part is used. */ - -void -bc_raise (num1, num2, result, scale) - bc_num num1, num2, *result; - int scale; -{ - bc_num temp, power; - long exponent; - int rscale; - char neg; - - /* Check the exponent for scale digits and convert to a long. */ - if (num2->n_scale != 0) - rt_warn ("non-zero scale in exponent"); - exponent = num2long (num2); - if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0)) - rt_error ("exponent too large in raise"); - - /* Special case if exponent is a zero. */ - if (exponent == 0) - { - free_num (result); - *result = copy_num (_one_); - return; - } - - /* Other initializations. */ - if (exponent < 0) - { - neg = TRUE; - exponent = -exponent; - rscale = scale; - } - else - { - neg = FALSE; - rscale = MIN (num1->n_scale*exponent, MAX(scale, num1->n_scale)); - } - - /* 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) - { - bc_multiply (power, power, &power, rscale); - if ((exponent & 1) == 1) - bc_multiply (temp, power, &temp, rscale); - exponent = exponent >> 1; - } - - /* Assign the value. */ - if (neg) - { - bc_divide (_one_, temp, result, rscale); - free_num (&temp); - } - else - { - free_num (result); - *result = temp; - } - free_num (&power); -} - - -/* Take the square root NUM and return it in NUM with SCALE digits - after the decimal place. */ - -int -bc_sqrt (num, scale) - bc_num *num; - int scale; -{ - int rscale, cmp_res, done; - int cscale; - bc_num guess, guess1, point5; - - /* Initial checks. */ - cmp_res = bc_compare (*num, _zero_); - if (cmp_res < 0) - return 0; /* error */ - else - { - if (cmp_res == 0) - { - free_num (num); - *num = copy_num (_zero_); - return 1; - } - } - cmp_res = bc_compare (*num, _one_); - if (cmp_res == 0) - { - free_num (num); - *num = copy_num (_one_); - return 1; - } - - /* Initialize the variables. */ - rscale = MAX (scale, (*num)->n_scale); - init_num (&guess); - init_num (&guess1); - point5 = new_num (1,1); - point5->n_value[1] = 5; - - - /* Calculate the initial guess. */ - if (cmp_res < 0) - /* The number is between 0 and 1. Guess should start at 1. */ - guess = copy_num (_one_); - else - { - /* 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, 0); - guess1->n_scale = 0; - 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); - guess1 = copy_num (guess); - bc_divide (*num,guess,&guess,cscale); - bc_add (guess,guess1,&guess); - bc_multiply (guess,point5,&guess,cscale); - cmp_res = _do_compare (guess,guess1,FALSE,TRUE); - if (cmp_res == 0) - if (cscale < rscale+1) - cscale = MIN (cscale*3, rscale+1); - else - done = TRUE; - } - - /* Assign the number and clean up. */ - free_num (num); - bc_divide (guess,_one_,num,rscale); - free_num (&guess); - free_num (&guess1); - free_num (&point5); - return 1; -} - - -/* The following routines provide output for bcd numbers package - using the rules of POSIX bc for output. */ - -/* This structure is used for saving digits in the conversion process. */ -typedef struct stk_rec { - long digit; - struct stk_rec *next; -} stk_rec; - -/* The reference string for digits. */ -char ref_str[] = "0123456789ABCDEF"; - - -/* A special output routine for "multi-character digits." Exactly - SIZE characters must be output for the value VAL. If SPACE is - non-zero, we must output one space before the number. OUT_CHAR - is the actual routine for writing the characters. */ - -void -out_long (val, size, space, out_char) - long val; - int size, space; -#ifdef __STDC__ - void (*out_char)(int); -#else - void (*out_char)(); -#endif -{ - char digits[40]; - int len, ix; - - if (space) (*out_char) (' '); - sprintf (digits, "%ld", val); - len = strlen (digits); - while (size > len) - { - (*out_char) ('0'); - size--; - } - for (ix=0; ix < len; ix++) - (*out_char) (digits[ix]); -} - -/* Output of a bcd number. NUM is written in base O_BASE using OUT_CHAR - as the routine to do the actual output of the characters. */ - -void -out_num (num, o_base, out_char) - bc_num num; - int o_base; -#ifdef __STDC__ - void (*out_char)(int); -#else - void (*out_char)(); -#endif -{ - char *nptr; - int index, fdigit, pre_space; - stk_rec *digits, *temp; - bc_num int_part, frac_part, base, cur_dig, t_num, max_o_digit; - - /* The negative sign if needed. */ - if (num->n_sign == MINUS) (*out_char) ('-'); - - /* Output the number. */ - if (is_zero (num)) - (*out_char) ('0'); - else - if (o_base == 10) - { - /* The number is in base 10, do it the fast way. */ - nptr = num->n_value; - if (num->n_len > 1 || *nptr != 0) - for (index=num->n_len; index>0; index--) - (*out_char) (BCD_CHAR(*nptr++)); - else - nptr++; - - /* Now the fraction. */ - if (num->n_scale > 0) - { - (*out_char) ('.'); - for (index=0; index<num->n_scale; index++) - (*out_char) (BCD_CHAR(*nptr++)); - } - } - else - { - /* The number is some other base. */ - digits = NULL; - init_num (&int_part); - bc_divide (num, _one_, &int_part, 0); - init_num (&frac_part); - 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); - - - /* Get the digits of the integer part and push them on a stack. */ - while (!is_zero (int_part)) - { - bc_modulo (int_part, base, &cur_dig, 0); - temp = (stk_rec *) malloc (sizeof(stk_rec)); - if (temp == NULL) out_of_memory(); - temp->digit = num2long (cur_dig); - temp->next = digits; - digits = temp; - bc_divide (int_part, base, &int_part, 0); - } - - /* Print the digits on the stack. */ - if (digits != NULL) - { - /* Output the digits. */ - while (digits != NULL) - { - temp = digits; - digits = digits->next; - if (o_base <= 16) - (*out_char) (ref_str[ (int) temp->digit]); - else - out_long (temp->digit, max_o_digit->n_len, 1, out_char); - free (temp); - } - } - - /* Get and print the digits of the fraction part. */ - if (num->n_scale > 0) - { - (*out_char) ('.'); - pre_space = 0; - t_num = copy_num (_one_); - while (t_num->n_len <= num->n_scale) { - bc_multiply (frac_part, base, &frac_part, num->n_scale); - fdigit = num2long (frac_part); - int2num (&int_part, fdigit); - bc_sub (frac_part, int_part, &frac_part); - if (o_base <= 16) - (*out_char) (ref_str[fdigit]); - else { - out_long (fdigit, max_o_digit->n_len, pre_space, out_char); - pre_space = 1; - } - bc_multiply (t_num, base, &t_num, 0); - } - } - - /* Clean up. */ - free_num (&int_part); - free_num (&frac_part); - free_num (&base); - free_num (&cur_dig); - } -} - - -#if DEBUG > 0 - -/* Debugging procedures. Some are just so one can call them from the - debugger. */ - -/* p_n prints the number NUM in base 10. */ - -void -p_n (num) - bc_num num; -{ - out_num (num, 10, out_char); -} - - -/* p_b prints a character array as if it was a string of bcd digits. */ -void -p_v (name, num, len) - char *name; - unsigned char *num; - int len; -{ - int i; - printf ("%s=", name); - for (i=0; i<len; i++) printf ("%c",BCD_CHAR(num[i])); - printf ("\n"); -} - - -/* Convert strings to bc numbers. Base 10 only.*/ - -void -str2num (num, str, scale) - bc_num *num; - char *str; - int scale; -{ - int digits, strscale; - char *ptr, *nptr; - char zero_int; - - /* Prepare num. */ - free_num (num); - - /* Check for valid number and count digits. */ - ptr = str; - digits = 0; - strscale = 0; - zero_int = FALSE; - if ( (*ptr == '+') || (*ptr == '-')) ptr++; /* Sign */ - while (*ptr == '0') ptr++; /* Skip leading zeros. */ - while (isdigit(*ptr)) ptr++, digits++; /* digits */ - if (*ptr == '.') ptr++; /* decimal point */ - while (isdigit(*ptr)) ptr++, strscale++; /* digits */ - if ((*ptr != '\0') || (digits+strscale == 0)) - { - *num = copy_num (_zero_); - return; - } - - /* Adjust numbers and allocate storage and initialize fields. */ - strscale = MIN(strscale, scale); - if (digits == 0) - { - zero_int = TRUE; - digits = 1; - } - *num = new_num (digits, strscale); - - /* Build the whole number. */ - ptr = str; - if (*ptr == '-') - { - (*num)->n_sign = MINUS; - ptr++; - } - else - { - (*num)->n_sign = PLUS; - if (*ptr == '+') ptr++; - } - while (*ptr == '0') ptr++; /* Skip leading zeros. */ - nptr = (*num)->n_value; - if (zero_int) - { - *nptr++ = 0; - digits = 0; - } - for (;digits > 0; digits--) - *nptr++ = CH_VAL(*ptr++); - - - /* Build the fractional part. */ - if (strscale > 0) - { - ptr++; /* skip the decimal point! */ - for (;strscale > 0; strscale--) - *nptr++ = CH_VAL(*ptr++); - } -} - -/* Convert a numbers to a string. Base 10 only.*/ - -char -*num2str (num) - bc_num num; -{ - char *str, *sptr; - char *nptr; - int index, signch; - - /* Allocate the string memory. */ - signch = ( num->n_sign == PLUS ? 0 : 1 ); /* Number of sign chars. */ - if (num->n_scale > 0) - str = (char *) malloc (num->n_len + num->n_scale + 2 + signch); - else - str = (char *) malloc (num->n_len + 1 + signch); - if (str == NULL) out_of_memory(); - - /* The negative sign if needed. */ - sptr = str; - if (signch) *sptr++ = '-'; - - /* Load the whole number. */ - nptr = num->n_value; - for (index=num->n_len; index>0; index--) - *sptr++ = BCD_CHAR(*nptr++); - - /* Now the fraction. */ - if (num->n_scale > 0) - { - *sptr++ = '.'; - for (index=0; index<num->n_scale; index++) - *sptr++ = BCD_CHAR(*nptr++); - } - - /* Terminate the string and return it! */ - *sptr = '\0'; - return (str); -} -#endif diff --git a/gnu/usr.bin/bc/number.h b/gnu/usr.bin/bc/number.h deleted file mode 100644 index 02552342942..00000000000 --- a/gnu/usr.bin/bc/number.h +++ /dev/null @@ -1,60 +0,0 @@ -/* number.h: Arbitrary precision numbers header file. */ - -/* 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 - -*************************************************************************/ - - -typedef enum {PLUS, MINUS} sign; - -typedef struct - { - sign n_sign; - int n_len; /* The number of digits before the decimal point. */ - int n_scale; /* The number of digits after the decimal point. */ - int n_refs; /* The number of pointers to this number. */ - char n_value[1]; /* The storage. Not zero char terminated. It is - allocated with all other fields. */ - } bc_struct; - -typedef bc_struct *bc_num; - -/* Some useful macros and constants. */ - -#define CH_VAL(c) (c - '0') -#define BCD_CHAR(d) (d + '0') - -#ifdef MIN -#undef MIN -#undef MAX -#endif -#define MAX(a,b) (a>b?a:b) -#define MIN(a,b) (a>b?b:a) -#define ODD(a) (a&1) - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif diff --git a/gnu/usr.bin/bc/proto.h b/gnu/usr.bin/bc/proto.h deleted file mode 100644 index d0dc9963164..00000000000 --- a/gnu/usr.bin/bc/proto.h +++ /dev/null @@ -1,168 +0,0 @@ -/* $NetBSD: proto.h,v 1.3 1994/12/02 00:43:39 phil Exp $ */ - -/* proto.h: Prototype function definitions for "external" functions. */ - -/* 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 - -*************************************************************************/ - -/* For the pc version using k&r ACK. (minix1.5 and earlier.) */ -#ifdef SHORTNAMES -#define init_numbers i_numbers -#define push_constant push__constant -#define load_const in_load_const -#define yy_get_next_buffer yyget_next_buffer -#define yy_init_buffer yyinit_buffer -#define yy_last_accepting_state yylast_accepting_state -#define arglist1 arg1list -#endif - -/* Include the standard library header files. */ -#ifndef NO_UNISTD -#include <unistd.h> -#endif -#ifndef NO_STDLIB -#ifdef __STDC__ -#include <stdlib.h> -#endif -#endif - -/* Define the _PROTOTYPE macro if it is needed. */ - -#ifndef _PROTOTYPE -#ifdef __STDC__ -#define _PROTOTYPE(func, args) func args -#else -#define _PROTOTYPE(func, args) func() -#endif -#endif - -/* From execute.c */ -_PROTOTYPE(void stop_execution, (int)); -_PROTOTYPE(unsigned char byte, (program_counter *pc)); -_PROTOTYPE(void execute, (void)); -_PROTOTYPE(char prog_char, (void)); -_PROTOTYPE(char input_char, (void)); -_PROTOTYPE(void push_constant, (char (*in_char)(void), int conv_base)); -_PROTOTYPE(void push_b10_const, (program_counter *pc)); -_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)); -_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)); -_PROTOTYPE(void generate, (char *str)); -_PROTOTYPE(void run_code, (void)); -_PROTOTYPE(void out_char, (int ch)); -_PROTOTYPE(id_rec *find_id, (id_rec *tree, char *id)); -_PROTOTYPE(int insert_id_rec, (id_rec **root, id_rec *new_id)); -_PROTOTYPE(void init_tree, (void)); -_PROTOTYPE(int lookup, (char *name, int namekind)); -_PROTOTYPE(char *bc_malloc, (int)); -_PROTOTYPE(void out_of_memory, (void)); -_PROTOTYPE(void welcome, (void)); -_PROTOTYPE(void warranty, (char *)); -_PROTOTYPE(void limits, (void)); -_PROTOTYPE(void yyerror, (char *str ,...)); -_PROTOTYPE(void warn, (char *mesg ,...)); -_PROTOTYPE(void rt_error, (char *mesg ,...)); -_PROTOTYPE(void rt_warn, (char *mesg ,...)); - -/* From load.c */ -_PROTOTYPE(void init_load, (void)); -_PROTOTYPE(void addbyte, (int byte)); -_PROTOTYPE(void def_label, (long lab)); -_PROTOTYPE(long long_val, (char **str)); -_PROTOTYPE(void load_code, (char *code)); - -/* From main.c */ -_PROTOTYPE(int main, (int argc , char *argv [])); -_PROTOTYPE(int open_new_file, (void)); -_PROTOTYPE(void new_yy_file, (FILE *file)); -_PROTOTYPE(void use_quit, (int)); - -/* From number.c */ -_PROTOTYPE(void free_num, (bc_num *num)); -_PROTOTYPE(bc_num new_num, (int length, int scale)); -_PROTOTYPE(void init_numbers, (void)); -_PROTOTYPE(bc_num copy_num, (bc_num num)); -_PROTOTYPE(void init_num, (bc_num *num)); -_PROTOTYPE(void str2num, (bc_num *num, char *str, int scale)); -_PROTOTYPE(char *num2str, (bc_num num)); -_PROTOTYPE(void int2num, (bc_num *num, int val)); -_PROTOTYPE(long num2long, (bc_num num)); -_PROTOTYPE(int bc_compare, (bc_num n1, bc_num n2)); -_PROTOTYPE(char is_zero, (bc_num num)); -_PROTOTYPE(char is_neg, (bc_num num)); -_PROTOTYPE(void bc_add, (bc_num n1, bc_num n2, bc_num *result)); -_PROTOTYPE(void bc_sub, (bc_num n1, bc_num n2, bc_num *result)); -_PROTOTYPE(void bc_multiply, (bc_num n1, bc_num n2, bc_num *prod, int scale)); -_PROTOTYPE(int bc_divide, (bc_num n1, bc_num n2, bc_num *quot, int scale)); -_PROTOTYPE(int bc_modulo, (bc_num num1, bc_num num2, bc_num *result, int scale)); -_PROTOTYPE(void bc_raise, (bc_num num1, bc_num num2, bc_num *result, int scale)); -_PROTOTYPE(int bc_sqrt, (bc_num *num, int scale)); -_PROTOTYPE(void out_long, (long val, int size, int space, - void (*out_char)(int))); -_PROTOTYPE(void out_num, (bc_num num, int o_base, void (* out_char)(int))); - - -/* From storage.c */ -_PROTOTYPE(void init_storage, (void)); -_PROTOTYPE(void more_functions, (void)); -_PROTOTYPE(void more_variables, (void)); -_PROTOTYPE(void more_arrays, (void)); -_PROTOTYPE(void clear_func, (int func )); -_PROTOTYPE(int fpop, (void)); -_PROTOTYPE(void fpush, (int val )); -_PROTOTYPE(void pop, (void)); -_PROTOTYPE(void push_copy, (bc_num num )); -_PROTOTYPE(void push_num, (bc_num num )); -_PROTOTYPE(char check_stack, (int depth )); -_PROTOTYPE(bc_var *get_var, (int var_name )); -_PROTOTYPE(bc_num *get_array_num, (int var_index, long index )); -_PROTOTYPE(void store_var, (int var_name )); -_PROTOTYPE(void store_array, (int var_name )); -_PROTOTYPE(void load_var, (int var_name )); -_PROTOTYPE(void load_array, (int var_name )); -_PROTOTYPE(void decr_var, (int var_name )); -_PROTOTYPE(void decr_array, (int var_name )); -_PROTOTYPE(void incr_var, (int var_name )); -_PROTOTYPE(void incr_array, (int var_name )); -_PROTOTYPE(void auto_var, (int name )); -_PROTOTYPE(void free_a_tree, (bc_array_node *root, int depth )); -_PROTOTYPE(void pop_vars, (arg_list *list )); -_PROTOTYPE(void process_params, (program_counter *pc, int func )); - -/* For the scanner and parser.... */ -_PROTOTYPE(int yyparse, (void)); -_PROTOTYPE(int yylex, (void)); - -/* Other things... */ -_PROTOTYPE (int getopt, (int, char *[], CONST char *)); - diff --git a/gnu/usr.bin/bc/sbc.y b/gnu/usr.bin/bc/sbc.y deleted file mode 100644 index 7e6e5b00e25..00000000000 --- a/gnu/usr.bin/bc/sbc.y +++ /dev/null @@ -1,450 +0,0 @@ -%{ -/* $NetBSD: sbc.y,v 1.2 1994/12/02 00:43:40 phil Exp $ */ - -/* sbc.y: A POSIX bc processor written for minix with no extensions. */ - -/* 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" /* To get the global variables. */ -#include "proto.h" -%} - -%start program - -%union { - char *s_value; - char c_value; - int i_value; - arg_list *a_value; - } - -%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' */ - -/* The types of all other non-terminals. */ -%type <i_value> expression named_expression return_expression -%type <a_value> opt_parameter_list parameter_list opt_auto_define_list -%type <a_value> define_list opt_argument_list argument_list -%type <i_value> program input_item semicolon_list statement_list -%type <i_value> statement_or_error statement function relational_expression - -/* precedence */ -%nonassoc REL_OP -%right ASSIGN_OP -%left '+' '-' -%left MUL_OP -%right '^' -%nonassoc UNARY_MINUS -%nonassoc INCR_DECR - -%% -program : /* empty */ - { - $$ = 0; - std_only = TRUE; - if (interactive) - { - printf ("s%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 - | statement_list NEWLINE - | statement_list NEWLINE statement - | statement_list ';' - | statement_list ';' statement - ; -statement_or_error : statement - | error statement - { $$ = $2; } - ; -statement : Warranty - { warranty("s"); } - | 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); - } - } - | Quit - { exit(0); } - | Return - { generate ("0R"); } - | Return '(' return_expression ')' - { generate ("R"); } - | For - { - $1 = break_label; - break_label = next_label++; - } - '(' expression ';' - { - $4 = next_label++; - sprintf (genstr, "pN%1d:", $4); - generate (genstr); - } - relational_expression ';' - { - $7 = next_label++; - sprintf (genstr, "B%1d:J%1d:", $7, break_label); - generate (genstr); - $<i_value>$ = next_label++; - sprintf (genstr, "N%1d:", $<i_value>$); - generate (genstr); - } - expression ')' - { - sprintf (genstr, "pJ%1d:N%1d:", $4, $7); - generate (genstr); - } - statement - { - sprintf (genstr, "J%1d:N%1d:", $<i_value>9, - break_label); - generate (genstr); - break_label = $1; - } - | If '(' relational_expression ')' - { - $3 = next_label++; - sprintf (genstr, "Z%1d:", $3); - generate (genstr); - } - statement - { - sprintf (genstr, "N%1d:", $3); - generate (genstr); - } - | While - { - $1 = next_label++; - sprintf (genstr, "N%1d:", $1); - generate (genstr); - } - '(' relational_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; } - ; -function : Define NAME '(' opt_parameter_list ')' '{' - NEWLINE opt_auto_define_list - { - check_params ($4,$8); - sprintf (genstr, "F%d,%s.%s[", lookup($2,FUNCT), - arg_str ($4,TRUE), arg_str ($8,TRUE)); - generate (genstr); - free_args ($4); - free_args ($8); - $1 = next_label; - next_label = 0; - } - statement_list NEWLINE '}' - { - generate ("0R]"); - next_label = $1; - } - ; -opt_parameter_list : /* empty */ - { $$ = NULL; } - | parameter_list - ; -parameter_list : NAME - { $$ = nextarg (NULL, lookup($1,SIMPLE)); } - | define_list ',' NAME - { $$ = nextarg ($1, lookup($3,SIMPLE)); } - ; -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 - { $$ = nextarg (NULL,0); } - | argument_list ',' expression - { $$ = nextarg ($1,0); } - ; -relational_expression : expression - { $$ = 0; } - | expression REL_OP expression - { - $$ = 0; - switch (*($2)) - { - case '=': - generate ("="); - break; - case '!': - generate ("#"); - break; - case '<': - if ($2[1] == '=') - generate ("{"); - else - generate ("<"); - break; - case '>': - if ($2[1] == '=') - generate ("}"); - else - generate (">"); - break; - } - } - ; -return_expression : /* empty */ - { - $$ = 0; - generate ("0"); - } - | expression - ; -expression : named_expression ASSIGN_OP - { - if ($2 != '=') - { - if ($1 < 0) - sprintf (genstr, "DL%d:", -$1); - else - sprintf (genstr, "l%d:", $1); - generate (genstr); - } - } - expression - { - $$ = 0; - if ($2 != '=') - { - sprintf (genstr, "%c", $2); - generate (genstr); - } - if ($1 < 0) - sprintf (genstr, "S%d:", -$1); - else - sprintf (genstr, "s%d:", $1); - generate (genstr); - } - | expression '+' expression - { generate ("+"); } - | expression '-' expression - { generate ("-"); } - | expression MUL_OP expression - { - genstr[0] = $2; - genstr[1] = 0; - generate (genstr); - } - | expression '^' expression - { generate ("^"); } - | '-' expression %prec UNARY_MINUS - { generate ("n"); $$ = 1;} - | 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 ')' - { $$ = 1; } - | NAME '(' opt_argument_list ')' - { - $$ = 1; - if ($3 != NULL) - { - sprintf (genstr, "C%d,%s:", lookup($1,FUNCT), - arg_str ($3,FALSE)); - 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;} - ; -named_expression : NAME - { $$ = lookup($1,SIMPLE); } - | NAME '[' expression ']' - { $$ = lookup($1,ARRAY); } - | Ibase - { $$ = 0; } - | Obase - { $$ = 1; } - | Scale - { $$ = 2; } - ; - -%% diff --git a/gnu/usr.bin/bc/scan.l b/gnu/usr.bin/bc/scan.l deleted file mode 100644 index 953229d4cd8..00000000000 --- a/gnu/usr.bin/bc/scan.l +++ /dev/null @@ -1,198 +0,0 @@ -%{ -/* $NetBSD: scan.l,v 1.2 1994/12/02 00:43:41 phil Exp $ */ - -/* 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. */ -} diff --git a/gnu/usr.bin/bc/storage.c b/gnu/usr.bin/bc/storage.c deleted file mode 100644 index 6ec556a57c3..00000000000 --- a/gnu/usr.bin/bc/storage.c +++ /dev/null @@ -1,965 +0,0 @@ -/* $NetBSD: storage.c,v 1.3 1994/12/02 00:43:43 phil Exp $ */ - -/* storage.c: Code and data storage manipulations. This includes labels. */ - -/* 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" - - -/* Initialize the storage at the beginning of the run. */ - -void -init_storage () -{ - - /* Functions: we start with none and ask for more. */ - f_count = 0; - more_functions (); - f_names[0] = "(main)"; - - /* Variables. */ - v_count = 0; - more_variables (); - - /* Arrays. */ - a_count = 0; - more_arrays (); - - /* Other things... */ - ex_stack = NULL; - fn_stack = NULL; - i_base = 10; - o_base = 10; - scale = 0; - c_code = FALSE; - init_numbers(); -} - -/* Three functions for increasing the number of functions, variables, or - arrays that are needed. This adds another 32 of the requested object. */ - -void -more_functions (VOID) -{ - int old_count; - int indx1, indx2; - bc_function *old_f; - bc_function *f; - char **old_names; - - /* Save old information. */ - old_count = f_count; - old_f = functions; - old_names = f_names; - - /* Add a fixed amount and allocate new space. */ - f_count += STORE_INCR; - functions = (bc_function *) bc_malloc (f_count*sizeof (bc_function)); - f_names = (char **) bc_malloc (f_count*sizeof (char *)); - - /* Copy old ones. */ - for (indx1 = 0; indx1 < old_count; indx1++) - { - functions[indx1] = old_f[indx1]; - f_names[indx1] = old_names[indx1]; - } - - /* Initialize the new ones. */ - for (; indx1 < f_count; indx1++) - { - f = &functions[indx1]; - f->f_defined = FALSE; - for (indx2 = 0; indx2 < BC_MAX_SEGS; indx2++) - f->f_body [indx2] = NULL; - f->f_code_size = 0; - f->f_label = NULL; - f->f_autos = NULL; - f->f_params = NULL; - } - - /* Free the old elements. */ - if (old_count != 0) - { - free (old_f); - free (old_names); - } -} - -void -more_variables () -{ - int indx; - int old_count; - bc_var **old_var; - char **old_names; - - /* Save the old values. */ - old_count = v_count; - old_var = variables; - old_names = v_names; - - /* Increment by a fixed amount and allocate. */ - v_count += STORE_INCR; - variables = (bc_var **) bc_malloc (v_count*sizeof(bc_var *)); - v_names = (char **) bc_malloc (v_count*sizeof(char *)); - - /* Copy the old variables. */ - for (indx = 3; indx < old_count; indx++) - variables[indx] = old_var[indx]; - - /* Initialize the new elements. */ - for (; indx < v_count; indx++) - variables[indx] = NULL; - - /* Free the old elements. */ - if (old_count != 0) - { - free (old_var); - free (old_names); - } -} - -void -more_arrays () -{ - int indx; - int old_count; - bc_var_array **old_ary; - char **old_names; - - /* Save the old values. */ - old_count = a_count; - old_ary = arrays; - old_names = a_names; - - /* Increment by a fixed amount and allocate. */ - a_count += STORE_INCR; - arrays = (bc_var_array **) bc_malloc (a_count*sizeof(bc_var_array *)); - a_names = (char **) bc_malloc (a_count*sizeof(char *)); - - /* Copy the old arrays. */ - for (indx = 1; indx < old_count; indx++) - arrays[indx] = old_ary[indx]; - - - /* Initialize the new elements. */ - for (; indx < v_count; indx++) - arrays[indx] = NULL; - - /* Free the old elements. */ - if (old_count != 0) - { - free (old_ary); - free (old_names); - } -} - - -/* clear_func clears out function FUNC and makes it ready to redefine. */ - -void -clear_func (func) - char func; -{ - bc_function *f; - int indx; - bc_label_group *lg; - - /* Set the pointer to the function. */ - f = &functions[func]; - f->f_defined = FALSE; - - /* Clear the code segments. */ - for (indx = 0; indx < BC_MAX_SEGS; indx++) - { - if (f->f_body[indx] != NULL) - { - free (f->f_body[indx]); - f->f_body[indx] = NULL; - } - } - - f->f_code_size = 0; - if (f->f_autos != NULL) - { - free_args (f->f_autos); - f->f_autos = NULL; - } - if (f->f_params != NULL) - { - free_args (f->f_params); - f->f_params = NULL; - } - while (f->f_label != NULL) - { - lg = f->f_label->l_next; - free (f->f_label); - f->f_label = lg; - } -} - - -/* Pop the function execution stack and return the top. */ - -int -fpop() -{ - fstack_rec *temp; - int retval; - - if (fn_stack != NULL) - { - temp = fn_stack; - fn_stack = temp->s_next; - retval = temp->s_val; - free (temp); - } - return (retval); -} - - -/* Push VAL on to the function stack. */ - -void -fpush (val) - int val; -{ - fstack_rec *temp; - - temp = (fstack_rec *) bc_malloc (sizeof (fstack_rec)); - temp->s_next = fn_stack; - temp->s_val = val; - fn_stack = temp; -} - - -/* Pop and discard the top element of the regular execution stack. */ - -void -pop () -{ - estack_rec *temp; - - if (ex_stack != NULL) - { - temp = ex_stack; - ex_stack = temp->s_next; - free_num (&temp->s_num); - free (temp); - } -} - - -/* Push a copy of NUM on to the regular execution stack. */ - -void -push_copy (num) - bc_num num; -{ - estack_rec *temp; - - temp = (estack_rec *) bc_malloc (sizeof (estack_rec)); - temp->s_num = copy_num (num); - temp->s_next = ex_stack; - ex_stack = temp; -} - - -/* Push NUM on to the regular execution stack. Do NOT push a copy. */ - -void -push_num (num) - bc_num num; -{ - estack_rec *temp; - - temp = (estack_rec *) bc_malloc (sizeof (estack_rec)); - temp->s_num = num; - temp->s_next = ex_stack; - ex_stack = temp; -} - - -/* Make sure the ex_stack has at least DEPTH elements on it. - Return TRUE if it has at least DEPTH elements, otherwise - return FALSE. */ - -char -check_stack (depth) - int depth; -{ - estack_rec *temp; - - temp = ex_stack; - while ((temp != NULL) && (depth > 0)) - { - temp = temp->s_next; - depth--; - } - if (depth > 0) - { - rt_error ("Stack error."); - return FALSE; - } - return TRUE; -} - - -/* The following routines manipulate simple variables and - array variables. */ - -/* get_var returns a pointer to the variable VAR_NAME. If one does not - exist, one is created. */ - -bc_var * -get_var (var_name) - int var_name; -{ - bc_var *var_ptr; - - var_ptr = variables[var_name]; - if (var_ptr == NULL) - { - var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var)); - init_num (&var_ptr->v_value); - } - return var_ptr; -} - - -/* get_array_num returns the address of the bc_num in the array - structure. If more structure is requried to get to the index, - this routine does the work to create that structure. VAR_INDEX - is a zero based index into the arrays storage array. INDEX is - the index into the bc array. */ - -bc_num * -get_array_num (var_index, index) - int var_index; - long index; -{ - bc_var_array *ary_ptr; - bc_array *a_var; - bc_array_node *temp; - int log, ix, ix1; - int sub [NODE_DEPTH]; - - /* Get the array entry. */ - ary_ptr = arrays[var_index]; - if (ary_ptr == NULL) - { - ary_ptr = arrays[var_index] = - (bc_var_array *) bc_malloc (sizeof (bc_var_array)); - ary_ptr->a_value = NULL; - ary_ptr->a_next = NULL; - ary_ptr->a_param = FALSE; - } - - a_var = ary_ptr->a_value; - if (a_var == NULL) { - a_var = ary_ptr->a_value = (bc_array *) bc_malloc (sizeof (bc_array)); - a_var->a_tree = NULL; - a_var->a_depth = 0; - } - - /* Get the index variable. */ - sub[0] = index & NODE_MASK; - ix = index >> NODE_SHIFT; - log = 1; - while (ix > 0 || log < a_var->a_depth) - { - sub[log] = ix & NODE_MASK; - ix >>= NODE_SHIFT; - log++; - } - - /* Build any tree that is necessary. */ - while (log > a_var->a_depth) - { - temp = (bc_array_node *) bc_malloc (sizeof(bc_array_node)); - if (a_var->a_depth != 0) - { - temp->n_items.n_down[0] = a_var->a_tree; - for (ix=1; ix < NODE_SIZE; ix++) - temp->n_items.n_down[ix] = NULL; - } - else - { - for (ix=0; ix < NODE_SIZE; ix++) - temp->n_items.n_num[ix] = copy_num(_zero_); - } - a_var->a_tree = temp; - a_var->a_depth++; - } - - /* Find the indexed variable. */ - temp = a_var->a_tree; - while ( log-- > 1) - { - ix1 = sub[log]; - if (temp->n_items.n_down[ix1] == NULL) - { - temp->n_items.n_down[ix1] = - (bc_array_node *) bc_malloc (sizeof(bc_array_node)); - temp = temp->n_items.n_down[ix1]; - if (log > 1) - for (ix=0; ix < NODE_SIZE; ix++) - temp->n_items.n_down[ix] = NULL; - else - for (ix=0; ix < NODE_SIZE; ix++) - temp->n_items.n_num[ix] = copy_num(_zero_); - } - else - temp = temp->n_items.n_down[ix1]; - } - - /* Return the address of the indexed variable. */ - return &(temp->n_items.n_num[sub[0]]); -} - - -/* Store the top of the execution stack into VAR_NAME. - This includes the special variables ibase, obase, and scale. */ - -void -store_var (var_name) - int var_name; -{ - bc_var *var_ptr; - long temp; - char toobig; - - if (var_name > 2) - { - /* It is a simple variable. */ - var_ptr = get_var (var_name); - if (var_ptr != NULL) - { - free_num(&var_ptr->v_value); - var_ptr->v_value = copy_num (ex_stack->s_num); - } - } - else - { - /* It is a special variable... */ - toobig = FALSE; - if (is_neg (ex_stack->s_num)) - { - switch (var_name) - { - case 0: - rt_warn ("negative ibase, set to 2"); - temp = 2; - break; - case 1: - rt_warn ("negative obase, set to 2"); - temp = 2; - break; - case 2: - rt_warn ("negative scale, set to 0"); - temp = 0; - break; - } - } - else - { - temp = num2long (ex_stack->s_num); - if (!is_zero (ex_stack->s_num) && temp == 0) - toobig = TRUE; - } - switch (var_name) - { - case 0: - if (temp < 2 && !toobig) - { - i_base = 2; - rt_warn ("ibase too small, set to 2"); - } - else - if (temp > 16 || toobig) - { - i_base = 16; - rt_warn ("ibase too large, set to 16"); - } - else - i_base = (int) temp; - break; - - case 1: - if (temp < 2 && !toobig) - { - o_base = 2; - rt_warn ("obase too small, set to 2"); - } - else - if (temp > BC_BASE_MAX || toobig) - { - o_base = BC_BASE_MAX; - rt_warn ("obase too large, set to %d", BC_BASE_MAX); - } - else - o_base = (int) temp; - break; - - case 2: - /* WARNING: The following if statement may generate a compiler - warning if INT_MAX == LONG_MAX. This is NOT a problem. */ - if (temp > BC_SCALE_MAX || toobig ) - { - scale = BC_SCALE_MAX; - rt_warn ("scale too large, set to %d", BC_SCALE_MAX); - } - else - scale = (int) temp; - } - } -} - - -/* Store the top of the execution stack into array VAR_NAME. - VAR_NAME is the name of an array, and the next to the top - of stack for the index into the array. */ - -void -store_array (var_name) - int var_name; -{ - bc_num *num_ptr; - long index; - - if (!check_stack(2)) return; - index = num2long (ex_stack->s_next->s_num); - if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !is_zero(ex_stack->s_next->s_num))) - rt_error ("Array %s subscript out of bounds.", a_names[var_name]); - else - { - num_ptr = get_array_num (var_name, index); - if (num_ptr != NULL) - { - free_num (num_ptr); - *num_ptr = copy_num (ex_stack->s_num); - free_num (&ex_stack->s_next->s_num); - ex_stack->s_next->s_num = ex_stack->s_num; - init_num (&ex_stack->s_num); - pop(); - } - } -} - - -/* Load a copy of VAR_NAME on to the execution stack. This includes - the special variables ibase, obase and scale. */ - -void -load_var (var_name) - int var_name; -{ - bc_var *var_ptr; - - switch (var_name) - { - - case 0: - /* Special variable ibase. */ - push_copy (_zero_); - int2num (&ex_stack->s_num, i_base); - break; - - case 1: - /* Special variable obase. */ - push_copy (_zero_); - int2num (&ex_stack->s_num, o_base); - break; - - case 2: - /* Special variable scale. */ - push_copy (_zero_); - int2num (&ex_stack->s_num, scale); - break; - - default: - /* It is a simple variable. */ - var_ptr = variables[var_name]; - if (var_ptr != NULL) - push_copy (var_ptr->v_value); - else - push_copy (_zero_); - } -} - - -/* Load a copy of VAR_NAME on to the execution stack. This includes - the special variables ibase, obase and scale. */ - -void -load_array (var_name) - int var_name; -{ - bc_num *num_ptr; - long index; - - if (!check_stack(1)) return; - index = num2long (ex_stack->s_num); - if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !is_zero(ex_stack->s_num))) - rt_error ("Array %s subscript out of bounds.", a_names[var_name]); - else - { - num_ptr = get_array_num (var_name, index); - if (num_ptr != NULL) - { - pop(); - push_copy (*num_ptr); - } - } -} - - -/* Decrement VAR_NAME by one. This includes the special variables - ibase, obase, and scale. */ - -void -decr_var (var_name) - int var_name; -{ - bc_var *var_ptr; - - switch (var_name) - { - - case 0: /* ibase */ - if (i_base > 2) - i_base--; - else - rt_warn ("ibase too small in --"); - break; - - case 1: /* obase */ - if (o_base > 2) - o_base--; - else - rt_warn ("obase too small in --"); - break; - - case 2: /* scale */ - if (scale > 0) - scale--; - else - rt_warn ("scale can not be negative in -- "); - break; - - default: /* It is a simple variable. */ - var_ptr = get_var (var_name); - if (var_ptr != NULL) - bc_sub (var_ptr->v_value,_one_,&var_ptr->v_value); - } -} - - -/* Decrement VAR_NAME by one. VAR_NAME is an array, and the top of - the execution stack is the index and it is popped off the stack. */ - -void -decr_array (var_name) - char var_name; -{ - bc_num *num_ptr; - long index; - - /* It is an array variable. */ - if (!check_stack (1)) return; - index = num2long (ex_stack->s_num); - if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !is_zero (ex_stack->s_num))) - rt_error ("Array %s subscript out of bounds.", a_names[var_name]); - else - { - num_ptr = get_array_num (var_name, index); - if (num_ptr != NULL) - { - pop (); - bc_sub (*num_ptr, _one_, num_ptr); - } - } -} - - -/* Increment VAR_NAME by one. This includes the special variables - ibase, obase, and scale. */ - -void -incr_var (var_name) - int var_name; -{ - bc_var *var_ptr; - - switch (var_name) - { - - case 0: /* ibase */ - if (i_base < 16) - i_base++; - else - rt_warn ("ibase too big in ++"); - break; - - case 1: /* obase */ - if (o_base < BC_BASE_MAX) - o_base++; - else - rt_warn ("obase too big in ++"); - break; - - case 2: - if (scale < BC_SCALE_MAX) - scale++; - else - rt_warn ("Scale too big in ++"); - break; - - default: /* It is a simple variable. */ - var_ptr = get_var (var_name); - if (var_ptr != NULL) - bc_add (var_ptr->v_value, _one_, &var_ptr->v_value); - - } -} - - -/* Increment VAR_NAME by one. VAR_NAME is an array and top of - execution stack is the index and is popped off the stack. */ - -void -incr_array (var_name) - int var_name; -{ - bc_num *num_ptr; - long index; - - if (!check_stack (1)) return; - index = num2long (ex_stack->s_num); - if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !is_zero (ex_stack->s_num))) - rt_error ("Array %s subscript out of bounds.", a_names[var_name]); - else - { - num_ptr = get_array_num (var_name, index); - if (num_ptr != NULL) - { - pop (); - bc_add (*num_ptr, _one_, num_ptr); - } - } -} - - -/* Routines for processing autos variables and parameters. */ - -/* NAME is an auto variable that needs to be pushed on its stack. */ - -void -auto_var (name) - int name; -{ - bc_var *v_temp; - bc_var_array *a_temp; - int ix; - - if (name > 0) - { - /* A simple variable. */ - ix = name; - v_temp = (bc_var *) bc_malloc (sizeof (bc_var)); - v_temp->v_next = variables[ix]; - init_num (&v_temp->v_value); - variables[ix] = v_temp; - } - else - { - /* An array variable. */ - ix = -name; - a_temp = (bc_var_array *) bc_malloc (sizeof (bc_var_array)); - a_temp->a_next = arrays[ix]; - a_temp->a_value = NULL; - a_temp->a_param = FALSE; - arrays[ix] = a_temp; - } -} - - -/* Free_a_tree frees everything associated with an array variable tree. - This is used when popping an array variable off its auto stack. */ - -void -free_a_tree ( root, depth ) - bc_array_node *root; - int depth; -{ - int ix; - - if (root != NULL) - { - if (depth > 1) - for (ix = 0; ix < NODE_SIZE; ix++) - free_a_tree (root->n_items.n_down[ix], depth-1); - else - for (ix = 0; ix < NODE_SIZE; ix++) - free_num ( &(root->n_items.n_num[ix])); - free (root); - } -} - - -/* LIST is an NULL terminated list of varible names that need to be - popped off their auto stacks. */ - -void -pop_vars (list) - arg_list *list; -{ - bc_var *v_temp; - bc_var_array *a_temp; - int ix; - - while (list != NULL) - { - ix = list->av_name; - if (ix > 0) - { - /* A simple variable. */ - v_temp = variables[ix]; - if (v_temp != NULL) - { - variables[ix] = v_temp->v_next; - free_num (&v_temp->v_value); - free (v_temp); - } - } - else - { - /* An array variable. */ - ix = -ix; - a_temp = arrays[ix]; - if (a_temp != NULL) - { - arrays[ix] = a_temp->a_next; - if (!a_temp->a_param && a_temp->a_value != NULL) - { - free_a_tree (a_temp->a_value->a_tree, - a_temp->a_value->a_depth); - free (a_temp->a_value); - } - free (a_temp); - } - } - list = list->next; - } -} - - -/* A call is being made to FUNC. The call types are at PC. Process - the parameters by doing an auto on the parameter variable and then - store the value at the new variable or put a pointer the the array - variable. */ - -void -process_params (pc, func) - program_counter *pc; - int func; -{ - char ch; - arg_list *params; - int ix, ix1; - bc_var *v_temp; - bc_var_array *a_src, *a_dest; - bc_num *n_temp; - - /* Get the parameter names from the function. */ - params = functions[func].f_params; - - while ((ch = byte(pc)) != ':') - { - if (params != NULL) - { - if ((ch == '0') && params->av_name > 0) - { - /* A simple variable. */ - ix = params->av_name; - v_temp = (bc_var *) bc_malloc (sizeof(bc_var)); - v_temp->v_next = variables[ix]; - v_temp->v_value = ex_stack->s_num; - init_num (&ex_stack->s_num); - variables[ix] = v_temp; - } - else - if ((ch == '1') && (params->av_name < 0)) - { - /* The variables is an array variable. */ - - /* Compute source index and make sure some structure exists. */ - ix = (int) num2long (ex_stack->s_num); - n_temp = get_array_num (ix, 0); - - /* Push a new array and Compute Destination index */ - auto_var (params->av_name); - ix1 = -params->av_name; - - /* Set up the correct pointers in the structure. */ - if (ix == ix1) - a_src = arrays[ix]->a_next; - else - a_src = arrays[ix]; - a_dest = arrays[ix1]; - a_dest->a_param = TRUE; - a_dest->a_value = a_src->a_value; - } - else - { - if (params->av_name < 0) - rt_error ("Parameter type mismatch parameter %s.", - a_names[-params->av_name]); - else - rt_error ("Parameter type mismatch, parameter %s.", - v_names[params->av_name]); - params++; - } - pop (); - } - else - { - rt_error ("Parameter number mismatch"); - return; - } - params = params->next; - } - if (params != NULL) - rt_error ("Parameter number mismatch"); -} diff --git a/gnu/usr.bin/bc/util.c b/gnu/usr.bin/bc/util.c deleted file mode 100644 index 467126a85e4..00000000000 --- a/gnu/usr.bin/bc/util.c +++ /dev/null @@ -1,820 +0,0 @@ -/* $NetBSD: util.c,v 1.3 1994/12/02 00:43:44 phil Exp $ */ - -/* util.c: Utility routines for bc. */ - -/* 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" -#ifndef VARARGS -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include "global.h" -#include "proto.h" - - -/* strcopyof mallocs new memory and copies a string to to the new - memory. */ - -char * -strcopyof (str) - char *str; -{ - char *temp; - - temp = (char *) bc_malloc (strlen (str)+1); - return (strcpy (temp,str)); -} - - -/* nextarg adds another value to the list of arguments. */ - -arg_list * -nextarg (args, val) - arg_list *args; - int val; -{ arg_list *temp; - - temp = (arg_list *) bc_malloc (sizeof (arg_list)); - temp->av_name = val; - temp->next = args; - - return (temp); -} - - -/* For generate, we must produce a string in the form - "val,val,...,val". We also need a couple of static variables - for retaining old generated strings. It also uses a recursive - function that builds the string. */ - -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. - */ - -_PROTOTYPE (static char *make_arg_str, (arg_list *args, int len)); - -static char * -make_arg_str (args, len) - arg_list *args; - int len; -{ - char *temp; - char sval[20]; - - /* Recursive call. */ - if (args != NULL) - temp = make_arg_str (args->next, len+11); - else - { - temp = (char *) bc_malloc (len); - *temp = 0; - return temp; - } - - /* Add the current number to the end of the string. */ - if (len != 1) - sprintf (sval, "%d,", args->av_name); - else - sprintf (sval, "%d", args->av_name); - temp = strcat (temp, sval); - return (temp); -} - -char * -arg_str (args) - arg_list *args; -{ - if (arglist2 != NULL) - free (arglist2); - arglist2 = arglist1; - 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. */ - -void -free_args (args) - arg_list *args; -{ - arg_list *temp; - - temp = args; - while (temp != NULL) - { - args = args->next; - free (temp); - temp = args; - } -} - - -/* Check for valid parameter (PARAMS) and auto (AUTOS) lists. - There must be no duplicates any where. Also, this is where - warnings are generated for array parameters. */ - -void -check_params ( params, autos ) - arg_list *params, *autos; -{ - arg_list *tmp1, *tmp2; - - /* Check for duplicate parameters. */ - if (params != NULL) - { - tmp1 = params; - while (tmp1 != NULL) - { - tmp2 = tmp1->next; - while (tmp2 != NULL) - { - if (tmp2->av_name == tmp1->av_name) - yyerror ("duplicate parameter names"); - tmp2 = tmp2->next; - } - if (tmp1->av_name < 0) - warn ("Array parameter"); - tmp1 = tmp1->next; - } - } - - /* Check for duplicate autos. */ - if (autos != NULL) - { - tmp1 = autos; - while (tmp1 != NULL) - { - tmp2 = tmp1->next; - while (tmp2 != NULL) - { - if (tmp2->av_name == tmp1->av_name) - yyerror ("duplicate auto variable names"); - tmp2 = tmp2->next; - } - tmp1 = tmp1->next; - } - } - - /* Check for duplicate between parameters and autos. */ - if ((params != NULL) && (autos != NULL)) - { - tmp1 = params; - while (tmp1 != NULL) - { - tmp2 = autos; - while (tmp2 != NULL) - { - if (tmp2->av_name == tmp1->av_name) - yyerror ("variable in both parameter and auto lists"); - tmp2 = tmp2->next; - } - tmp1 = tmp1->next; - } - } -} - - -/* Initialize the code generator the parser. */ - -void -init_gen () -{ - /* Get things ready. */ - break_label = 0; - continue_label = 0; - next_label = 1; - out_count = 2; - if (compile_only) - printf ("@i"); - else - init_load (); - had_error = FALSE; - did_gen = FALSE; -} - - -/* generate code STR for the machine. */ - -void -generate (str) - char *str; -{ - did_gen = TRUE; - if (compile_only) - { - printf ("%s",str); - out_count += strlen(str); - if (out_count > 60) - { - printf ("\n"); - out_count = 0; - } - } - else - load_code (str); -} - - -/* Execute the current code as loaded. */ - -void -run_code() -{ - /* If no compile errors run the current code. */ - if (!had_error && did_gen) - { - if (compile_only) - { - printf ("@r\n"); - out_count = 0; - } - else - execute (); - } - - /* Reinitialize the code generation and machine. */ - if (did_gen) - init_gen(); - else - had_error = FALSE; -} - - -/* Output routines: Write a character CH to the standard output. - It keeps track of the number of characters output and may - break the output with a "\<cr>". */ - -void -out_char (ch) - char ch; -{ - if (ch == '\n') - { - out_col = 0; - putchar ('\n'); - } - else - { - out_col++; - if (out_col == 70) - { - putchar ('\\'); - putchar ('\n'); - out_col = 1; - } - putchar (ch); - } -} - - -/* The following are "Symbol Table" routines for the parser. */ - -/* find_id returns a pointer to node in TREE that has the correct - ID. If there is no node in TREE with ID, NULL is returned. */ - -id_rec * -find_id (tree, id) - id_rec *tree; - char *id; -{ - int cmp_result; - - /* Check for an empty tree. */ - if (tree == NULL) - return NULL; - - /* Recursively search the tree. */ - cmp_result = strcmp (id, tree->id); - if (cmp_result == 0) - return tree; /* This is the item. */ - else if (cmp_result < 0) - return find_id (tree->left, id); - else - return find_id (tree->right, id); -} - - -/* insert_id_rec inserts a NEW_ID rec into the tree whose ROOT is - provided. insert_id_rec returns TRUE if the tree height from - ROOT down is increased otherwise it returns FALSE. This is a - recursive balanced binary tree insertion algorithm. */ - -int insert_id_rec (root, new_id) - id_rec **root; - id_rec *new_id; -{ - id_rec *A, *B; - - /* If root is NULL, this where it is to be inserted. */ - if (*root == NULL) - { - *root = new_id; - new_id->left = NULL; - new_id->right = NULL; - new_id->balance = 0; - return (TRUE); - } - - /* We need to search for a leaf. */ - if (strcmp (new_id->id, (*root)->id) < 0) - { - /* Insert it on the left. */ - if (insert_id_rec (&((*root)->left), new_id)) - { - /* The height increased. */ - (*root)->balance --; - - switch ((*root)->balance) - { - case 0: /* no height increase. */ - return (FALSE); - case -1: /* height increase. */ - return (FALSE); - case -2: /* we need to do a rebalancing act. */ - A = *root; - B = (*root)->left; - if (B->balance <= 0) - { - /* Single Rotate. */ - A->left = B->right; - B->right = A; - *root = B; - A->balance = 0; - B->balance = 0; - } - else - { - /* Double Rotate. */ - *root = B->right; - B->right = (*root)->left; - A->left = (*root)->right; - (*root)->left = B; - (*root)->right = A; - switch ((*root)->balance) - { - case -1: - A->balance = 1; - B->balance = 0; - break; - case 0: - A->balance = 0; - B->balance = 0; - break; - case 1: - A->balance = 0; - B->balance = -1; - break; - } - (*root)->balance = 0; - } - } - } - } - else - { - /* Insert it on the right. */ - if (insert_id_rec (&((*root)->right), new_id)) - { - /* The height increased. */ - (*root)->balance ++; - switch ((*root)->balance) - { - case 0: /* no height increase. */ - return (FALSE); - case 1: /* height increase. */ - return (FALSE); - case 2: /* we need to do a rebalancing act. */ - A = *root; - B = (*root)->right; - if (B->balance >= 0) - { - /* Single Rotate. */ - A->right = B->left; - B->left = A; - *root = B; - A->balance = 0; - B->balance = 0; - } - else - { - /* Double Rotate. */ - *root = B->left; - B->left = (*root)->right; - A->right = (*root)->left; - (*root)->left = A; - (*root)->right = B; - switch ((*root)->balance) - { - case -1: - A->balance = 0; - B->balance = 1; - break; - case 0: - A->balance = 0; - B->balance = 0; - break; - case 1: - A->balance = -1; - B->balance = 0; - break; - } - (*root)->balance = 0; - } - } - } - } - - /* If we fall through to here, the tree did not grow in height. */ - return (FALSE); -} - - -/* Initialize variables for the symbol table tree. */ - -void -init_tree() -{ - name_tree = NULL; - next_array = 1; - next_func = 1; - next_var = 4; /* 0 => ibase, 1 => obase, 2 => scale, 3 => last. */ -} - - -/* Lookup routines for symbol table names. */ - -int -lookup (name, namekind) - char *name; - int namekind; -{ - id_rec *id; - - /* Warn about non-standard name. */ - if (strlen(name) != 1) - warn ("multiple letter name - %s", name); - - /* Look for the id. */ - id = find_id (name_tree, name); - if (id == NULL) - { - /* We need to make a new item. */ - id = (id_rec *) bc_malloc (sizeof (id_rec)); - id->id = strcopyof (name); - id->a_name = 0; - id->f_name = 0; - id->v_name = 0; - insert_id_rec (&name_tree, id); - } - - /* Return the correct value. */ - switch (namekind) - { - - case ARRAY: - /* ARRAY variable numbers are returned as negative numbers. */ - if (id->a_name != 0) - { - free (name); - return (-id->a_name); - } - id->a_name = next_array++; - a_names[id->a_name] = name; - if (id->a_name < MAX_STORE) - { - if (id->a_name >= a_count) - more_arrays (); - return (-id->a_name); - } - yyerror ("Too many array variables"); - 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++; - f_names[id->f_name] = name; - if (id->f_name < MAX_STORE) - { - if (id->f_name >= f_count) - more_functions (); - return (id->f_name); - } - yyerror ("Too many functions"); - exit (1); - - case SIMPLE: - if (id->v_name != 0) - { - free(name); - return (id->v_name); - } - id->v_name = next_var++; - v_names[id->v_name - 1] = name; - if (id->v_name <= MAX_STORE) - { - if (id->v_name >= v_count) - more_variables (); - return (id->v_name); - } - yyerror ("Too many variables"); - exit (1); - } -} - - -/* Print the welcome banner. */ - -void -welcome() -{ - printf ("This is free software with ABSOLUTELY NO WARRANTY.\n"); - printf ("For details type `warranty'. \n"); -} - - -/* Print out the warranty information. */ - -void -warranty(prefix) - char *prefix; -{ - printf ("\n%s%s\n\n", prefix, BC_VERSION); - printf ("%s%s%s%s%s%s%s%s%s%s%s", -" This program is free software; you can redistribute it and/or modify\n", -" it under the terms of the GNU General Public License as published by\n", -" the Free Software Foundation; either version 2 of the License , or\n", -" (at your option) any later version.\n\n", -" This program is distributed in the hope that it will be useful,\n", -" but WITHOUT ANY WARRANTY; without even the implied warranty of\n", -" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n", -" GNU General Public License for more details.\n\n", -" You should have received a copy of the GNU General Public License\n", -" along with this program. If not, write to the Free Software\n", -" Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n\n"); -} - -/* Print out the limits of this program. */ - -void -limits() -{ - printf ("BC_BASE_MAX = %d\n", BC_BASE_MAX); - printf ("BC_DIM_MAX = %ld\n", (long) BC_DIM_MAX); - printf ("BC_SCALE_MAX = %d\n", BC_SCALE_MAX); - printf ("BC_STRING_MAX = %d\n", BC_STRING_MAX); - printf ("MAX Exponent = %ld\n", (long) LONG_MAX); - printf ("MAX code = %ld\n", (long) BC_MAX_SEGS * (long) BC_SEG_SIZE); - printf ("multiply digits = %ld\n", (long) LONG_MAX / (long) 90); - printf ("Number of vars = %ld\n", (long) MAX_STORE); -#ifdef OLD_EQ_OP - printf ("Old assignment operatiors are valid. (=-, =+, ...)\n"); -#endif -} - -/* bc_malloc will check the return value so all other places do not - have to do it! SIZE is the number of types to allocate. */ - -char * -bc_malloc (size) - int size; -{ - char *ptr; - - ptr = (char *) malloc (size); - if (ptr == NULL) - out_of_memory (); - - return ptr; -} - - -/* The following routines are error routines for various problems. */ - -/* Malloc could not get enought memory. */ - -void -out_of_memory() -{ - fprintf (stderr, "Fatal error: Out of memory for malloc.\n"); - exit (1); -} - - - -/* The standard yyerror routine. Built with variable number of argumnets. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -yyerror (char *str, ...) -#else -void -yyerror (str) - char *str; -#endif -#else -void -yyerror (str, va_alist) - char *str; -#endif -{ - char *name; - va_list args; - -#ifndef VARARGS - va_start (args, str); -#else - va_start (args); -#endif - if (is_std_in) - name = "(standard_in)"; - else - name = g_argv[optind-1]; - fprintf (stderr,"%s %d: ",name,line_no); - vfprintf (stderr, str, args); - fprintf (stderr, "\n"); - had_error = TRUE; - va_end (args); -} - - -/* The routine to produce warnings about non-standard features - found during parsing. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -warn (char *mesg, ...) -#else -void -warn (mesg) - char *mesg; -#endif -#else -void -warn (mesg, va_alist) - char *mesg; -#endif -{ - char *name; - va_list args; - -#ifndef VARARGS - va_start (args, mesg); -#else - va_start (args); -#endif - if (std_only) - { - if (is_std_in) - name = "(standard_in)"; - else - name = g_argv[optind-1]; - fprintf (stderr,"%s %d: ",name,line_no); - vfprintf (stderr, mesg, args); - fprintf (stderr, "\n"); - had_error = TRUE; - } - else - if (warn_not_std) - { - if (is_std_in) - name = "(standard_in)"; - else - name = g_argv[optind-1]; - fprintf (stderr,"%s %d: (Warning) ",name,line_no); - vfprintf (stderr, mesg, args); - fprintf (stderr, "\n"); - } - va_end (args); -} - -/* Runtime error will print a message and stop the machine. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -rt_error (char *mesg, ...) -#else -void -rt_error (mesg) - char *mesg; -#endif -#else -void -rt_error (mesg, va_alist) - char *mesg; -#endif -{ - va_list args; - char error_mesg [255]; - -#ifndef VARARGS - va_start (args, mesg); -#else - va_start (args); -#endif - vsprintf (error_mesg, mesg, args); - va_end (args); - - fprintf (stderr, "Runtime error (func=%s, adr=%d): %s\n", - f_names[pc.pc_func], pc.pc_addr, error_mesg); - runtime_error = TRUE; -} - - -/* A runtime warning tells of some action taken by the processor that - may change the program execution but was not enough of a problem - to stop the execution. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -rt_warn (char *mesg, ...) -#else -void -rt_warn (mesg) - char *mesg; -#endif -#else -void -rt_warn (mesg, va_alist) - char *mesg; -#endif -{ - va_list args; - char error_mesg [255]; - -#ifndef VARARGS - va_start (args, mesg); -#else - va_start (args); -#endif - vsprintf (error_mesg, mesg, args); - va_end (args); - - fprintf (stderr, "Runtime warning (func=%s, adr=%d): %s\n", - f_names[pc.pc_func], pc.pc_addr, error_mesg); -} diff --git a/gnu/usr.bin/bc/version.h b/gnu/usr.bin/bc/version.h deleted file mode 100644 index 3e4b691e8ad..00000000000 --- a/gnu/usr.bin/bc/version.h +++ /dev/null @@ -1,5 +0,0 @@ -/* $NetBSD: version.h,v 1.3 1994/12/02 00:43:45 phil Exp $ */ - -#define BC_VERSION \ -"bc 1.03 (Nov 2, 1994)\nCopyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc." - diff --git a/gnu/usr.bin/bc/vfprintf.c b/gnu/usr.bin/bc/vfprintf.c deleted file mode 100644 index 4c009103292..00000000000 --- a/gnu/usr.bin/bc/vfprintf.c +++ /dev/null @@ -1,13 +0,0 @@ -#include <lib.h> -#include <stdarg.h> -#include <stdio.h> - -int vfprintf(file, format, argp) -FILE *file; -_CONST char *format; -va_list argp; -{ - _doprintf(file, format, argp); - if (testflag(file, PERPRINTF)) fflush(file); - return 0; -} |