bs(1) bs(1)NAME bs - a compiler/interpreter for modest-sized programs SYNOPSIS bs [file [args]] DESCRIPTION bs is a remote descendant of BASIC and SNOBOL4, with a lit- tle C language thrown in. bs is designed for programming tasks where program development time is as important as the resulting speed of execution. Formalities of data declara- tion and file/process manipulation are minimized. Line-at- a-time debugging, the trace and dump statements, and useful run time error messages all simplify program testing. Furthermore, incomplete programs can be debugged; inner functions can be tested before outer functions have been written and vice versa. If the command line file argument is provided, the file is used for input before the console is read. By default, statements read from the file argument are compiled for later execution. Likewise, statements entered from the con- sole are normally executed immediately (see compile and exe- cute below). Unless the final operation is an assignment, the result of an immediate expression statement is printed. bs programs are made up of input lines. If the last charac- ter on a line is a \, the line is continued. bs accepts lines of the following form: statement label statement A label is a name (see Expression Syntax later in this sec- tion) followed by a colon. A label and a variable may have the same name. A bs statement is either an expression or a keyword followed by zero or more expressions. Some keywords (clear, compile, !, execute, include, ibase, obase, and run) are always exe- cuted as they are compiled. Statement Syntax expression The expression is executed for its side effects (value, assignment or function call). See Expression Syntax for details about expressions. Descriptions of statement types are as follows: break break exits from the innermost for/while loop. April, 1990 1
bs(1) bs(1)clear Clears the symbol table and compiled statements. clear is executed immediately. compile [expression] Succeeding statements are compiled (overriding the im- mediate execution default). The optional expression is evaluated and used as a filename for further input. A clear is associated with this latter case. compile is executed immediately. continue continue transfers to the loop-continuation of the current for/while loop. dump [name] The name and current value of every nonlocal variable is printed. Optionally, only the named variable is report- ed. After an error or interrupt, the number of the last statement and (possibly) the user-function trace are displayed. exit [expression] Return to system level. The expression is returned as process status. execute Change to immediate execution mode (an interrupt has a similar effect). This statement does not cause stored statements to execute (see run later in this section). for name = expression expression statement for name = expression expression ... next for expression , expression , expression statement for expression , expression , expression ... next The for statement repetitively executes a statement (first form) or a group of statements (second form) under control of a named variable. The variable takes on the value of the first expression, then is incremented by one on each loop, not to exceed the value of the second ex- pression. The third and fourth forms require three ex- pressions separated by commas. The first of these is the initialization, the second is the test (true to contin- ue), and the third is the loop-continuation action (nor- mally an increment). fun f( [a, ...]) [v, ...] 2 April, 1990
bs(1) bs(1)... nuf fun defines the function name, arguments, and local vari- ables for a user-written function. Up to ten arguments and local variables are allowed. Such names cannot be arrays, nor can they be I/O associated. Function defini- tions may not be nested. freturn A way to signal the failure of a user-written function. See the interrogation operator (?), later in this sec- tion. If interrogation is not present, freturn merely returns zero. When interrogation is active, freturn transfers to that expression (possibly by-passing inter- mediate function returns). goto name Control is passed to the internally-stored statement with the matching label. ibase N ibase sets the input base (radix) to N. The only sup- ported values for N are 8, 10 (the default), and 16. Hexadecimal values 10-15 are entered as a-f. A leading digit is required (that is, f0a must be entered as 0f0a). ibase (and obase later in this section) are executed im- mediately. if expression statement if expression ... [ else ... ] fi The statement (first form) or group of statements (second form) is executed if the expression evaluates to nonzero. The strings 0 and "" (null) evaluate as zero. In the second form, an optional else allows for a group of statements to be executed when the first group is not. The only statement permitted on the same line with an else is an if; only other fi's can be on the same line with a fi. The elision of else and if into an elif is supported. Only a single fi is required to close an if...elif...[else...] sequence. include expression The expression must evaluate to a filename. The file must contain bs source statements. Such statements be- come part of the program being compiled. include state- ments may not be nested. obase N April, 1990 3
bs(1) bs(1)obase sets the output base to N (see ibase earlier in this section). onintr label onintr The onintr command provides program control of inter- rupts. In the first form, control will pass to the label given, just as if a goto had been executed at the time onintr was executed. The effect of the statement is cleared after each interrupt. In the second form, an in- terrupt will cause bs to terminate. return [expression] The expression is evaluated and the result is passed back as the value of a function call. If no expression is given, zero is returned. run The random number generator is reset. Control is passed to the first internal statement. If the run statement is contained in a file, it should be the last statement. stop Execution of internal statements is stopped. bs reverts to immediate mode. trace [expression] The trace statement controls function tracing. If the expression is null (or evaluates to zero), tracing is turned off. Otherwise, a record of user-function calls/returns will be printed. Each return decrements the trace expression value. while expression statement while expression ... next while is similar to for except that only the conditional expression for loop-continuation is given. ! shell command An immediate escape to the Shell. # ... This statement is ignored. It is used to interject com- mentary in a program. Expression Syntax name A name is used to specify a variable. Names are composed of a letter (upper or lowercase), optionally followed by letters and digits. Only the first six characters of a 4 April, 1990
bs(1) bs(1)name are significant. Except for names declared in fun statements, all names are global to the program. Names can take on numeric (double float) values, string values, or can be associated with input/output (see the built-in function open() later in this section). name ( [expression[ , expression]...]) Functions may be called by a name followed by the argu- ments in parentheses separated by commas. Except for built-in functions (listed later in this section), the name must be defined with a fun statement. Arguments to functions are passed by value. name [expression[ ,expression]...] This syntax is used to reference either arrays or tables (see built-in table functions later in this section). For arrays, each expression is truncated to an integer and used as a specifier for the name. The resulting ar- ray reference is syntactically identical to a name; a[1,2] is the same as a[1][2]. The truncated expressions are restricted to values between 0 and 32767. number A number is used to represent a constant value. A number is written in Fortran style, and contains digits, an op- tional decimal point, and possibly a scale factor con- sisting of an e followed by a possibly-signed exponent. string Character strings are delimited by " characters. The \ escape character allows the double quote (\"), newline (\n), carriage return (\r), backspace (\b), and tab (\t) characters to appear in a string. Otherwise, \ stands for itself. ( expression ) Parentheses are used to alter the normal order of evalua- tion. ( expression, expression [, expression...] )[ expression] The bracketed expression is used as a subscript to select a comma-separated expression from the parenthesized list. List elements are numbered from the left, starting at zero. The expression: ( False, True )[ a == b ] has the value true if the comparison is true. ? expression The interrogation operator tests for the success of the expression, rather than its value. At the moment, it is April, 1990 5
bs(1) bs(1)useful for testing for end-of-file (see examples in Pro- gramming Tips, below), the result of the eval built-in function, and for checking the return from user-written functions (see freturn). An interrogation trap (end-of- file, and so forth) causes an immediate transfer to the most recent interrogation, possibly skipping assignment statements or intervening function levels. - expression The result is the negation of the expression. ++name Increments the value of the variable (or array refer- ence). The result is the new value. --name Decrements the value of the variable. The result is the new value. ! expression The logical negation of the expression. Watch out for the shell escape command. expression operator expression Common functions of two arguments are abbreviated by the two arguments separated by an operator denoting the func- tion. Except for the assignment, concatenation, and re- lational operators, both operands are converted to numer- ic form before the function is applied. Binary Operators The binary operators are listeds in order of increasing pre- cedence, as follows: = THe equal sign (=) is the assignment operator. The left operand must be a name or an array element. The result is the right operand. Assignment binds right to left, all other operators bind left to right. _ Th underscore (_) is the concatenation operator. & | The logical AND character & has result zero if either of its arguments are zero. It has result one if both of its arguments are nonzero; the logical OR character | has result zero if both of its arguments are zero. It has result one if either of its arguments is nonzero. Both operators treat a null string as a zero. < <= > >= == != 6 April, 1990
bs(1) bs(1)The relational operators (< less than, <= less than or equal, > greater than, >= greater than or equal, == equal to, != not equal to) return one if their arguments are in the specified relation. They return zero otherwise. Re- lational operators at the same level extend as follows: a>b>c is the same as a>b & b>c. A string comparison is made if both operands are strings. + - Add and subtract. * / % Multiply, divide, and remainder. ^ Exponentiation. BUILT-IN FUNCTIONS Dealing with Arguments arg(i) The value of the ith actual parameter on the current lev- el of function call. At level zero, arg returns the ith command-line argument (arg(0) returns bs). narg() Returns the number of arguments passed. At level zero, the command argument count is returned. Mathematical abs(x) The absolute value of x. atan(x) The arctangent of x. Its value is between -π/2 and π/2. ceil(x) Returns the smallest integer not less than x. cos(x) The cosine of x (radians). exp(x) The exponential function of x. floor(x) Returns the largest integer not greater than x. log(x) The natural logarithm of x. rand() A uniformly distributed random number between zero and April, 1990 7
bs(1) bs(1)one. sin(x) The sine of x (radians). sqrt(x) The square root of x. String operations size(s) The size (length in bytes) of s is returned. format(F, a) Returns the formatted value of a. F is assumed to be a format specification in the style of printf(3S). Only the %...f, %...e, and %...s types are safe. index(x, y) Returns the number of the first position in x that any of the characters from y matches. No match yields zero. trans(s, f, t) Translates characters of the source s from matching char- acters in f to a character in the same position in t. Source characters that do not appear in f are copied to the result. If the string f is longer than t, source characters that match in the excess portion of f do not appear in the result. substr(s, start,width) returns the sub-string of s defined by the start position and width. match(string, pattern) mstring(n) The pattern is similar to the regular expression syntax of the ed(1) command. The characters ., [, ], *, and $ are special. The mstring function returns the nth (1 <= n <= 10) substring of the subject that occurred between pairs of the pattern symbols \( and \) for the most re- cent call to match. To succeed, patterns must match the beginning of the string (as if all patterns began with *). The function returns the number of characters matched. For example match("a123ab123", ".*\([a-z]\)") == 6 mstring(1) == "b" File Handling open(name, file, function) close(name) 8 April, 1990
bs(1) bs(1)The name argument must be a bs variable name (passed as a string). For the open, the file argument may be either (1) a 0 (zero), 1, or 2, representing standard input, output, or error output, respectively, (2) a string representing a filename, or (3) a string beginning with an ! representing a command to be executed (via sh -c). The function argument must be either r (read), w (write), W (write without newline), or a (append). After a close, the name reverts to being an ordinary variable. The ini- tial associations are open("get", 0, "r") open("put", 1, "w") open("puterr", 2, "w") Examples are given in the following section. access(s, m) Executes access(2). ftype(s) Returns a single character file type indication: f for regular file, p for FIFO (that is, named pipe), d for directory, b for block special, or c for character spe- cial. Tables table(name, size) A table in bs is an associatively accessed, single- dimension array. Subscripts (called keys) are strings (numbers are converted). The name argument must be a bs variable name (passed as a string). The size argument sets the minimum number of elements to be allocated. bs prints an error message and stops on table overflow. item(name, i) key() The item function accesses table elements sequentially (in normal use, there is no orderly progression of key values). Where the item function accesses values, the key function accesses the subscript of the previous item call. The name argument should not be quoted. Since ex- act table sizes are not defined, the interrogation opera- tor should be used to detect end-of-table, for example: table("t", 100) ... # If word contains the string "party", # the following expression adds one # to the count of that word: April, 1990 9
bs(1) bs(1)++t[word] ... # To print out the the key/value pairs: for i = 0, ?(s = item (t , i)), ++i if key() put = key()_:_s iskey(name, word) The iskey function tests whether the key word exists in the table name and returns one for true, zero for false. Odds and Ends eval(s) The string argument is evaluated as a bs expression. The function is handy for converting numeric strings to numeric internal form. eval may also be used as a crude form of indirection, as in name = "xyz" eval("++"_ name) which increments the variable xyz. In addition, eval preceded by the interrogation operator permits the user to control bs error conditions. For example, ?eval("open(\"X\", \"XXX\", \"r\")") returns the value zero if there is no file named XXX (in- stead of halting the user's program). The following exe- cutes a goto to the label L (if it exists): label="L" if !(?eval("goto "_ label)) puterr = "no label" plot(request, args) The plot function produces output on devices recognized by tplot(1G). The requests are as follows: Call Function plot(0, term) Causes further plot output to be piped into tplot(1G) with an argument of -Tterm. plot(1) Erases the plotter. plot(2, string) Labels the current point with string. plot(3,x1,y1,x2,y2) 10 April, 1990
bs(1) bs(1)Draws the line between (x1,y1) and (x2,y2). plot(4,x,y,r) Draws a circle with center (x,y) and radius r. plot(5,x1,y1,x2,y2,x3,y3) Draws an arc (counterclockwise) with center (x1,y1) and endpoints (x2,y2) and (x3,y3). plot(6) Not implemented. plot(7,x,y) Makes the current point (x,y). plot(8,x,y) Draws a line from the current point to (x,y). plot(9,x,y) Draws a point at (x,y). plot(10,string) Sets the line mode to string. plot(11,x1,y1,x2,y2) Makes (x1,y1) the lower left corner of the plotting area and (x2,y2) the upper-right corner of the plot- ting area. plot(12,x1,y1,x2,y2) Causes subsequent x(y) coordinates to be multiplied by x1 (y1) and then added to x2 (y2) before they are plotted. The initial scaling is plot(12,1.0, 1.0,0.0,0.0) Some requests do not apply to all plotters. All requests except zero and twelve are implemented by piping charac- ters to tplot(1G). See plot(4) for more details. last() In immediate mode, last returns the most recently comput- ed value. NOTES Using bs as a calculator $ bs # Distance (inches) light travels # in a nanosecond. 186000 * 5280 * 12 / 1e9 11.78496 ... April, 1990 11
bs(1) bs(1)# Compound interest # (6% for 5 years on $1,000). int = .06 / 4 bal = 1000 for i = 1 5*4 bal = bal + bal*int bal - 1000 346.855007 ... exit The outline of a typical bs program # initialize things: var1 = 1 open("read", "infile", "r") ... # compute: while ?(str = read) ... next # clean up: close("read") ... # last statement executed (exit or stop): exit # last input line: run Input/Output examples # Copy "oldfile" to "newfile". open("read", "oldfile", "r") open("write", "newfile", "w") ... while ?(write = read) ... # close "read" and "write": close("read") close("write") # Pipe between commands. open("ls", "!ls *", "r") open("pr", "!pr -2 -h 'List'", "w") while ?(pr = ls) ... ... # be sure to close (wait for) these: close("ls") close("pr") 12 April, 1990
bs(1) bs(1)EXAMPLES bs program 1 2 3 compiles or executes the file named program as well as statements typed from standard input. The arguments 1, 2, and 3 are passed as arguments to the compiled/executed pro- gram. FILES /bin/bs SEE ALSO ed(1), ksh(1), sh(1), tplot(1G), access(2), printf(3S), in- tro(3), plot(4). A/UX Programmer's Reference. April, 1990 13