bs Command

Purpose

Compiles and interprets modest-sized programs.

Syntax

bsFile Arguments ] ]

Description

The bs command is a compiler and interpreter for interactive program development and debugging. To simplify program testing, it minimizes formal data declaration and file manipulation, allows line-at-a-time debugging, and provides trace and dump facilities and run-time error messages.

The optional parameter File specifies a file of program statements that you create and that the compiler reads before it reads from standard input. Statements entered from standard input are normally executed immediately (see compile and execute statement syntax). By default, statements read from File are compiled for later execution.

Unless the final operator is assignment to a variable, the result of an immediate expression statement is displayed.

Additional command line Arguments can be passed to the program using the built-in functions arg and narg.

Program lines must conform to one of the following formats:

statement
label statement

The interpreter accepts labeled statements only when it is compiling statements. A label is a name immediately followed by a colon. A label and a variable can have the same name. If the last character of a line is a \ (backslash), the statement continues on the following physical line.

A statement consists of either an expression or a keyword followed by zero or more expressions.

Note: To avoid unpredictable results when using a range expression in the international environment, use a character class expression rather than a standard range expression.

Statement Syntax

Item Description
break Exits the innermost for or while loop.
clear Clears the symbol table and removes compiled statements from memory. A clear is always executed immediately.
compile [Expression] Causes succeeding statements to be compiled (overrides the immediate execution default). The optional Expression is evaluated and used as a file name for further input. In this latter case, the symbol table and memory are cleared first. compile is always executed immediately.
continue Transfers control to the loop-continuation test of the current for or while loop.
dump [Name] Displays the name and current value of every global variable or, optionally, of the Named variable. After an error or interrupt, dump displays the number of the last statement and (possibly) the user-function trace.
exit [Expression] Returns to the system level. The Expression is returned as process status.
execute Changes to immediate execution mode (pressing the INTERRUPT key has the same effect). This statement does not cause stored statements to execute (see run).
for Performs repeatedly, under the control of a named variable, a statement or a group of statements using one of the following syntaxes:
for name=Expression Expression statement
next

OR

for name=Expression Expression
statement . . . 
next

OR

for Expression, Expression, Expression statement
next

OR

for Expression, Expression, Expression
statement . . .
next

The first format specifies a single statement where the variable takes on the value of the first expression and then is increased by one on each loop until it exceeds the value of the second expression. You can use the second format to do the same thing , but you can specify a group of statements.

The third format requires an initialization expression followed by a test expression (such as true to continue) and a loop-continuation action expression. You can use the fourth format to do the same thing, but you can specify a group of statements. Use commas to separate the expressions in the third and fourth formats.

fun Defines a user-written function using the following syntax:
fun f ([a. . . ]) [v. . . ]
statement . . . 
nuf

f specifies the function name, a specifies any parameters, and v identifies any local variables for the user-written function. You can specify up to 10 parameters and local variables; however, they cannot be arrays or associated with I/O functions. You cannot nest function definitions.

freturn Signals the failure of a user-written function. Without interrogation, freturn returns zero. (See the unary interrogation operator ( ?).) With interrogation, freturn transfers to the interrogated expression, possibly bypassing intermediate function returns.
goto Name Passes control to the compiled statement with the matching label of Name.
ibase n Sets the input base to n. The only supported values for n are 8, 10 (the default), and 16. Hexadecimal values 10-15 are entered as alphabetic characters a-f. A leading digit is required when a hexadecimal number begins with an alphabetic character (for example, f0a must be entered as 0f0a). ibase is always executed immediately.
if Performs a statement in one of the following syntaxes:
if Expression statement
[else
statement . . . ]
fi

OR

if Expression
statement . . .
 [else
statement . . . ]
fi

The first format specifies a single statement and the second format specifies a group of statements to continue using if the expression evaluates to nonzero. The strings 0 and "" (null) evaluate as zero.

In the second format, an optional else allows a group of statements to be performed when the first group is not. The only statement permitted on the same line with an else is an if. You can put fis only on the same line as another fi. You can combine else and if into elif. You can close an if . . . elif . . . [else . . . ] sequence with a single fi.

include Expression Evaluates an Expression to the name of a file containing program statements. Such statements become part of the program being compiled. The include statements are always executed immediately. Do not nest include statements.
obase n Sets the output base to n. The only supported values for n are 8, 10 (the default), and 16. Hexadecimal values 10 through15 are entered as alphabetic characters a-f. A leading digit is required when a hexadecimal number begins with an alphabetic character (that is, f0a must be entered as 0f0a). Like ibase, obase is always executed immediately.
onintr Provides program control of interrupts using one of the following syntaxes:
onintr Label

OR

onintr

In the first format, control passes to the Label given, just as if a goto had been performed when onintr was executed. The effect of the onintr statement is cleared after each interrupt. In the second format, pressing INTERRUPT ends the bs program.

return [Expression] Evaluates the Expression and passes the result back as the value of a function call. If you do not provide an expression, the function returns zero.
run Passes control to the first compiled statement. The random number generator is reset. If a file contains a run statement, it should be the last statement; run is always executed immediately.
stop Stops execution of compiled statements and returns to immediate mode.
trace [Expression] Controls function tracing. If you do not provide an Expression or if it evaluates to zero, tracing is turned off. Otherwise, a record of user-function calls/returns will be written. Each return decreases by one the trace expression value.
while Performs repeatedly, under the control of a named variable, a statement or a group of statements using one of the following syntaxes:
while Expression statement
next

OR

while Expression
statement . . . 
next

The while statement is similar to the for statement except that only the conditional expression for loop continuation is given.

!cmd Runs a command and then returns control to the bs program.
# Comment Inserts a comment line.

Expression Syntax

Item Description
Name Specifies a variable or, when followed immediately by a colon, a label. Names are composed of a letter (uppercase or lowercase) optionally followed by letters and digits. Only the first six characters of a name are significant. Except for names declared locally in fun statements, all names are global. Names can take on numeric (double float) values or string values or be associated with input/output (see the built-in function open).
Name([Expression[, Expression] . . . ]) Calls function Name and passes to it the parameters in parentheses. Except for built-in functions, Name must be defined in a fun statement. Function parameters are passed by value.
Name[Expression[, Expression] . . . ] References either arrays or tables (see built-in function table). For arrays, each expression is truncated to an integer and used as a specifier for the name. The resulting array reference is syntactically identical to a name; a [1,2] is the same as a [1] [2]. The truncated expressions must be values between 0 and 32,767.
Number Represents a constant numerical value. This number can be expressed in integer, decimal, or scientific notation (it can contain digits, an optional decimal point, and an optional e followed by a possibly signed exponent).
String Represents a character string delimited by " " (double quotation marks). Within the string, you can use the \ (backslash) as an escape character that allows the double quotation mark (\"), new-line character (\n), carriage return(\r), backspace (\b), and tab (\t) characters to appear in a string. When not immediately followed by these special characters, \ stands for itself.
(Expression) Alters the normal order of evaluation.
(Expression, Expression[, Expression] . . . ) [Expression] Specifies to use the bracketed expression outside the parentheses as a subscript to the list of expressions within the parentheses. List elements are numbered from the left, starting at zero. The following expression has the value of True if the comparison is true:
(False, True) [a == b]
Expression Operator Expression Converts the operands to numeric form before the operator is applied unless the operator is an assignment, concatenation, or relational operator.

Unary Operators

Item Description
? Expression Tests for the success of Expression rather than its value. This interrogation operator is useful for testing:
  • The end of file
  • Result of the eval built-in function
  • Return from user-written functions (see freturn)

An interrogation trap (end of file, for example), causes an immediate transfer to the most recent interrogation, possibly skipping assignment statements or intervening function levels.

- Expression Negates Expression.
++ Name Increases by one the value of the variable (or array reference).
Name Decreases by one the value of the variable.
! Expression Specifies the logical negation of Expression.
Note: Unary operators treat a null string as a zero.

Binary Operators (in increasing precedence)

Item Description
= Specifies the assignment operator. The left operand must be a name or array element. It acquires the value of the right operand. Assignment binds right to left; all other operators bind left to right.
_ Specifies the concatenation operator. (It is the underline character).
& | Specifies logical AND, logical OR.

The result of:

Expression & Expression

is 1 (true) only if both of its parameters are non-zero (true); it is 0 (false) if one or both of its parameters are 0 (false).

The result of:

Expression | Expression

is 1 (true) if one or both of its expressions are non-zero (true); it is 0 (false) only if both of its expressions are 0 (false). Both operators treat a null string as a zero.

< <= > >= == != Specifies the relational operators:
  • < for less than
  • <= for less than or equal to
  • > for greater than
  • >= for greater than or equal to
  • == for equal to
  • != for not equal to

The relational operators return 1 if the specified relation is True; otherwise they return 0 (false). Relational 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. The comparison is based on the collating sequence specified in the environment variable LC_COLLATE. The National Language Support Overview contains more information on this environment variable.

+ - Specifies addition and subtraction.
* / % Specifies multiplication, division, and remainder.
^ Specifies exponentiation.
Note: Binary operators treat a null string as a zero.

Functions Dealing With Arguments

Item Description
arg(i) Returns the value of the i-th actual argument at the current function call level. At level zero, arg returns the i-th command-line argument. For example, arg(0) returns bs.
narg( ) Returns the number of arguments passed. At level zero, it returns the command line argument count.

Mathematical Functions

Item Description
abs(x) Returns the absolute value of x.
atan(x) Returns the arc tangent of x.
ceil(x) Returns the smallest integer not less than x.
cos(x) Returns the cosine of x.
exp(x) Returns e raised to the power x.
floor(x) Returns the largest integer not greater than x.
log(x) Returns the natural logarithm of x.
rand( ) Returns a uniformly distributed random number between zero and one.
sin(x) Returns the sine of x.
sqrt(x) Returns the square root of x.

String Functions

Item Description
size(s) Returns the size (length in characters) of s.
bsize(s) Returns the size (length in bytes) of s.
format(f, a) Returns the formatted value of a, f being a format specification string in the style of the printf subroutine. Use only the %...f,%...e, and %...s formats.
index(x, y) Returns a number that is the first position in x containing a character that any of the characters in y matches. 0 return if no match is found. For 2-byte extended characters, the location of the first byte is returned.
trans(s, f, t) Translates characters in the source string s which match characters in f into characters having the same position in t. Source characters that do not appear in f are copied unchanged into the translated string. If string f is longer than t, source characters that match characters found in the excess portion of f do not appear in the translated string.
substr(s, Start, Length) Returns the substring of s defined by Start position in characters and Length in characters.
match(String, Pattern) mstring(n) Returns the number of characters in string that match pattern. The characters ., *, $, [, ], ^ (when inside square brackets), \ (and \) have the following special meanings:
Note: See ed for a more detailed discussion of this special notation.
.
Matches any character except the new-line character.
*
Matches zero or more occurrences of the pattern element that it follows. For example, .* matches zero or more occurrences of any character except the new-line character.
$
Specifies the end of the line.
[.-.]
Matches any one character in the specified range ([.-.]) or list ([ . . . ]), including the first and last characters.
[^ .-.]
[^ . . . ]
Matches any character except the new-line character and any remaining characters in a range or list. A circumflex (^ ) has this special meaning only when it immediately follows the left bracket.
[].-.]
[] . . . ]
Matches ] or any character in the list. The right square bracket does not terminate such a list when it is the first character within it (after an initial ^ , if any).
\( . . . \)
Marks a substring and matches it exactly.The pattern must match from the beginning of the string and the longest possible string. Consider, for example:
match ('a123ab123',".*\([a-z]\)") = 6

In this instance, .* matches a 123a (the longest string that precedes a character in the range a-z); \ ([a-z]\) matches b, giving a total of six characters matched in the string. In an expression such as [a-z], the minus means "through," according to the current collating sequence.

A collating sequence may define equivalence classes for use in character ranges. See the "International Character Support Overview" for more information on collating sequences and equivalence classes.

The mstring function returns the nth substring in the last call to match (n must be between 1 and 10 inclusive).

File-Handling Functions

open(Name, File, Mode)

Item Description
close(Name) Specifies the name, file type and file mode. Name must be a legal variable name (passed as a string). After a close, the name becomes an ordinary variable. For open, the File can be one of the following:
  • 0 for standard input
  • 1 for standard output
  • 2 for error output
  • A string representing a file name
  • A string beginning with an !, which represents a command to be run (using "sh -c")

Mode must be specified with an r for read, w for write, W for write without the new line character, or a for append. The initial associations are:

  • open ("get", 0, "r")
  • open ("put", 1, "w")
  • open ("puterr", 2, "w")
access(p, m) Performs the access subroutine. Parameter p is the path name of a file; m is a bit pattern representing the requested mode of access. This function returns a 0 if the system request is permitted, -1 if it is denied.
ftype(s) Returns a single character indicating file type: f for regular file, p for FIFO (named pipe), d for directory, b for block special, or c for character special.

Table Functions

Item Description
table(Name, Size) Specifies an associatively accessed, one-dimensional array. "Subscripts" (called keys) are strings (numbers are converted). Name must be a bs variable name (passed as a string). Size sets the minimum number of elements to be allocated. On table overflow, bs writes an error message.
item(Name, i)  
key( ) Accesses table elements sequentially instead of in an orderly progression of key values. Where the item function accesses values, the key function accesses the "subscript" of the previous item call. Do not quote Name.

Since exact table sizes are not defined, the interrogation operator should be used to detect end-of-table; for example:

table("t",100)

               
.
.
.
#If word contains "parity", the following expression
#adds one to the count of that word:
++t[word]
.
.
.
#To display the key/value pairs:
for i = 0, ? (s = item (t, i)), ++i if key( ) put = key
( )_":"_s
iskey(Name, Word) Tests whether the key word exists in the table name and returns one for true, zero for false.

Miscellaneous Functions

Item Description
eval(string) Specifies to evaluate the string parameter as an expression. The function is handy for converting numeric strings to numbers. eval can also be used as a crude form of indirection, as in:
name = "x,y,z"
eval("++"_name)

which increments the variable "x,y,z". In addition, when eval is preceded by ? (interrogation operator), you can control bs error conditions. For example:

?eval ("open(\"X\",\"XXX\", \"r\")")

returns the value zero if there is no file named "XXX" (instead of halting your program). The following performs a goto to the label "L:" (if it exists):

label = "L:"
if! (?eval ("goto"_label))puterr="no label"
plot(request, args) Produces output on devices recognized by the tplot command. Some requests do not apply to all plotters. All requests except 0 and 12 are implemented by piping characters to tplot.

The call requests are as follows:

plot(0, term)
Causes further plot output to be piped into tplot with a flag of -Tterm.
plot(1)
Erases the plotter.
plot(2, string)
Labels the current point with string
plot(3, x1, y1, x2, y2)
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 end points (x2,y2) and (x3, y3).
plot(6)
Not implemented.
plot(7, x, y)
Makes the current point at (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 plotting 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).
last ( ) Returns, in immediate mode, the most recently computed value.

Example

To execute the bs command and direct the result to a file called output, enter:

bs < input.n > output

OR

bs input.n > output