|
Packit |
70b277 |
.\"
|
|
Packit |
70b277 |
.\" bc.1 - the *roff document processor source for the bc manual
|
|
Packit |
70b277 |
.\"
|
|
Packit |
70b277 |
.\" This file is part of GNU bc.
|
|
Packit |
70b277 |
.\" Copyright (C) 1991-1994, 1997, 2000, 2003, 2006, 2017 Free Software Foundation, Inc.
|
|
Packit |
70b277 |
.\"
|
|
Packit |
70b277 |
.\" This program is free software; you can redistribute it and/or modify
|
|
Packit |
70b277 |
.\" it under the terms of the GNU General Public License as published by
|
|
Packit |
70b277 |
.\" the Free Software Foundation; either version 2 of the License , or
|
|
Packit |
70b277 |
.\" (at your option) any later version.
|
|
Packit |
70b277 |
.\"
|
|
Packit |
70b277 |
.\" This program is distributed in the hope that it will be useful,
|
|
Packit |
70b277 |
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
70b277 |
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
70b277 |
.\" GNU General Public License for more details.
|
|
Packit |
70b277 |
.\"
|
|
Packit |
70b277 |
.\" You should have received a copy of the GNU General Public License
|
|
Packit |
70b277 |
.\" along with this program; see the file COPYING. If not, write to:
|
|
Packit |
70b277 |
.\" The Free Software Foundation, Inc.
|
|
Packit |
70b277 |
.\" 51 Franklin Street, Fifth Floor
|
|
Packit |
70b277 |
.\" Boston, MA 02110-1301 USA
|
|
Packit |
70b277 |
.\"
|
|
Packit |
70b277 |
.\" You may contact the author by:
|
|
Packit |
70b277 |
.\" e-mail: philnelson@acm.org
|
|
Packit |
70b277 |
.\" us-mail: Philip A. Nelson
|
|
Packit |
70b277 |
.\" Computer Science Department, 9062
|
|
Packit |
70b277 |
.\" Western Washington University
|
|
Packit |
70b277 |
.\" Bellingham, WA 98226-9062
|
|
Packit |
70b277 |
.\"
|
|
Packit |
70b277 |
.\"
|
|
Packit |
70b277 |
.TH bc 1 "2006-06-11" "GNU Project"
|
|
Packit |
70b277 |
.SH NAME
|
|
Packit |
70b277 |
bc - An arbitrary precision calculator language
|
|
Packit |
70b277 |
.SH SYNTAX
|
|
Packit |
70b277 |
\fBbc\fR [ \fB-hlwsqv\fR ] [long-options] [ \fI file ...\fR ]
|
|
Packit |
70b277 |
.SH DESCRIPTION
|
|
Packit |
70b277 |
\fBbc\fR is a language that supports arbitrary precision numbers
|
|
Packit |
70b277 |
with interactive execution of statements. There are some similarities
|
|
Packit |
70b277 |
in the syntax to the C programming language.
|
|
Packit |
70b277 |
A standard math library is available by command line option.
|
|
Packit |
70b277 |
If requested, the math library is defined before processing any files.
|
|
Packit |
70b277 |
\fBbc\fR starts by processing code from all the files listed
|
|
Packit |
70b277 |
on the command line in the order listed. After all files have been
|
|
Packit |
70b277 |
processed, \fBbc\fR reads from the standard input. All code is
|
|
Packit |
70b277 |
executed as it is read. (If a file contains a command to halt the
|
|
Packit |
70b277 |
processor, \fBbc\fR will never read from the standard input.)
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
This version of \fBbc\fR contains several extensions beyond
|
|
Packit |
70b277 |
traditional \fBbc\fR implementations and the POSIX draft standard.
|
|
Packit |
70b277 |
Command line options can cause these extensions to print a warning
|
|
Packit |
70b277 |
or to be rejected. This
|
|
Packit |
70b277 |
document describes the language accepted by this processor.
|
|
Packit |
70b277 |
Extensions will be identified as such.
|
|
Packit |
70b277 |
.SS OPTIONS
|
|
Packit |
70b277 |
.IP "-h, --help"
|
|
Packit |
70b277 |
Print the usage and exit.
|
|
Packit |
70b277 |
.IP "-i, --interactive"
|
|
Packit |
70b277 |
Force interactive mode.
|
|
Packit |
70b277 |
.IP "-l, --mathlib"
|
|
Packit |
70b277 |
Define the standard math library.
|
|
Packit |
70b277 |
.IP "-w, --warn"
|
|
Packit |
70b277 |
Give warnings for extensions to POSIX \fBbc\fR.
|
|
Packit |
70b277 |
.IP "-s, --standard"
|
|
Packit |
70b277 |
Process exactly the POSIX \fBbc\fR language.
|
|
Packit |
70b277 |
.IP "-q, --quiet"
|
|
Packit |
70b277 |
Do not print the normal GNU bc welcome.
|
|
Packit |
70b277 |
.IP "-v, --version"
|
|
Packit |
70b277 |
Print the version number and copyright and quit.
|
|
Packit |
70b277 |
.SS NUMBERS
|
|
Packit |
70b277 |
The most basic element in \fBbc\fR is the number. Numbers are
|
|
Packit |
70b277 |
arbitrary precision numbers. This precision is both in the integer
|
|
Packit |
70b277 |
part and the fractional part. All numbers are represented internally
|
|
Packit |
70b277 |
in decimal and all computation is done in decimal. (This version
|
|
Packit |
70b277 |
truncates results from divide and multiply operations.) There are two
|
|
Packit |
70b277 |
attributes of numbers, the length and the scale. The length is the
|
|
Packit |
70b277 |
total number of decimal digits used by \fBbc\fR to represent a number
|
|
Packit |
70b277 |
and the scale is the total number of decimal digits after the decimal
|
|
Packit |
70b277 |
point. For example:
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
.000001 has a length of 6 and scale of 6.
|
|
Packit |
70b277 |
1935.000 has a length of 7 and a scale of 3.
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
.SS VARIABLES
|
|
Packit |
70b277 |
Numbers are stored in two types of variables, simple variables and
|
|
Packit |
70b277 |
arrays. Both simple variables and array variables are named. Names
|
|
Packit |
70b277 |
begin with a letter followed by any number of letters, digits and
|
|
Packit |
70b277 |
underscores. All letters must be lower case. (Full alpha-numeric
|
|
Packit |
70b277 |
names are an extension. In POSIX \fBbc\fR all names are a single
|
|
Packit |
70b277 |
lower case letter.) The type of variable is clear by the context
|
|
Packit |
70b277 |
because all array variable names will be followed by brackets ([]).
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
There are four special variables, \fBscale, ibase, obase,\fR and
|
|
Packit |
70b277 |
\fBlast\fR. \fBscale\fR defines how some operations use digits after the
|
|
Packit |
70b277 |
decimal point. The default value of \fBscale\fR is 0. \fBibase\fR
|
|
Packit |
70b277 |
and \fBobase\fR define the conversion base for input and output
|
|
Packit |
70b277 |
numbers. The default for both input and output is base 10.
|
|
Packit |
70b277 |
\fBlast\fR (an extension) is a variable that has the value of the last
|
|
Packit |
70b277 |
printed number. These will be discussed in further detail where
|
|
Packit |
70b277 |
appropriate. All of these variables may have values assigned to them
|
|
Packit |
70b277 |
as well as used in expressions.
|
|
Packit |
70b277 |
.SS COMMENTS
|
|
Packit |
70b277 |
Comments in \fBbc\fR start with the characters \fB/*\fR and end with
|
|
Packit |
70b277 |
the characters \fB*/\fR. Comments may start anywhere and appear as a
|
|
Packit |
70b277 |
single space in the input. (This causes comments to delimit other
|
|
Packit |
70b277 |
input items. For example, a comment can not be found in the middle of
|
|
Packit |
70b277 |
a variable name.) Comments include any newlines (end of line) between
|
|
Packit |
70b277 |
the start and the end of the comment.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
To support the use of scripts for \fBbc\fR, a single line comment has been
|
|
Packit |
70b277 |
added as an extension. A single line comment starts at a \fB#\fR
|
|
Packit |
70b277 |
character and continues to the next end of the line. The end of line
|
|
Packit |
70b277 |
character is not part of the comment and is processed normally.
|
|
Packit |
70b277 |
.SS EXPRESSIONS
|
|
Packit |
70b277 |
The numbers are manipulated by expressions and statements. Since
|
|
Packit |
70b277 |
the language was designed to be interactive, statements and expressions
|
|
Packit |
70b277 |
are executed as soon as possible. There is no "main" program. Instead,
|
|
Packit |
70b277 |
code is executed as it is encountered. (Functions, discussed in
|
|
Packit |
70b277 |
detail later, are defined when encountered.)
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
A simple expression is just a constant. \fBbc\fR converts constants
|
|
Packit |
70b277 |
into internal decimal numbers using the current input base, specified
|
|
Packit |
70b277 |
by the variable \fBibase\fR. (There is an exception in functions.)
|
|
Packit |
70b277 |
The legal values of \fBibase\fR are 2 through 36. (Bases greater than
|
|
Packit |
70b277 |
16 are an extension.) Assigning a value outside this range to
|
|
Packit |
70b277 |
\fBibase\fR will result in a value of 2 or 36. Input numbers may
|
|
Packit |
70b277 |
contain the characters 0-9 and A-Z. (Note: They must be capitals.
|
|
Packit |
70b277 |
Lower case letters are variable names.) Single digit numbers always
|
|
Packit |
70b277 |
have the value of the digit regardless of the value of
|
|
Packit |
70b277 |
\fBibase\fR. (i.e. A = 10.) For multi-digit numbers, \fBbc\fR changes
|
|
Packit |
70b277 |
all input digits greater or equal to ibase to the value of
|
|
Packit |
70b277 |
\fBibase\fR-1. This makes the number \fBZZZ\fR always be the largest
|
|
Packit |
70b277 |
3 digit number of the input base.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Full expressions are similar to many other high level languages.
|
|
Packit |
70b277 |
Since there is only one kind of number, there are no rules for mixing
|
|
Packit |
70b277 |
types. Instead, there are rules on the scale of expressions. Every
|
|
Packit |
70b277 |
expression has a scale. This is derived from the scale of original
|
|
Packit |
70b277 |
numbers, the operation performed and in many cases, the value of the
|
|
Packit |
70b277 |
variable \fBscale\fR. Legal values of the variable \fBscale\fR are
|
|
Packit |
70b277 |
0 to the maximum number representable by a C integer.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
In the following descriptions of legal expressions, "expr" refers to a
|
|
Packit |
70b277 |
complete expression and "var" refers to a simple or an array variable.
|
|
Packit |
70b277 |
A simple variable is just a
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
\fIname\fR
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
and an array variable is specified as
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
\fIname\fR[\fIexpr\fR]
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
Unless specifically
|
|
Packit |
70b277 |
mentioned the scale of the result is the maximum scale of the
|
|
Packit |
70b277 |
expressions involved.
|
|
Packit |
70b277 |
.IP "- expr"
|
|
Packit |
70b277 |
The result is the negation of the expression.
|
|
Packit |
70b277 |
.IP "++ var"
|
|
Packit |
70b277 |
The variable is incremented by one and the new value is the result of
|
|
Packit |
70b277 |
the expression.
|
|
Packit |
70b277 |
.IP "-- var"
|
|
Packit |
70b277 |
The variable
|
|
Packit |
70b277 |
is decremented by one and the new value is the result of the
|
|
Packit |
70b277 |
expression.
|
|
Packit |
70b277 |
.IP "var ++"
|
|
Packit |
70b277 |
The result of the expression is the value of
|
|
Packit |
70b277 |
the variable and then the variable is incremented by one.
|
|
Packit |
70b277 |
.IP "var --"
|
|
Packit |
70b277 |
The result of the expression is the value of the variable and then
|
|
Packit |
70b277 |
the variable is decremented by one.
|
|
Packit |
70b277 |
.IP "expr + expr"
|
|
Packit |
70b277 |
The result of the expression is the sum of the two expressions.
|
|
Packit |
70b277 |
.IP "expr - expr"
|
|
Packit |
70b277 |
The result of the expression is the difference of the two expressions.
|
|
Packit |
70b277 |
.IP "expr * expr"
|
|
Packit |
70b277 |
The result of the expression is the product of the two expressions.
|
|
Packit |
70b277 |
.IP "expr / expr"
|
|
Packit |
70b277 |
The result of the expression is the quotient of the two expressions.
|
|
Packit |
70b277 |
The scale of the result is the value of the variable \fBscale\fR.
|
|
Packit |
70b277 |
.IP "expr % expr"
|
|
Packit |
70b277 |
The result of the expression is the "remainder" and it is computed in the
|
|
Packit |
70b277 |
following way. To compute a%b, first a/b is computed to \fBscale\fR
|
|
Packit |
70b277 |
digits. That result is used to compute a-(a/b)*b to the scale of the
|
|
Packit |
70b277 |
maximum of \fBscale\fR+scale(b) and scale(a). If \fBscale\fR is set
|
|
Packit |
70b277 |
to zero and both expressions are integers this expression is the
|
|
Packit |
70b277 |
integer remainder function.
|
|
Packit |
70b277 |
.IP "expr ^ expr"
|
|
Packit |
70b277 |
The result of the expression is the value of the first raised to the
|
|
Packit |
70b277 |
second. The second expression must be an integer. (If the second
|
|
Packit |
70b277 |
expression is not an integer, a warning is generated and the
|
|
Packit |
70b277 |
expression is truncated to get an integer value.) The scale of the
|
|
Packit |
70b277 |
result is \fBscale\fR if the exponent is negative. If the exponent
|
|
Packit |
70b277 |
is positive the scale of the result is the minimum of the scale of the
|
|
Packit |
70b277 |
first expression times the value of the exponent and the maximum of
|
|
Packit |
70b277 |
\fBscale\fR and the scale of the first expression. (e.g. scale(a^b)
|
|
Packit |
70b277 |
= min(scale(a)*b, max( \fBscale,\fR scale(a))).) It should be noted
|
|
Packit |
70b277 |
that expr^0 will always return the value of 1.
|
|
Packit |
70b277 |
.IP "( expr )"
|
|
Packit |
70b277 |
This alters the standard precedence to force the evaluation of the
|
|
Packit |
70b277 |
expression.
|
|
Packit |
70b277 |
.IP "var = expr"
|
|
Packit |
70b277 |
The variable is assigned the value of the expression.
|
|
Packit |
70b277 |
.IP "var <op>= expr"
|
|
Packit |
70b277 |
This is equivalent to "var = var <op> expr" with the exception that
|
|
Packit |
70b277 |
the "var" part is evaluated only once. This can make a difference if
|
|
Packit |
70b277 |
"var" is an array.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Relational expressions are a special kind of expression
|
|
Packit |
70b277 |
that always evaluate to 0 or 1, 0 if the relation is false and 1 if
|
|
Packit |
70b277 |
the relation is true. These may appear in any legal expression.
|
|
Packit |
70b277 |
(POSIX bc requires that relational expressions are used only in if,
|
|
Packit |
70b277 |
while, and for statements and that only one relational test may be
|
|
Packit |
70b277 |
done in them.) The relational operators are
|
|
Packit |
70b277 |
.IP "expr1 < expr2"
|
|
Packit |
70b277 |
The result is 1 if expr1 is strictly less than expr2.
|
|
Packit |
70b277 |
.IP "expr1 <= expr2"
|
|
Packit |
70b277 |
The result is 1 if expr1 is less than or equal to expr2.
|
|
Packit |
70b277 |
.IP "expr1 > expr2"
|
|
Packit |
70b277 |
The result is 1 if expr1 is strictly greater than expr2.
|
|
Packit |
70b277 |
.IP "expr1 >= expr2"
|
|
Packit |
70b277 |
The result is 1 if expr1 is greater than or equal to expr2.
|
|
Packit |
70b277 |
.IP "expr1 == expr2"
|
|
Packit |
70b277 |
The result is 1 if expr1 is equal to expr2.
|
|
Packit |
70b277 |
.IP "expr1 != expr2"
|
|
Packit |
70b277 |
The result is 1 if expr1 is not equal to expr2.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Boolean operations are also legal. (POSIX \fBbc\fR does NOT have
|
|
Packit |
70b277 |
boolean operations). The result of all boolean operations are 0 and 1
|
|
Packit |
70b277 |
(for false and true) as in relational expressions. The boolean
|
|
Packit |
70b277 |
operators are:
|
|
Packit |
70b277 |
.IP "!expr"
|
|
Packit |
70b277 |
The result is 1 if expr is 0.
|
|
Packit |
70b277 |
.IP "expr && expr"
|
|
Packit |
70b277 |
The result is 1 if both expressions are non-zero.
|
|
Packit |
70b277 |
.IP "expr || expr"
|
|
Packit |
70b277 |
The result is 1 if either expression is non-zero.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
The expression precedence is as follows: (lowest to highest)
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
|| operator, left associative
|
|
Packit |
70b277 |
&& operator, left associative
|
|
Packit |
70b277 |
! operator, nonassociative
|
|
Packit |
70b277 |
Relational operators, left associative
|
|
Packit |
70b277 |
Assignment operator, right associative
|
|
Packit |
70b277 |
+ and - operators, left associative
|
|
Packit |
70b277 |
*, / and % operators, left associative
|
|
Packit |
70b277 |
^ operator, right associative
|
|
Packit |
70b277 |
unary - operator, nonassociative
|
|
Packit |
70b277 |
++ and -- operators, nonassociative
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
This precedence was chosen so that POSIX compliant \fBbc\fR programs
|
|
Packit |
70b277 |
will run correctly. This will cause the use of the relational and
|
|
Packit |
70b277 |
logical operators to have some unusual behavior when used with
|
|
Packit |
70b277 |
assignment expressions. Consider the expression:
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
a = 3 < 5
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Most C programmers would assume this would assign the result of "3 <
|
|
Packit |
70b277 |
5" (the value 1) to the variable "a". What this does in \fBbc\fR is
|
|
Packit |
70b277 |
assign the value 3 to the variable "a" and then compare 3 to 5. It is
|
|
Packit |
70b277 |
best to use parenthesis when using relational and logical operators
|
|
Packit |
70b277 |
with the assignment operators.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
There are a few more special expressions that are provided in \fBbc\fR.
|
|
Packit |
70b277 |
These have to do with user defined functions and standard
|
|
Packit |
70b277 |
functions. They all appear as "\fIname\fB(\fIparameters\fB)\fR".
|
|
Packit |
70b277 |
See the section on functions for user defined functions. The standard
|
|
Packit |
70b277 |
functions are:
|
|
Packit |
70b277 |
.IP "length ( expression )"
|
|
Packit |
70b277 |
The value of the length function is the number of significant digits in the
|
|
Packit |
70b277 |
expression.
|
|
Packit |
70b277 |
.IP "read ( )"
|
|
Packit |
70b277 |
The read function (an extension) will read a number from the standard
|
|
Packit |
70b277 |
input, regardless of where the function occurs. Beware, this can
|
|
Packit |
70b277 |
cause problems with the mixing of data and program in the standard input.
|
|
Packit |
70b277 |
The best use for this function is in a previously written program that
|
|
Packit |
70b277 |
needs input from the user, but never allows program code to be input
|
|
Packit |
70b277 |
from the user. The value of the read function is the number read from
|
|
Packit |
70b277 |
the standard input using the current value of the variable
|
|
Packit |
70b277 |
\fBibase\fR for the conversion base.
|
|
Packit |
70b277 |
.IP "scale ( expression )"
|
|
Packit |
70b277 |
The value of the scale function is the number of digits after the decimal
|
|
Packit |
70b277 |
point in the expression.
|
|
Packit |
70b277 |
.IP "sqrt ( expression )"
|
|
Packit |
70b277 |
The value of the sqrt function is the square root of the expression. If
|
|
Packit |
70b277 |
the expression is negative, a run time error is generated.
|
|
Packit |
70b277 |
.SS STATEMENTS
|
|
Packit |
70b277 |
Statements (as in most algebraic languages) provide the sequencing of
|
|
Packit |
70b277 |
expression evaluation. In \fBbc\fR statements are executed "as soon
|
|
Packit |
70b277 |
as possible." Execution happens when a newline in encountered and
|
|
Packit |
70b277 |
there is one or more complete statements. Due to this immediate
|
|
Packit |
70b277 |
execution, newlines are very important in \fBbc\fR. In fact, both a
|
|
Packit |
70b277 |
semicolon and a newline are used as statement separators. An
|
|
Packit |
70b277 |
improperly placed newline will cause a syntax error. Because newlines
|
|
Packit |
70b277 |
are statement separators, it is possible to hide a newline by using
|
|
Packit |
70b277 |
the backslash character. The sequence "\e<nl>", where <nl> is the
|
|
Packit |
70b277 |
newline appears to \fBbc\fR as whitespace instead of a newline. A
|
|
Packit |
70b277 |
statement list is a series of statements separated by semicolons and
|
|
Packit |
70b277 |
newlines. The following is a list of \fBbc\fR statements and what
|
|
Packit |
70b277 |
they do: (Things enclosed in brackets ([]) are optional parts of the
|
|
Packit |
70b277 |
statement.)
|
|
Packit |
70b277 |
.IP "expression"
|
|
Packit |
70b277 |
This statement does one of two things. If the expression starts with
|
|
Packit |
70b277 |
"<variable> <assignment> ...", it is considered to be an assignment
|
|
Packit |
70b277 |
statement. If the expression is not an assignment statement, the
|
|
Packit |
70b277 |
expression is evaluated and printed to the output. After the number
|
|
Packit |
70b277 |
is printed, a newline is printed. For example, "a=1" is an assignment
|
|
Packit |
70b277 |
statement and "(a=1)" is an expression that has an embedded
|
|
Packit |
70b277 |
assignment. All numbers that are printed are printed in the base
|
|
Packit |
70b277 |
specified by the variable \fBobase\fR. The legal values for \fB
|
|
Packit |
70b277 |
obase\fR are 2 through BC_BASE_MAX. (See the section LIMITS.) For
|
|
Packit |
70b277 |
bases 2 through 16, the usual method of writing numbers is used. For
|
|
Packit |
70b277 |
bases greater than 16, \fBbc\fR uses a multi-character digit method
|
|
Packit |
70b277 |
of printing the numbers where each higher base digit is printed as a
|
|
Packit |
70b277 |
base 10 number. The multi-character digits are separated by spaces.
|
|
Packit |
70b277 |
Each digit contains the number of characters required to represent the
|
|
Packit |
70b277 |
base ten value of "obase-1". Since numbers are of arbitrary
|
|
Packit |
70b277 |
precision, some numbers may not be printable on a single output line.
|
|
Packit |
70b277 |
These long numbers will be split across lines using the "\e" as the
|
|
Packit |
70b277 |
last character on a line. The maximum number of characters printed
|
|
Packit |
70b277 |
per line is 70. Due to the interactive nature of \fBbc\fR, printing
|
|
Packit |
70b277 |
a number causes the side effect of assigning the printed value to the
|
|
Packit |
70b277 |
special variable \fBlast\fR. This allows the user to recover the
|
|
Packit |
70b277 |
last value printed without having to retype the expression that
|
|
Packit |
70b277 |
printed the number. Assigning to \fBlast\fR is legal and will
|
|
Packit |
70b277 |
overwrite the last printed value with the assigned value. The newly
|
|
Packit |
70b277 |
assigned value will remain until the next number is printed or another
|
|
Packit |
70b277 |
value is assigned to \fBlast\fR. (Some installations may allow the
|
|
Packit |
70b277 |
use of a single period (.) which is not part of a number as a short
|
|
Packit |
70b277 |
hand notation for for \fBlast\fR.)
|
|
Packit |
70b277 |
.IP "string"
|
|
Packit |
70b277 |
The string is printed to the output. Strings start with a double quote
|
|
Packit |
70b277 |
character and contain all characters until the next double quote character.
|
|
Packit |
70b277 |
All characters are take literally, including any newline. No newline
|
|
Packit |
70b277 |
character is printed after the string.
|
|
Packit |
70b277 |
.IP "\fBprint\fR list"
|
|
Packit |
70b277 |
The print statement (an extension) provides another method of output.
|
|
Packit |
70b277 |
The "list" is a list of strings and expressions separated by commas.
|
|
Packit |
70b277 |
Each string or expression is printed in the order of the list. No
|
|
Packit |
70b277 |
terminating newline is printed. Expressions are evaluated and their
|
|
Packit |
70b277 |
value is printed and assigned to the variable \fBlast\fR. Strings
|
|
Packit |
70b277 |
in the print statement are printed to the output and may contain
|
|
Packit |
70b277 |
special characters. Special characters start with the backslash
|
|
Packit |
70b277 |
character (\e). The special characters recognized by \fBbc\fR are
|
|
Packit |
70b277 |
"a" (alert or bell), "b" (backspace), "f" (form feed), "n" (newline),
|
|
Packit |
70b277 |
"r" (carriage return), "q" (double quote), "t" (tab), and "\e" (backslash).
|
|
Packit |
70b277 |
Any other character following the backslash will be ignored.
|
|
Packit |
70b277 |
.IP "{ statement_list }"
|
|
Packit |
70b277 |
This is the compound statement. It allows multiple statements to be
|
|
Packit |
70b277 |
grouped together for execution.
|
|
Packit |
70b277 |
.IP "\fBif\fR ( expression ) statement1 [\fBelse\fR statement2]"
|
|
Packit |
70b277 |
The if statement evaluates the expression and executes statement1 or
|
|
Packit |
70b277 |
statement2 depending on the value of the expression. If the expression
|
|
Packit |
70b277 |
is non-zero, statement1 is executed. If statement2 is present and
|
|
Packit |
70b277 |
the value of the expression is 0, then statement2 is executed. (The
|
|
Packit |
70b277 |
else clause is an extension.)
|
|
Packit |
70b277 |
.IP "\fBwhile\fR ( expression ) statement"
|
|
Packit |
70b277 |
The while statement will execute the statement while the expression
|
|
Packit |
70b277 |
is non-zero. It evaluates the expression before each execution of
|
|
Packit |
70b277 |
the statement. Termination of the loop is caused by a zero
|
|
Packit |
70b277 |
expression value or the execution of a break statement.
|
|
Packit |
70b277 |
.IP "\fBfor\fR ( [expression1] ; [expression2] ; [expression3] ) statement"
|
|
Packit |
70b277 |
The for statement controls repeated execution of the statement.
|
|
Packit |
70b277 |
Expression1 is evaluated before the loop. Expression2 is evaluated
|
|
Packit |
70b277 |
before each execution of the statement. If it is non-zero, the statement
|
|
Packit |
70b277 |
is evaluated. If it is zero, the loop is terminated. After each
|
|
Packit |
70b277 |
execution of the statement, expression3 is evaluated before the reevaluation
|
|
Packit |
70b277 |
of expression2. If expression1 or expression3 are missing, nothing is
|
|
Packit |
70b277 |
evaluated at the point they would be evaluated.
|
|
Packit |
70b277 |
If expression2 is missing, it is the same as substituting
|
|
Packit |
70b277 |
the value 1 for expression2. (The optional expressions are an
|
|
Packit |
70b277 |
extension. POSIX \fBbc\fR requires all three expressions.)
|
|
Packit |
70b277 |
The following is equivalent code for the for statement:
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
expression1;
|
|
Packit |
70b277 |
while (expression2) {
|
|
Packit |
70b277 |
statement;
|
|
Packit |
70b277 |
expression3;
|
|
Packit |
70b277 |
}
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
.IP "\fBbreak\fR"
|
|
Packit |
70b277 |
This statement causes a forced exit of the most recent enclosing while
|
|
Packit |
70b277 |
statement or for statement.
|
|
Packit |
70b277 |
.IP "\fBcontinue\fR"
|
|
Packit |
70b277 |
The continue statement (an extension) causes the most recent enclosing
|
|
Packit |
70b277 |
for statement to start the next iteration.
|
|
Packit |
70b277 |
.IP "\fBhalt\fR"
|
|
Packit |
70b277 |
The halt statement (an extension) is an executed statement that causes
|
|
Packit |
70b277 |
the \fBbc\fR processor to quit only when it is executed. For example,
|
|
Packit |
70b277 |
"if (0 == 1) halt" will not cause \fBbc\fR to terminate because the halt is
|
|
Packit |
70b277 |
not executed.
|
|
Packit |
70b277 |
.IP "\fBreturn\fR"
|
|
Packit |
70b277 |
Return the value 0 from a function. (See the section on functions.)
|
|
Packit |
70b277 |
.IP "\fBreturn\fR ( expression )"
|
|
Packit |
70b277 |
Return the value of the expression from a function. (See the section on
|
|
Packit |
70b277 |
functions.) As an extension, the parenthesis are not required.
|
|
Packit |
70b277 |
.SS PSEUDO STATEMENTS
|
|
Packit |
70b277 |
These statements are not statements in the traditional sense. They are
|
|
Packit |
70b277 |
not executed statements. Their function is performed at "compile" time.
|
|
Packit |
70b277 |
.IP "\fBlimits\fR"
|
|
Packit |
70b277 |
Print the local limits enforced by the local version of \fBbc\fR. This
|
|
Packit |
70b277 |
is an extension.
|
|
Packit |
70b277 |
.IP "\fBquit\fR"
|
|
Packit |
70b277 |
When the quit statement is read, the \fBbc\fR processor
|
|
Packit |
70b277 |
is terminated, regardless of where the quit statement is found. For
|
|
Packit |
70b277 |
example, "if (0 == 1) quit" will cause \fBbc\fR to terminate.
|
|
Packit |
70b277 |
.IP "\fBwarranty\fR"
|
|
Packit |
70b277 |
Print a longer warranty notice. This is an extension.
|
|
Packit |
70b277 |
.SS FUNCTIONS
|
|
Packit |
70b277 |
Functions provide a method of defining a computation that can be executed
|
|
Packit |
70b277 |
later. Functions in
|
|
Packit |
70b277 |
.B bc
|
|
Packit |
70b277 |
always compute a value and return it to the caller. Function definitions
|
|
Packit |
70b277 |
are "dynamic" in the sense that a function is undefined until a definition
|
|
Packit |
70b277 |
is encountered in the input. That definition is then used until another
|
|
Packit |
70b277 |
definition function for the same name is encountered. The new definition
|
|
Packit |
70b277 |
then replaces the older definition. A function is defined as follows:
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
\fBdefine \fIname \fB( \fIparameters \fB) { \fInewline
|
|
Packit |
70b277 |
\fI auto_list statement_list \fB}\fR
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
A function call is just an expression of the form
|
|
Packit |
70b277 |
"\fIname\fB(\fIparameters\fB)\fR".
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Parameters are numbers or arrays (an extension). In the function definition,
|
|
Packit |
70b277 |
zero or more parameters are defined by listing their names separated by
|
|
Packit |
70b277 |
commas. All parameters are call by value parameters.
|
|
Packit |
70b277 |
Arrays are specified in the parameter definition by
|
|
Packit |
70b277 |
the notation "\fIname\fB[]\fR". In the function call, actual parameters
|
|
Packit |
70b277 |
are full expressions for number parameters. The same notation is used
|
|
Packit |
70b277 |
for passing arrays as for defining array parameters. The named array is
|
|
Packit |
70b277 |
passed by value to the function. Since function definitions are dynamic,
|
|
Packit |
70b277 |
parameter numbers and types are checked when a function is called. Any
|
|
Packit |
70b277 |
mismatch in number or types of parameters will cause a runtime error.
|
|
Packit |
70b277 |
A runtime error will also occur for the call to an undefined function.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
The \fIauto_list\fR is an optional list of variables that are for
|
|
Packit |
70b277 |
"local" use. The syntax of the auto list (if present) is "\fBauto
|
|
Packit |
70b277 |
\fIname\fR, ... ;". (The semicolon is optional.) Each \fIname\fR is
|
|
Packit |
70b277 |
the name of an auto variable. Arrays may be specified by using the
|
|
Packit |
70b277 |
same notation as used in parameters. These variables have their
|
|
Packit |
70b277 |
values pushed onto a stack at the start of the function. The
|
|
Packit |
70b277 |
variables are then initialized to zero and used throughout the
|
|
Packit |
70b277 |
execution of the function. At function exit, these variables are
|
|
Packit |
70b277 |
popped so that the original value (at the time of the function call)
|
|
Packit |
70b277 |
of these variables are restored. The parameters are really auto
|
|
Packit |
70b277 |
variables that are initialized to a value provided in the function
|
|
Packit |
70b277 |
call. Auto variables are different than traditional local variables
|
|
Packit |
70b277 |
because if function A calls function B, B may access function
|
|
Packit |
70b277 |
A's auto variables by just using the same name, unless function B has
|
|
Packit |
70b277 |
called them auto variables. Due to the fact that auto variables and
|
|
Packit |
70b277 |
parameters are pushed onto a stack, \fBbc\fR supports recursive functions.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
The function body is a list of \fBbc\fR statements. Again, statements
|
|
Packit |
70b277 |
are separated by semicolons or newlines. Return statements cause the
|
|
Packit |
70b277 |
termination of a function and the return of a value. There are two
|
|
Packit |
70b277 |
versions of the return statement. The first form, "\fBreturn\fR", returns
|
|
Packit |
70b277 |
the value 0 to the calling expression. The second form,
|
|
Packit |
70b277 |
"\fBreturn ( \fIexpression \fB)\fR", computes the value of the expression
|
|
Packit |
70b277 |
and returns that value to the calling expression. There is an implied
|
|
Packit |
70b277 |
"\fBreturn (0)\fR" at the end of every function. This allows a function
|
|
Packit |
70b277 |
to terminate and return 0 without an explicit return statement.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Functions also change the usage of the variable \fBibase\fR. All
|
|
Packit |
70b277 |
constants in the function body will be converted using the value of
|
|
Packit |
70b277 |
\fBibase\fR at the time of the function call. Changes of \fBibase\fR
|
|
Packit |
70b277 |
will be ignored during the execution of the function except for the
|
|
Packit |
70b277 |
standard function \fBread\fR, which will always use the current value
|
|
Packit |
70b277 |
of \fBibase\fR for conversion of numbers.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Several extensions have been added to functions. First, the format of
|
|
Packit |
70b277 |
the definition has been slightly relaxed. The standard requires the
|
|
Packit |
70b277 |
opening brace be on the same line as the \fBdefine\fR keyword and all
|
|
Packit |
70b277 |
other parts must be on following lines. This version of \fBbc\fR will
|
|
Packit |
70b277 |
allow any number of newlines before and after the opening brace of the
|
|
Packit |
70b277 |
function. For example, the following definitions are legal.
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
\f(CW
|
|
Packit |
70b277 |
define d (n) { return (2*n); }
|
|
Packit |
70b277 |
define d (n)
|
|
Packit |
70b277 |
{ return (2*n); }
|
|
Packit |
70b277 |
\fR
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Functions may be defined as \fBvoid\fR. A void
|
|
Packit |
70b277 |
funtion returns no value and thus may not be used in any place that needs
|
|
Packit |
70b277 |
a value. A void function does not produce any output when called by itself
|
|
Packit |
70b277 |
on an input line. The key word \fBvoid\fR is placed between the key word
|
|
Packit |
70b277 |
\fBdefine\fR and the function name. For example, consider the following
|
|
Packit |
70b277 |
session.
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
\f(CW
|
|
Packit |
70b277 |
define py (y) { print "--->", y, "<---", "\en"; }
|
|
Packit |
70b277 |
define void px (x) { print "--->", x, "<---", "\en"; }
|
|
Packit |
70b277 |
py(1)
|
|
Packit |
70b277 |
--->1<---
|
|
Packit |
70b277 |
0
|
|
Packit |
70b277 |
px(1)
|
|
Packit |
70b277 |
--->1<---
|
|
Packit |
70b277 |
\fR
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
Since \fBpy\fR is not a void function, the call of \fBpy(1)\fR prints
|
|
Packit |
70b277 |
the desired output and then prints a second line that is the value of
|
|
Packit |
70b277 |
the function. Since the value of a function that is not given an
|
|
Packit |
70b277 |
explicit return statement is zero, the zero is printed. For \fBpx(1)\fR,
|
|
Packit |
70b277 |
no zero is printed because the function is a void function.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Also, call by variable for arrays was added. To declare
|
|
Packit |
70b277 |
a call by variable array, the declaration of the array parameter in the
|
|
Packit |
70b277 |
function definition looks like "\fI*name\fB[]\fR". The call to the
|
|
Packit |
70b277 |
function remains the same as call by value arrays.
|
|
Packit |
70b277 |
.SS MATH LIBRARY
|
|
Packit |
70b277 |
If \fBbc\fR is invoked with the \fB-l\fR option, a math library is preloaded
|
|
Packit |
70b277 |
and the default scale is set to 20. The math functions will calculate their
|
|
Packit |
70b277 |
results to the scale set at the time of their call.
|
|
Packit |
70b277 |
The math library defines the following functions:
|
|
Packit |
70b277 |
.IP "s (\fIx\fR)"
|
|
Packit |
70b277 |
The sine of x, x is in radians.
|
|
Packit |
70b277 |
.IP "c (\fIx\fR)"
|
|
Packit |
70b277 |
The cosine of x, x is in radians.
|
|
Packit |
70b277 |
.IP "a (\fIx\fR)"
|
|
Packit |
70b277 |
The arctangent of x, arctangent returns radians.
|
|
Packit |
70b277 |
.IP "l (\fIx\fR)"
|
|
Packit |
70b277 |
The natural logarithm of x.
|
|
Packit |
70b277 |
.IP "e (\fIx\fR)"
|
|
Packit |
70b277 |
The exponential function of raising e to the value x.
|
|
Packit |
70b277 |
.IP "j (\fIn,x\fR)"
|
|
Packit |
70b277 |
The Bessel function of integer order n of x.
|
|
Packit |
70b277 |
.SS EXAMPLES
|
|
Packit |
70b277 |
In /bin/sh, the following will assign the value of "pi" to the shell
|
|
Packit |
70b277 |
variable \fBpi\fR.
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
\f(CW
|
|
Packit |
70b277 |
pi=$(echo "scale=10; 4*a(1)" | bc -l)
|
|
Packit |
70b277 |
\fR
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
The following is the definition of the exponential function used in the
|
|
Packit |
70b277 |
math library. This function is written in POSIX \fBbc\fR.
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
\f(CW
|
|
Packit |
70b277 |
scale = 20
|
|
Packit |
70b277 |
|
|
Packit |
70b277 |
/* Uses the fact that e^x = (e^(x/2))^2
|
|
Packit |
70b277 |
When x is small enough, we use the series:
|
|
Packit |
70b277 |
e^x = 1 + x + x^2/2! + x^3/3! + ...
|
|
Packit |
70b277 |
*/
|
|
Packit |
70b277 |
|
|
Packit |
70b277 |
define e(x) {
|
|
Packit |
70b277 |
auto a, d, e, f, i, m, v, z
|
|
Packit |
70b277 |
|
|
Packit |
70b277 |
/* Check the sign of x. */
|
|
Packit |
70b277 |
if (x<0) {
|
|
Packit |
70b277 |
m = 1
|
|
Packit |
70b277 |
x = -x
|
|
Packit |
70b277 |
}
|
|
Packit |
70b277 |
|
|
Packit |
70b277 |
/* Precondition x. */
|
|
Packit |
70b277 |
z = scale;
|
|
Packit |
70b277 |
scale = 4 + z + .44*x;
|
|
Packit |
70b277 |
while (x > 1) {
|
|
Packit |
70b277 |
f += 1;
|
|
Packit |
70b277 |
x /= 2;
|
|
Packit |
70b277 |
}
|
|
Packit |
70b277 |
|
|
Packit |
70b277 |
/* Initialize the variables. */
|
|
Packit |
70b277 |
v = 1+x
|
|
Packit |
70b277 |
a = x
|
|
Packit |
70b277 |
d = 1
|
|
Packit |
70b277 |
|
|
Packit |
70b277 |
for (i=2; 1; i++) {
|
|
Packit |
70b277 |
e = (a *= x) / (d *= i)
|
|
Packit |
70b277 |
if (e == 0) {
|
|
Packit |
70b277 |
if (f>0) while (f--) v = v*v;
|
|
Packit |
70b277 |
scale = z
|
|
Packit |
70b277 |
if (m) return (1/v);
|
|
Packit |
70b277 |
return (v/1);
|
|
Packit |
70b277 |
}
|
|
Packit |
70b277 |
v += e
|
|
Packit |
70b277 |
}
|
|
Packit |
70b277 |
}
|
|
Packit |
70b277 |
\fR
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
The following is code that uses the extended features of \fBbc\fR to
|
|
Packit |
70b277 |
implement a simple program for calculating checkbook balances. This
|
|
Packit |
70b277 |
program is best kept in a file so that it can be used many times
|
|
Packit |
70b277 |
without having to retype it at every use.
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
\f(CW
|
|
Packit |
70b277 |
scale=2
|
|
Packit |
70b277 |
print "\enCheck book program!\en"
|
|
Packit |
70b277 |
print " Remember, deposits are negative transactions.\en"
|
|
Packit |
70b277 |
print " Exit by a 0 transaction.\en\en"
|
|
Packit |
70b277 |
|
|
Packit |
70b277 |
print "Initial balance? "; bal = read()
|
|
Packit |
70b277 |
bal /= 1
|
|
Packit |
70b277 |
print "\en"
|
|
Packit |
70b277 |
while (1) {
|
|
Packit |
70b277 |
"current balance = "; bal
|
|
Packit |
70b277 |
"transaction? "; trans = read()
|
|
Packit |
70b277 |
if (trans == 0) break;
|
|
Packit |
70b277 |
bal -= trans
|
|
Packit |
70b277 |
bal /= 1
|
|
Packit |
70b277 |
}
|
|
Packit |
70b277 |
quit
|
|
Packit |
70b277 |
\fR
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
The following is the definition of the recursive factorial function.
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
\f(CW
|
|
Packit |
70b277 |
define f (x) {
|
|
Packit |
70b277 |
if (x <= 1) return (1);
|
|
Packit |
70b277 |
return (f(x-1) * x);
|
|
Packit |
70b277 |
}
|
|
Packit |
70b277 |
\fR
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
.SS READLINE AND LIBEDIT OPTIONS
|
|
Packit |
70b277 |
GNU \fBbc\fR can be compiled (via a configure option) to use the GNU
|
|
Packit |
70b277 |
\fBreadline\fR input editor library or the BSD \fBlibedit\fR library.
|
|
Packit |
70b277 |
This allows the user to do editing of lines before sending them
|
|
Packit |
70b277 |
to \fBbc\fR. It also allows for a history of previous lines typed.
|
|
Packit |
70b277 |
When this option is selected, \fBbc\fR has one more special variable.
|
|
Packit |
70b277 |
This special variable, \fBhistory\fR is the number of lines of history
|
|
Packit |
70b277 |
retained. For \fBreadline\fR, a value of -1 means that an unlimited
|
|
Packit |
70b277 |
number of history lines are retained. Setting the value of
|
|
Packit |
70b277 |
\fBhistory\fR to a positive number restricts the number of history
|
|
Packit |
70b277 |
lines to the number given. The value of 0 disables the history
|
|
Packit |
70b277 |
feature. The default value is 100. For more information, read the
|
|
Packit |
70b277 |
user manuals for the GNU \fBreadline\fR, \fBhistory\fR and BSD \fBlibedit\fR
|
|
Packit |
70b277 |
libraries. One can not enable both \fBreadline\fR and \fBlibedit\fR
|
|
Packit |
70b277 |
at the same time.
|
|
Packit |
70b277 |
.SS DIFFERENCES
|
|
Packit |
70b277 |
This version of
|
|
Packit |
70b277 |
.B bc
|
|
Packit |
70b277 |
was implemented from the POSIX P1003.2/D11 draft and contains
|
|
Packit |
70b277 |
several differences and extensions relative to the draft and
|
|
Packit |
70b277 |
traditional implementations.
|
|
Packit |
70b277 |
It is not implemented in the traditional way using
|
|
Packit |
70b277 |
.I dc(1).
|
|
Packit |
70b277 |
This version is a single process which parses and runs a byte code
|
|
Packit |
70b277 |
translation of the program. There is an "undocumented" option (-c)
|
|
Packit |
70b277 |
that causes the program to output the byte code to
|
|
Packit |
70b277 |
the standard output instead of running it. It was mainly used for
|
|
Packit |
70b277 |
debugging the parser and preparing the math library.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
A major source of differences is
|
|
Packit |
70b277 |
extensions, where a feature is extended to add more functionality and
|
|
Packit |
70b277 |
additions, where new features are added.
|
|
Packit |
70b277 |
The following is the list of differences and extensions.
|
|
Packit |
70b277 |
.IP "LANG environment"
|
|
Packit |
70b277 |
This version does not conform to the POSIX standard in the processing
|
|
Packit |
70b277 |
of the LANG environment variable and all environment variables starting
|
|
Packit |
70b277 |
with LC_.
|
|
Packit |
70b277 |
.IP "names"
|
|
Packit |
70b277 |
Traditional and POSIX
|
|
Packit |
70b277 |
.B bc
|
|
Packit |
70b277 |
have single letter names for functions, variables and arrays. They have
|
|
Packit |
70b277 |
been extended to be multi-character names that start with a letter and
|
|
Packit |
70b277 |
may contain letters, numbers and the underscore character.
|
|
Packit |
70b277 |
.IP "Strings"
|
|
Packit |
70b277 |
Strings are not allowed to contain NUL characters. POSIX says all characters
|
|
Packit |
70b277 |
must be included in strings.
|
|
Packit |
70b277 |
.IP "last"
|
|
Packit |
70b277 |
POSIX \fBbc\fR does not have a \fBlast\fR variable. Some implementations
|
|
Packit |
70b277 |
of \fBbc\fR use the period (.) in a similar way.
|
|
Packit |
70b277 |
.IP "comparisons"
|
|
Packit |
70b277 |
POSIX \fBbc\fR allows comparisons only in the if statement, the while
|
|
Packit |
70b277 |
statement, and the second expression of the for statement. Also, only
|
|
Packit |
70b277 |
one relational operation is allowed in each of those statements.
|
|
Packit |
70b277 |
.IP "if statement, else clause"
|
|
Packit |
70b277 |
POSIX \fBbc\fR does not have an else clause.
|
|
Packit |
70b277 |
.IP "for statement"
|
|
Packit |
70b277 |
POSIX \fBbc\fR requires all expressions to be present in the for statement.
|
|
Packit |
70b277 |
.IP "&&, ||, !"
|
|
Packit |
70b277 |
POSIX \fBbc\fR does not have the logical operators.
|
|
Packit |
70b277 |
.IP "read function"
|
|
Packit |
70b277 |
POSIX \fBbc\fR does not have a read function.
|
|
Packit |
70b277 |
.IP "print statement"
|
|
Packit |
70b277 |
POSIX \fBbc\fR does not have a print statement .
|
|
Packit |
70b277 |
.IP "continue statement"
|
|
Packit |
70b277 |
POSIX \fBbc\fR does not have a continue statement.
|
|
Packit |
70b277 |
.IP "return statement"
|
|
Packit |
70b277 |
POSIX \fBbc\fR requires parentheses around the return expression.
|
|
Packit |
70b277 |
.IP "array parameters"
|
|
Packit |
70b277 |
POSIX \fBbc\fR does not (currently) support array parameters in full.
|
|
Packit |
70b277 |
The POSIX grammar allows for arrays in function definitions, but does
|
|
Packit |
70b277 |
not provide a method to specify an array as an actual parameter. (This
|
|
Packit |
70b277 |
is most likely an oversight in the grammar.) Traditional implementations
|
|
Packit |
70b277 |
of \fBbc\fR have only call by value array parameters.
|
|
Packit |
70b277 |
.IP "function format"
|
|
Packit |
70b277 |
POSIX \fBbc\fR requires the opening brace on the same line as the
|
|
Packit |
70b277 |
\fBdefine\fR key word and the \fBauto\fR statement on the next line.
|
|
Packit |
70b277 |
.IP "=+, =-, =*, =/, =%, =^"
|
|
Packit |
70b277 |
POSIX \fBbc\fR does not require these "old style" assignment operators to
|
|
Packit |
70b277 |
be defined. This version may allow these "old style" assignments. Use
|
|
Packit |
70b277 |
the limits statement to see if the installed version supports them. If
|
|
Packit |
70b277 |
it does support the "old style" assignment operators, the statement
|
|
Packit |
70b277 |
"a =- 1" will decrement \fBa\fR by 1 instead of setting \fBa\fR to the
|
|
Packit |
70b277 |
value -1.
|
|
Packit |
70b277 |
.IP "spaces in numbers"
|
|
Packit |
70b277 |
Other implementations of \fBbc\fR allow spaces in numbers. For example,
|
|
Packit |
70b277 |
"x=1 3" would assign the value 13 to the variable x. The same statement
|
|
Packit |
70b277 |
would cause a syntax error in this version of \fBbc\fR.
|
|
Packit |
70b277 |
.IP "errors and execution"
|
|
Packit |
70b277 |
This implementation varies from other implementations in terms of what
|
|
Packit |
70b277 |
code will be executed when syntax and other errors are found in the
|
|
Packit |
70b277 |
program. If a syntax error is found in a function definition, error
|
|
Packit |
70b277 |
recovery tries to find the beginning of a statement and continue to
|
|
Packit |
70b277 |
parse the function. Once a syntax error is found in the function, the
|
|
Packit |
70b277 |
function will not be callable and becomes undefined.
|
|
Packit |
70b277 |
Syntax errors in the interactive execution code will invalidate the
|
|
Packit |
70b277 |
current execution block. The execution block is terminated by an
|
|
Packit |
70b277 |
end of line that appears after a complete sequence of statements.
|
|
Packit |
70b277 |
For example,
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
a = 1
|
|
Packit |
70b277 |
b = 2
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
has two execution blocks and
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
.RS
|
|
Packit |
70b277 |
{ a = 1
|
|
Packit |
70b277 |
b = 2 }
|
|
Packit |
70b277 |
.RE
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
has one execution block. Any runtime error will terminate the execution
|
|
Packit |
70b277 |
of the current execution block. A runtime warning will not terminate the
|
|
Packit |
70b277 |
current execution block.
|
|
Packit |
70b277 |
.IP "Interrupts"
|
|
Packit |
70b277 |
During an interactive session, the SIGINT signal (usually generated by
|
|
Packit |
70b277 |
the control-C character from the terminal) will cause execution of the
|
|
Packit |
70b277 |
current execution block to be interrupted. It will display a "runtime"
|
|
Packit |
70b277 |
error indicating which function was interrupted. After all runtime
|
|
Packit |
70b277 |
structures have been cleaned up, a message will be printed to notify the
|
|
Packit |
70b277 |
user that \fBbc\fR is ready for more input. All previously defined functions
|
|
Packit |
70b277 |
remain defined and the value of all non-auto variables are the value at
|
|
Packit |
70b277 |
the point of interruption. All auto variables and function parameters
|
|
Packit |
70b277 |
are removed during the
|
|
Packit |
70b277 |
clean up process. During a non-interactive
|
|
Packit |
70b277 |
session, the SIGINT signal will terminate the entire run of \fBbc\fR.
|
|
Packit |
70b277 |
.SS LIMITS
|
|
Packit |
70b277 |
The following are the limits currently in place for this
|
|
Packit |
70b277 |
.B bc
|
|
Packit |
70b277 |
processor. Some of them may have been changed by an installation.
|
|
Packit |
70b277 |
Use the limits statement to see the actual values.
|
|
Packit |
70b277 |
.IP "BC_BASE_MAX"
|
|
Packit |
70b277 |
The maximum output base is currently set at 999. The maximum input base
|
|
Packit |
70b277 |
is 16.
|
|
Packit |
70b277 |
.IP "BC_DIM_MAX"
|
|
Packit |
70b277 |
This is currently an arbitrary limit of 65535 as distributed. Your
|
|
Packit |
70b277 |
installation may be different.
|
|
Packit |
70b277 |
.IP "BC_SCALE_MAX"
|
|
Packit |
70b277 |
The number of digits after the decimal point is limited to INT_MAX digits.
|
|
Packit |
70b277 |
Also, the number of digits before the decimal point is limited to INT_MAX
|
|
Packit |
70b277 |
digits.
|
|
Packit |
70b277 |
.IP "BC_STRING_MAX"
|
|
Packit |
70b277 |
The limit on the number of characters in a string is INT_MAX characters.
|
|
Packit |
70b277 |
.IP "exponent"
|
|
Packit |
70b277 |
The value of the exponent in the raise operation (^) is limited to LONG_MAX.
|
|
Packit |
70b277 |
.IP "variable names"
|
|
Packit |
70b277 |
The current limit on the number of unique names is 32767 for each of
|
|
Packit |
70b277 |
simple variables, arrays and functions.
|
|
Packit |
70b277 |
.SH ENVIRONMENT VARIABLES
|
|
Packit |
70b277 |
The following environment variables are processed by \fBbc\fR:
|
|
Packit |
70b277 |
.IP "POSIXLY_CORRECT"
|
|
Packit |
70b277 |
This is the same as the \fB-s\fR option.
|
|
Packit |
70b277 |
.IP "BC_ENV_ARGS"
|
|
Packit |
70b277 |
This is another mechanism to get arguments to \fBbc\fR. The
|
|
Packit |
70b277 |
format is the same as the command line arguments. These arguments
|
|
Packit |
70b277 |
are processed first, so any files listed in the environment arguments
|
|
Packit |
70b277 |
are processed before any command line argument files. This allows
|
|
Packit |
70b277 |
the user to set up "standard" options and files to be processed
|
|
Packit |
70b277 |
at every invocation of \fBbc\fR. The files in the environment
|
|
Packit |
70b277 |
variables would typically contain function definitions for functions
|
|
Packit |
70b277 |
the user wants defined every time \fBbc\fR is run.
|
|
Packit |
70b277 |
.IP "BC_LINE_LENGTH"
|
|
Packit |
70b277 |
This should be an integer specifying the number of characters in an
|
|
Packit |
70b277 |
output line for numbers. This includes the backslash and newline characters
|
|
Packit |
70b277 |
for long numbers. As an extension, the value of zero disables the
|
|
Packit |
70b277 |
multi-line feature. Any other value of this variable that is less than
|
|
Packit |
70b277 |
3 sets the line length to 70.
|
|
Packit |
70b277 |
.SH DIAGNOSTICS
|
|
Packit |
70b277 |
If any file on the command line can not be opened, \fBbc\fR will report
|
|
Packit |
70b277 |
that the file is unavailable and terminate. Also, there are compile
|
|
Packit |
70b277 |
and run time diagnostics that should be self-explanatory.
|
|
Packit |
70b277 |
.SH BUGS
|
|
Packit |
70b277 |
Error recovery is not very good yet.
|
|
Packit |
70b277 |
.PP
|
|
Packit |
70b277 |
Email bug reports to
|
|
Packit |
70b277 |
.BR bug-bc@gnu.org .
|
|
Packit |
70b277 |
Be sure to include the word ``bc'' somewhere in the ``Subject:'' field.
|
|
Packit |
70b277 |
.SH AUTHOR
|
|
Packit |
70b277 |
.nf
|
|
Packit |
70b277 |
Philip A. Nelson
|
|
Packit |
70b277 |
philnelson@acm.org
|
|
Packit |
70b277 |
.fi
|
|
Packit |
70b277 |
.SH ACKNOWLEDGEMENTS
|
|
Packit |
70b277 |
The author would like to thank Steve Sommars (Steve.Sommars@att.com) for
|
|
Packit |
70b277 |
his extensive help in testing the implementation. Many great suggestions
|
|
Packit |
70b277 |
were given. This is a much better product due to his involvement.
|