------------------------------- Page    i -------------------------------

          Bc - An Arbitrary Precision Desk Calculator Language




                                                 Lorinda Cherry

                                                 Robert Morris



                                                 Edited for UTS

------------------------------- Page   ii -------------------------------

                            TABLE OF CONTENTS


Abstract  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   1

1.    Introduction  . . . . . . . . . . . . . . . . . . . . . . . . .   1

2.    Simple Computations with Integers . . . . . . . . . . . . . . .   2

3.    Bases . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   3

4.    Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . .   4

5.    Functions . . . . . . . . . . . . . . . . . . . . . . . . . . .   5

6.    Subscripted Variables . . . . . . . . . . . . . . . . . . . . .   6

7.    Control Statements  . . . . . . . . . . . . . . . . . . . . . .   7

8.    Some Details  . . . . . . . . . . . . . . . . . . . . . . . . .   9

9.    Three Important Things  . . . . . . . . . . . . . . . . . . . .   9

10.   Acknowledgement . . . . . . . . . . . . . . . . . . . . . . . .  10

11.   References  . . . . . . . . . . . . . . . . . . . . . . . . . .  10

Appendix A.    Syntax . . . . . . . . . . . . . . . . . . . . . . . .  11

1.    Notation  . . . . . . . . . . . . . . . . . . . . . . . . . . .  11

2.    Tokens  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  11

2.1      Comments . . . . . . . . . . . . . . . . . . . . . . . . . .  11
2.2      Identifiers  . . . . . . . . . . . . . . . . . . . . . . . .  11
2.3      Keywords . . . . . . . . . . . . . . . . . . . . . . . . . .  11
2.4      Constants  . . . . . . . . . . . . . . . . . . . . . . . . .  12

3.    Expressions . . . . . . . . . . . . . . . . . . . . . . . . . .  12

3.1      Primitive expressions  . . . . . . . . . . . . . . . . . . .  12

3.1.1       Named expressions . . . . . . . . . . . . . . . . . . . .  12

3.1.1.1        identifiers  . . . . . . . . . . . . . . . . . . . . .  12
3.1.1.2        array-name[expression] . . . . . . . . . . . . . . . .  12
3.1.1.3        scale, ibase and obase . . . . . . . . . . . . . . . .  13

------------------------------- Page  iii -------------------------------

3.1.2       Function calls  . . . . . . . . . . . . . . . . . . . . .  13

3.1.2.1        function-name([expression[, expression] ...])  . . . .  13
3.1.2.2        sqrt(expression) . . . . . . . . . . . . . . . . . . .  13
3.1.2.3        length(expression) . . . . . . . . . . . . . . . . . .  13
3.1.2.4        scale(expression)  . . . . . . . . . . . . . . . . . .  13

3.1.3       Constants . . . . . . . . . . . . . . . . . . . . . . . .  13
3.1.4       Parentheses . . . . . . . . . . . . . . . . . . . . . . .  14

3.2      Unary operators  . . . . . . . . . . . . . . . . . . . . . .  14

3.2.1       -expression . . . . . . . . . . . . . . . . . . . . . . .  14
3.2.2       ++named-expression  . . . . . . . . . . . . . . . . . . .  14
3.2.3       --named-expression  . . . . . . . . . . . . . . . . . . .  14
3.2.4       named-expression++  . . . . . . . . . . . . . . . . . . .  14
3.2.5       named-expression--  . . . . . . . . . . . . . . . . . . .  14

3.3      Exponentiation operator  . . . . . . . . . . . . . . . . . .  14

3.3.1       expression ^ expression . . . . . . . . . . . . . . . . .  14

3.4      Multiplicative operators . . . . . . . . . . . . . . . . . .  15

3.4.1       expression * expression . . . . . . . . . . . . . . . . .  15
3.4.2       expression / expression . . . . . . . . . . . . . . . . .  15
3.4.3       expression % expression . . . . . . . . . . . . . . . . .  15

3.5      Additive operators . . . . . . . . . . . . . . . . . . . . .  15

3.5.1       expression + expression . . . . . . . . . . . . . . . . .  15
3.5.2       expression - expression . . . . . . . . . . . . . . . . .  15

3.6      assignment operators . . . . . . . . . . . . . . . . . . . .  16

3.6.1       named-expression = expression . . . . . . . . . . . . . .  16
3.6.2       named-expression =+ expression  . . . . . . . . . . . . .  16
3.6.3       named-expression =- expression  . . . . . . . . . . . . .  16
3.6.4       named-expression =* expression  . . . . . . . . . . . . .  16
3.6.5       named-expression =/ expression  . . . . . . . . . . . . .  16
3.6.6       named-expression =% expression  . . . . . . . . . . . . .  16
3.6.7       named-expression =^ expression  . . . . . . . . . . . . .  16

4.    Relations . . . . . . . . . . . . . . . . . . . . . . . . . . .  16

4.1      expression < expression  . . . . . . . . . . . . . . . . . .  16
4.2      expression > expression  . . . . . . . . . . . . . . . . . .  16
4.3      expression <= expression . . . . . . . . . . . . . . . . . .  17
4.4      expression >= expression . . . . . . . . . . . . . . . . . .  17
4.5      expression == expression . . . . . . . . . . . . . . . . . .  17

------------------------------- Page   iv -------------------------------

4.6      expression != expression . . . . . . . . . . . . . . . . . .  17

5.    Storage classes . . . . . . . . . . . . . . . . . . . . . . . .  17

6.    Statements  . . . . . . . . . . . . . . . . . . . . . . . . . .  17

6.1      Expression statements  . . . . . . . . . . . . . . . . . . .  17
6.2      Compound statements  . . . . . . . . . . . . . . . . . . . .  18
6.3      Quoted string statements . . . . . . . . . . . . . . . . . .  18
6.4      If statements  . . . . . . . . . . . . . . . . . . . . . . .  18
6.5      While statements . . . . . . . . . . . . . . . . . . . . . .  18
6.6      For statements . . . . . . . . . . . . . . . . . . . . . . .  18
6.7      Break statements . . . . . . . . . . . . . . . . . . . . . .  18
6.8      Auto statements  . . . . . . . . . . . . . . . . . . . . . .  19
6.9      Define statements  . . . . . . . . . . . . . . . . . . . . .  19
6.10     Return statements  . . . . . . . . . . . . . . . . . . . . .  19
6.11     Quit . . . . . . . . . . . . . . . . . . . . . . . . . . . .  19


                                                            Last Page  19

-------------------------------- Page  1 --------------------------------

ABSTRACT

Bc is a language and a compiler for doing arbitrary precision  arithmetic
on the UTS  Time-Sharing System.   The output of  the compiler is  inter-
preted and executed by a collection of routines which can input,  output,
and do arithmetic  on indefinitely  large integers and  on scaled  fixed-
point numbers.  These routines are themselves based on a dynamic  storage
allocator.  Overflow does not occur  until all available main storage  is
exhausted.  The  language has  a complete  control structure  as well  as
immediate-mode operation.  Functions can  be defined and saved for  later
execution.  A small collection  of library functions  is also  available,
including sin,  cos, arctan,  log, exponential, and  Bessel functions  of
integer order.  Some of the uses of this compiler are

  -  to do computation with large integers,

  -  to do computation accurate to many decimal places,

  -  conversion of numbers from one base to another base.




1.    INTRODUCTION

Bc is a language and a compiler for doing arbitrary precision  arithmetic
on the UTS  Time-Sharing System  [1].  The compiler  was written to  make
conveniently available a collection of routines (called DC [4]) which are
capable of doing arithmetic on integers of arbitrary size.  The  compiler
is by no means intended to  provide a complete programming language.   It
is a minimal language facility.   There is a scaling provision that  per-
mits the use of decimal point notation.  Provision is made for input  and
output in  bases  other than  decimal.   Numbers can  be  converted  from
decimal to  octal by  simply setting  the output  base to  equal 8.   The
actual limit on the number  of digits that can be handled depends on  the
amount of storage available on the machine.  Manipulation of numbers with
many hundreds of  digits is possible.   The syntax of  bc has been  deli-
berately selected to agree substantially with the C language [2].   Those
who are familiar with C will find few surprises in this language.

-------------------------------- Page  2 --------------------------------

2.    SIMPLE COMPUTATIONS WITH INTEGERS

The simplest kind of statement is an  arithmetic expression on a line  by
itself.  For instance, if you type in the line:

     142857 + 285714

the program responds immediately with the line

     428571

The operators -, *, /, %, and ^ can also be used; they indicate  subtrac-
tion, multiplication, division, remaindering, and exponentiation, respec-
tively.  Division of integers produces an integer result truncated toward
zero.  Division  by  zero produces  an  error comment.   Any term  in  an
expression may be prefixed by a minus sign to  indicate that it is to  be
negated (the 'unary' minus sign).  The expression

     7+-3

is interpreted to mean that -3 is to be added to 7.  More complex expres-
sions with several operators and with parentheses are interpreted just as
in Fortran, with ^ having the greatest binding power, then * and % and /,
and finally  +  and -.   Contents  of parentheses  are  evaluated  before
material outside  the parentheses.   Exponentiations are  performed  from
right to  left and  the  other operators  from left  to  right.  The  two
expressions

     a^b^c  and  a^(b^c)

are equivalent, as are the two expressions

     a*b*c  and  (a*b)*c

Bc shares with Fortran and C the undesirable convention that

     a/b*c  is equivalent to  (a/b)*c

Internal storage registers to hold numbers have single lower-case  letter
names.  The value of an  expression can be assigned to a register in  the
usual way.  The statement

     x = x + 3

has the effect of increasing  by three the value of  the contents of  the
register named x.  When, as in this case, the outermost operator is an =,
the assignment is performed but  the result is not  printed.  Only 26  of
these named storage registers are available.  There is a built-in  square
root function whose result is  truncated to an  integer (but see  scaling
below).  The lines

-------------------------------- Page  3 --------------------------------

     x = sqrt(191)
     x

produce the printed result

     13




3.    BASES

There are special internal quantities,  called 'ibase' and 'obase'.   The
contents of 'ibase', initially  set to 10,  determines the base used  for
interpreting numbers read in.  For example, the lines

     ibase = 8
     11

will produce the output line

     9

and you are all set up to do octal to decimal conversions.  Beware,  how-
ever of trying to change the input base back to decimal by typing

     ibase = 10

Because the number 10 is interpreted  as octal, this statement will  have
no effect.  For those  who deal in  hexadecimal notation, the  characters
A-F are permitted in numbers (no matter what  base is in effect) and  are
interpreted as digits having values 10-15 respectively.  The statement

     ibase = A

will change you back  to decimal input  base no matter  what the  current
input base is.  Negative and large positive input bases are permitted but
useless.  No  mechanism has  been  provided for  the input  of  arbitrary
numbers in  bases less  than  1 and  greater than  16.   The contents  of
'obase', initially set to 10,  are used as the  base for output  numbers.
The lines

     obase = 16
     1000

will produce the output line

-------------------------------- Page  4 --------------------------------

     3E8

which is to be interpreted as  a 3-digit hexadecimal number.  Very  large
output bases are permitted, and they are sometimes useful.  For  example,
large numbers can be output in groups  of five digits by setting  'obase'
to 100000.  Strange  (i.e. 1,  0, or negative)  output bases are  handled
appropriately.  Very large numbers are split across lines with 70 charac-
ters per line.   Lines which  are continued end  with \.  Decimal  output
conversion is practically instantaneous, but output of very large numbers
(i.e., more  than 100  digits)  with other  bases is  rather slow.   Non-
decimal output conversion of a one hundred digit number takes about three
seconds.  It is best to remember that 'ibase' and 'obase'  have no effect
whatever on the course of  internal computation or  on the evaluation  of
expressions, but only affect input and output conversion, respectively.




4.    SCALING

A third special internal quantity called 'scale' is used to determine the
scale of calculated quantities.  Numbers may have up to 99 decimal digits
after the decimal  point.  This  fractional part is  retained in  further
computations.  We refer to the  number of digits after the decimal  point
of a number as its scale.  When two scaled numbers are combined by  means
of one of the arithmetic operations, the result has a scale determined by
the following  rules.  For  addition and  subtraction, the  scale of  the
result is the larger  of the scales of  the two operands.  In this  case,
there is never any  truncation of the  result.  For multiplications,  the
scale of the result is  never less than the maximum of the two scales  of
the operands, never more than the sum of the scales of the operands  and,
subject to those two restrictions,  the scale of the result is set  equal
to the contents of the  internal quantity 'scale'.  The  scale of a  quo-
tient is the contents of  the internal quantity 'scale'.  The scale of  a
remainder is the sum of the scales of the quotient and the divisor.   The
result of an exponentiation is  scaled as if the implied  multiplications
were performed.  An exponent must be an  integer.  The scale of a  square
root is set to the maximum of the scale of  the argument and the contents
of 'scale'.  All of the internal  operations are actually carried out  in
terms of integers, with digits being discarded when necessary.  In  every
case where  digits are  discarded, truncation  and not  rounding is  per-
formed.  The contents of 'scale'  must be no greater than 99 and no  less
than 0.  It is initially set to 0.  In case  you need more than 99  frac-
tion digits, you may arrange  your own scaling.  The internal  quantities
'scale', 'ibase', and 'obase' can be used in expressions just like  other
variables.  The line

-------------------------------- Page  5 --------------------------------

     scale = scale + 1

increases the value of 'scale' by one, and the line

     scale

causes the current value of 'scale' to be printed.  The value of  'scale'
retains its  meaning as  a number  of decimal  digits to  be retained  in
internal computation even when 'ibase'  or 'obase' are  not equal to  10.
The internal computations (which are still conducted in decimal,  regard-
less of  the bases)  are performed  to the  specified number  of  decimal
digits, never hexadecimal or octal or any other kind of digits.




5.    FUNCTIONS

The name of a function is a single lower-case letter.  Function names are
permitted to collide  with simple  variable names.  Twenty-six  different
defined functions are permitted  in addition to  the twenty-six  variable
names.  The line

     define a(x){

begins the definition of a function with one argument.  This line must be
followed by one or more  statements, which make up the body of the  func-
tion, ending with a  right brace }.   Return of control  from a  function
occurs when a return statement  is executed or when the end of the  func-
tion is reached.  The return statement can take either of the two forms

     return
     return(x)

In the first case, the value of the function is 0, and in the second, the
value of the expression in  parentheses.  Variables used in the  function
can be declared as automatic by a statement of the form

     auto x,y,z

There can be only one 'auto' statement in a  function and it must be  the
first statement in the  definition.  These automatic variables are  allo-
cated space and initialized to zero on  entry to the function and  thrown
away on return.  The values of any variables with the  same names outside
the function are not disturbed.  Functions may be called recursively  and
the automatic variables at each level of call are protected.  The parame-
ters named in a function  definition are treated in the  same way as  the
automatic variables of that function with the single exception that  they

-------------------------------- Page  6 --------------------------------

are given a value  on entry to  the function.  An  example of a  function
definition is

     define a(x,y){
             auto z
             z = x*y
             return(z)
     }

The value of this function, when called, will  be the product of its  two
arguments.  A function is called  by the appearance of its name  followed
by a string of arguments enclosed in parentheses and separated by commas.
The result is  unpredictable if  the wrong number  of arguments is  used.
Functions with no arguments are defined and called using parentheses with
nothing between them:  b().  If  the function a  above has been  defined,
then the line

     a(7,3.14)

would cause the result 21.98 to be printed and the line

     x = a(a(3,4),5)

would cause the value of x to become 60.




6.    SUBSCRIPTED VARIABLES

A single lower-case  letter variable  name followed by  an expression  in
brackets is called a subscripted variable (an array element).  The  vari-
able name is  called the  array name and  the expression  in brackets  is
called the subscript.   Only one-dimensional  arrays are permitted.   The
names of arrays are permitted to collide  with the names of simple  vari-
ables and function  names.  Any  fractional part of  a subscript is  dis-
carded before use.  Subscripts must be greater than or equal to zero  and
less than or equal to 2047.  Subscripted variables may be  freely used in
expressions, in function calls, and in return statements.  An array  name
may be used as an argument to a function, or may be declared as automatic
in a function definition by the use of empty brackets:

     f(a[])
     define f(a[])
     auto a[]

When an array name is so used, the whole contents of the array are copied
for the use of the  function, and thrown away on exit from the  function.

-------------------------------- Page  7 --------------------------------

Array names which refer to whole arrays cannot be used in any other  con-
texts.




7.    CONTROL STATEMENTS

The 'if', the 'while', and the 'for' statements may be used to alter  the
flow within programs or to cause iteration.  The range of each of them is
a statement or a compound statement consisting of a collection of  state-
ments enclosed in braces.  They are written in the following way

     if(relation) statement
     while(relation) statement
     for(expression1; relation; expression2) statement

or

     if(relation) {statements}
     while(relation) {statements}
     for(expression1; relation; expression2) {statements}

A relation in one of the control statements is an expression of the form

     x>y

where two expressions are related by one of the six relational  operators
<, >, <=, >=, ==,  or !=.  The relation ==  stands for 'equal to' and  !=
stands for  'not equal  to'.   The meaning  of the  remaining  relational
operators is clear.   BEWARE of using  = instead of  == in a  relational.
Unfortunately, both of them are legal, so  you will not get a  diagnostic
message, but  = really  will  not do  a comparison.   The 'if'  statement
causes execution of its range if and only if the relation is true.   Then
control passes to the next statement in sequence.  The 'while'  statement
causes execution of its range repeatedly as long as the relation is true.
The relation  is tested before  each execution  of its range  and if  the
relation is false, control passes to the next statement beyond the  range
of the  while.  The  'for' statement begins  by executing  'expression1'.
Then the relation is tested and, if true, the statements in the range  of
the 'for' are executed.  Then 'expression2' is executed.  The relation is
tested, and so on.  The typical use of the 'for' statement is for a  con-
trolled iteration, as in the statement

     for(i=1; i<=10; i=i+1) i

which will print the integers  from 1 to 10.  Here  are some examples  of
the use of the control statements.

-------------------------------- Page  8 --------------------------------

     define f(n){
             auto i, x
             x=1
             for(i=1; i<=n; i=i+1) x=x*i
             return(x)
     }

The line

     f(a)

will print a factorial if a is a  positive integer.  Here is the  defini-
tion of a function which will compute values of the  binomial coefficient
(m and n are assumed to be positive integers).

     define b(n,m){
             auto x, j
             x=1
             for(j=1; j<=m; j=j+1) x=x*(n-j+1)/j
             return(x)
     }

The following function  computes values  of the  exponential function  by
summing the  appropriate series  without regard  for possible  truncation
errors:

scale = 20
define e(x){
        auto a, b, c, d, n
        a = 1
        b = 1
        c = 1
        d = 0
        n = 1
        while(1==1){
                a = a*x
                b = b*n
                c = c + a/b
                n = n + 1
                if(c==d) return(c)
                d = c
        }
}

-------------------------------- Page  9 --------------------------------

8.    SOME DETAILS

There are some language features that  every user should know about  even
if he will not  use them.  Normally statements  are typed one to a  line.
It is also permissible to type several statements on a line separated  by
semicolons.  If an assignment statement  is parenthesized, it then has  a
value and it can be used anywhere  that an expression can.  For  example,
the line

(x=y+17)

not only makes the  indicated assignment, but  also prints the  resulting
value.  Here is an example of a use of the  value of an assignment state-
ment even when it is not parenthesized.

x = a[i=i+1]

causes a value to  be assigned to x  and also increments  i before it  is
used as a subscript.  The following constructs work in bc  in exactly the
same manner as they do in the C language.  Consult the appendix or the  C
manuals [2] for their exact workings.

x=y=z   is the same as  x=(y=z)
x =+ y                  x = x+y
x =- y                  x = x-y
x =* y                  x = x*y
x =/ y                  x = x/y
x =% y                  x = x%y
x =^ y                  x = x^y
x++                     (x=x+1)-1
x--                     (x=x-1)+1
++x                     x = x+1
--x                     x = x-1

Even if you don't intend to use the constructs, if you type one  inadver-
tently, something correct but  unexpected may happen.  WARNING!  In  some
of these constructions, spaces are significant.  There is a real  differ-
ence between x=-y and x= -y.  The first replaces x  by x-y and the second
by -y.




9.    THREE IMPORTANT THINGS

 1.  To exit a bc program, type 'quit'.

 2.  There is a comment convention  identical to that of  C and of  PL/I.

-------------------------------- Page 10 --------------------------------

     Comments begin with '/*' and end with '*/'.

 3.  There is a library of math functions which may be obtained by typing
     at command level

          bc -l

     This command will load a set of library functions which, at the time
     of writing, consists of  sine (named 's'), cosine ('c'),  arctangent
     ('a'), natural logarithm ('l'), exponential  ('e') and Bessel  func-
     tions of integer order ('j(n,x)').  Doubtless more functions will be
     added in time.  The library sets the scale to 20.  You can reset  it
     to something else if you like.  If you type

          bc file ...

     Bc will read and execute  the named file  or files before  accepting
     commands from the keyboard.  In this way, you may load your favorite
     programs and function definitions.




10.   ACKNOWLEDGEMENT

The compiler is written using YACC [3]; its original version was  written
by S. C. Johnson.




11.   REFERENCES

 [1]  UTS Programmer's Manual, Volume 1,

 [2]  B. W.  Kernighan and  D. M.  Ritchie, The  C Programming  Language,
      Prentice-Hall, 1978.

 [3]  S. C. Johnson, YACC--Yet Another Compiler-Compiler.

 [4]  R. Morris and L. L. Cherry, DC - An Interactive Desk Calculator.

-------------------------------- Page 11 --------------------------------

APPENDIX A.    SYNTAX




1.    NOTATION

In the following pages syntactic categories are in italics; literals  are
in bold; material in brackets [] is optional.




2.    TOKENS

Tokens  consist  of  keywords,  identifiers,  constants,  operators,  and
separators.  Token separators may  be blanks, tabs or comments.   Newline
characters or semicolons separate statements.


2.1      COMMENTS

Comments are introduced by the characters /* and terminated by */.


2.2      IDENTIFIERS

There are three kinds of identifiers - ordinary identifiers, array  iden-
tifiers and  function identifiers.   All  three types  consist of  single
lower-case letters.  Array identifiers are  followed by square  brackets,
possibly enclosing  an  expression describing  a subscript.   Arrays  are
singly dimensioned and may contain up to 2048 elements.  Indexing  begins
at zero so an array may be indexed from 0  to 2047.  Subscripts are trun-
cated to  integers.  Function  identifiers are  followed by  parentheses,
possibly enclosing arguments.  The three types of identifiers do not con-
flict; a program can  have a variable  named x,  an array named  x and  a
function named x, all of which are separate and distinct.


2.3      KEYWORDS

The following are reserved keywords:

-------------------------------- Page 12 --------------------------------

        ibase   if
        obase   break
        scale   define
        sqrt    auto
        length  return
        while   quit
        for


2.4      CONSTANTS

Constants consist of arbitrarily  long numbers with  an optional  decimal
point.  The hexadecimal  digits A-F  are also recognized  as digits  with
values 10-15, respectively.




3.    EXPRESSIONS

The value of  an expression  is printed unless  the main  operator is  an
assignment.  Precedence is the  same as the  order of presentation  here,
with highest appearing first.  Left or right associativity, where  appli-
cable, is discussed with each operator.


3.1      PRIMITIVE EXPRESSIONS


3.1.1       NAMED EXPRESSIONS

Named expressions are  places where  values are  stored.  Simply  stated,
named expressions are legal on the left side of an assignment.  The value
of a named expression is the value stored in the place named.


3.1.1.1        IDENTIFIERS

Simple identifiers are named expressions.  They have an initial value  of
zero.


3.1.1.2        ARRAY-NAME[EXPRESSION]

Array elements  are named  expressions.  They  have an  initial value  of
zero.

-------------------------------- Page 13 --------------------------------

3.1.1.3        SCALE, IBASE AND OBASE

The internal registers scale, ibase and obase are all named  expressions.
scale is the number of  digits after the decimal point to be retained  in
arithmetic operations.  scale has  an initial value  of zero.  ibase  and
obase are the input and output number radix respectively.  Both ibase and
obase have initial values of 10.


3.1.2       FUNCTION CALLS


3.1.2.1        FUNCTION-NAME([EXPRESSION[, EXPRESSION] ...])

A function call consists of a function name followed by parentheses  con-
taining a  comma-separated list  of expressions, which  are the  function
arguments.  A whole array passed as an argument is specified by the array
name followed  by  empty square  brackets.   All function  arguments  are
passed by value.  As a result, changes made to the formal parameters have
no effect on the actual arguments.  If the function terminates by execut-
ing a return statement,  the value of  the function is  the value of  the
expression in the parentheses  of the return  statement or is zero if  no
expression is provided or if there is no return statement.


3.1.2.2        SQRT(EXPRESSION)

The result is the square root of the expression.  The result is truncated
in the least significant decimal  place.  The scale of the result is  the
scale of the expression or the value of scale, whichever is larger.


3.1.2.3        LENGTH(EXPRESSION)

The result  is the  total number  of significant  decimal digits  in  the
expression.  The scale of the result is zero.


3.1.2.4        SCALE(EXPRESSION)

The result is the scale  of the expression.  The scale  of the result  is
zero.


3.1.3       CONSTANTS

Constants are primitive expressions.

-------------------------------- Page 14 --------------------------------

3.1.4       PARENTHESES

An expression surrounded by parentheses  is a primitive expression.   The
parentheses are used to alter the normal precedence.


3.2      UNARY OPERATORS

The unary operators bind right to left.


3.2.1       -EXPRESSION

The result is the negative of the expression.


3.2.2       ++NAMED-EXPRESSION

The named expression is incremented by one.   The result is the value  of
the named expression after incrementing.


3.2.3       --NAMED-EXPRESSION

The named expression is decremented by one.   The result is the value  of
the named expression after decrementing.


3.2.4       NAMED-EXPRESSION++

The named expression is incremented by one.   The result is the value  of
the named expression before incrementing.


3.2.5       NAMED-EXPRESSION--

The named expression is decremented by one.   The result is the value  of
the named expression before decrementing.


3.3      EXPONENTIATION OPERATOR

The exponentiation operator binds right to left.


3.3.1       EXPRESSION ^ EXPRESSION

The result is  the first  expression raised to  the power  of the  second
expression.  The second expression must be an integer.  If a is the scale
of the  left  expression  and  b is  the  absolute  value  of  the  right

-------------------------------- Page 15 --------------------------------

expression, then the scale of the result is:

min(a*b,max(scale,a))


3.4      MULTIPLICATIVE OPERATORS

The operators *, /, % bind left to right.


3.4.1       EXPRESSION * EXPRESSION

The result is the  product of the two  expressions.  If a  and b are  the
scales of the two expressions, then the scale of the result is:

min(a+b,max(scale,a,b))


3.4.2       EXPRESSION / EXPRESSION

The result is  the quotient  of the two  expressions.  The  scale of  the
result is the value of scale.


3.4.3       EXPRESSION % EXPRESSION

The % operator produces the remainder of the division of the two  expres-
sions.  More precisely, a%b is a-a/b*b.

The scale of the result  is the sum of the  scale of the divisor and  the
value of scale.


3.5      ADDITIVE OPERATORS

The additive operators bind left to right.


3.5.1       EXPRESSION + EXPRESSION

The result is the sum of the two expressions.  The scale of the result is
the maximum of the scales of the expressions.


3.5.2       EXPRESSION - EXPRESSION

The result is the difference  of the two expressions.   The scale of  the
result is the maximum of the scales of the expressions.

-------------------------------- Page 16 --------------------------------

3.6      ASSIGNMENT OPERATORS

The assignment operators bind right to left.


3.6.1       NAMED-EXPRESSION = EXPRESSION

This expression results in assigning the  value of the expression on  the
right to the named expression on the left.


3.6.2       NAMED-EXPRESSION =+ EXPRESSION


3.6.3       NAMED-EXPRESSION =- EXPRESSION


3.6.4       NAMED-EXPRESSION =* EXPRESSION


3.6.5       NAMED-EXPRESSION =/ EXPRESSION


3.6.6       NAMED-EXPRESSION =% EXPRESSION


3.6.7       NAMED-EXPRESSION =^ EXPRESSION

The result of the above expressions is equivalent to "named expression  =
named expression OP  expression", where  OP is the  operator after the  =
sign.




4.    RELATIONS

Unlike all other operators,  the relational operators  are only valid  as
the object of an if, while, or inside a for statement.


4.1      EXPRESSION < EXPRESSION


4.2      EXPRESSION > EXPRESSION

-------------------------------- Page 17 --------------------------------

4.3      EXPRESSION <= EXPRESSION


4.4      EXPRESSION >= EXPRESSION


4.5      EXPRESSION == EXPRESSION


4.6      EXPRESSION != EXPRESSION




5.    STORAGE CLASSES

There are only two storage classes  in bc, global and automatic  (local).
Only identifiers that are to be local to a function need be declared with
the auto command.  The arguments to a function are local to the function.
All other identifiers are assumed to be global and available to all func-
tions.  All identifiers, global and  local, have initial values of  zero.
Identifiers declared as auto are  allocated on entry to the function  and
released on returning from  the function.  They  therefore do not  retain
values between function calls.   auto arrays are  specified by the  array
name followed by empty square brackets.

Automatic variables in  bc do  not work  in exactly  the same  way as  in
either C or PL/I.   On entry to a function,  the old values of the  names
that appear as parameters and  as automatic variables  are pushed onto  a
stack.  Until return is made from the function, reference to  these names
refers only to the new values.




6.    STATEMENTS

Statements must  be separated  by  semicolon or  newline.   Except  where
altered by control statements, execution is sequential.


6.1      EXPRESSION STATEMENTS

When a statement is an expression, unless the main operator is an assign-
ment, the value of the expression is printed, followed by a newline char-
acter.

-------------------------------- Page 18 --------------------------------

6.2      COMPOUND STATEMENTS

Statements may  be  grouped  together  and used  when  one  statement  is
expected by surrounding them with { }.


6.3      QUOTED STRING STATEMENTS

"any string"

This statement prints the string inside the quotes.


6.4      IF STATEMENTS

if(relation) statement

The substatement is executed if the relation is true.


6.5      WHILE STATEMENTS

while(relation) statement

The statement is executed while  the relation is  true.  The test  occurs
before each execution of the statement.


6.6      FOR STATEMENTS

for(expression; relation; expression) statement

The for statement is the same as

first-expression
while(relation) {
        statement
        last-expression
}

All three expressions must be present.


6.7      BREAK STATEMENTS

break

break causes termination of a for or while statement.

-------------------------------- Page 19 --------------------------------

6.8      AUTO STATEMENTS

auto identifier[,identifier...]

The auto statement  causes the  values of  the identifiers  to be  pushed
down.  The identifiers can be ordinary identifiers or array  identifiers.
Array identifiers  are specified  by following  the array  name by  empty
square brackets.  The  auto statement  must be the  first statement in  a
function definition.


6.9      DEFINE STATEMENTS

define([parameter[,parameter...]]){
        statements}

The define statement defines a function.  The parameters may be  ordinary
identifiers or array names.  Array names must be followed by empty square
brackets.


6.10     RETURN STATEMENTS

return
return(expression)

The return statement  causes termination  of a function,  popping of  its
auto variables, and specifies the result of the function.  The first form
is equivalent to return(0).  The result of the function is the result  of
the expression in parentheses.


6.11     QUIT

The quit statement stops execution of a bc program and returns control to
UTS when it is first  encountered.  Because it is not treated as an  exe-
cutable statement, it cannot be  used in a function  definition or in  an
if, for, or while statement.
