Home Page | Introduction | Tutorials | Reference | Packages | Hacking

- 3.1 AdaScript versus GCC
- 3.2 Case Sensitivity
- 3.3 Reserved Words
- 3.4 Comments
- 3.5 Literals
- 3.6 Bourne Shell Arguments
- 3.7 Fundamental Types
- 3.8 User-defined Types
- 3.9 Enumerated Types
- 3.10 Arrays
- 3.11 Records
- 3.12 Basic Assignment
- 3.13 The @ and %
- 3.14 Command Argument Shortcuts
- 3.15 Redirection and Pipelines
- 3.16 Command Line Interaction
- 3.17 Interactive Statements
- 3.18 The Current Directory
- 3.19 Database Commands
- 3.20 Flow of Control
- 3.21 Other Statements/Subprograms
- 3.22 External Commands
- 3.23 Block Statements and Subprograms
- 3.24 TCP/IP Sockets
- 3.25 Numeric Formatting with Put
- 3.26 Interpreter Directives
- 3.27 Command Line Options
- 3.28 Command Reference
- 3.29 ASCII Character Set
- 3.30 Common Error Messages
- 3.31 Common PHP Functions and the BUSH Equivalent

This part of the guide provides a technical overview of the AdaScript language including the basic types, keywords, syntax structures and Bourne shell commands.

### 3.1 AdaScript versus GCC Ada 95

The computer language that the BUSH shell understands is called AdaScript. Unlike JavaScript, which has no relation to Java, AdaScript is a small subset of the Ada programming language, with additional features related to shell commands.

AdaScript is intended to be "upward compatible" with Ada. AdaScript scripts should run with little difficulty under Ada, but Ada programs may require large changes run under BUSH.

### 3.2 Case Sensitivity

AdaScript is a case-sensitive language because shell variables and Linux commands are all case-sensitive. If AdaScript ignored the case of variables and commands, some commands couldn't be run and some variables couldn't be used.

Ada is case-insensitive and programs may need to have the capitalization of keywords changed to fit the case expected by AdaScript.

### 3.3 Reserved Words

AdaScript has a number of reserved words. These are keywords that have a special significance to the language and they cannot be used as variable names. The following table lists all reserved words. They are only reserved when in lower case.

`abort` `abs` `abstract` `accept` `aliased` `all` `and` `array` `at` `begin` `body` `case` `clear` `constant` `declare` `delay` `delta` `digits` `do` | `else` `elsif` `end` `entry` `env` `exception` `exit` `for` `function` `generic` `goto` `help` `if` `in` `is` `jobs` `limited` `logout` `loop` | `mod` `new` `not` `null` `of` `or` `others` `out` `package` `pragma` `private` `procedure` `protected` `raise` `range` `record` `rem` `renames` `requeue` | r`eturn` `reverse` `select` `separate` `subtype` `tagged` `task` `terminate` `then` `trace` `type` `typeset` `unset` `until` `use` `when` `while` `with` `xor`

If you attempt to use a reserved word, you will receive a error

`=> digits : integer`
`digits : integer;`
`^ identifier expected, not a keyword`
`=> DIGITS : integer`
`=>`

All Ada keywords are also reserved, even those that are not used by AdaScript, to make it easier to compile scripts under GCC Ada.

### 3.4 Comments

Comments are denoted by a "--" and all text after these symbols is ignored until the end of line.
`=> null; -- An Ada style comment`
As a special case, scripts may begin with a path to the interpreter as specified with "#!". BUSH doesn't honor any parameters included with the path.
#!/usr/local/bin/bush
In this case, the operating system would look for BUSH in /usr/local/bin if the script file is executed directly. This is the standard behavior for Linux and UNIX-based operating systems.

### 3.5 Literals

Numbers (numeric literals) can contain a decimal point. An alternate base (hex, octal, etc.) can be specified by following the base with the value between '#'. Hexadecimal letter characters can be in upper or lower case. Scientific notation is not yet supported.

    => ? 16#FFFF#
     65535

- `5` - the integer 5
- `5.0` the integer 5.0
- `8#777#` - the octal value 511
- `16#ff#` - the hexadecimal value 255

Characters are enclosed in single quotes.

- `'a'` - the character a

Strings are enclosed in double quotes.

- `"hello"` - the string hello

### 3.6 Bourne Shell Arguments

BUSH provides a subset of Bourne shell features for convenient use on the command line. Many new users are already familiar with the Bourne shell since it's the standard shell for Linux and FreeBSD. Also, the AdaScript syntax can be awkward to use for simple interactive commands. Where the Bourne standard conflicts with Ada BUSH always favors compatibility with Ada for the sake of the progressive development model.
Bourne shell arguments consist of groups of characters called "words". Each word is separated by spaces. BUSH does not implement the Bourne shell IFS variable.
Argument expansion is the process of performing substitutions on a Bourne shell word. Argument expansion occurs at run-time since it depends on the current working directory and the current value of variables.
Bourne shell expansions include:

Brace Expansion | a.{txt,.dat} | a.txt a.dat | not implemented
Tilde Expansion | ~a/a.txt | /home/user/a.txt | OK
Variable Expansion | $HOME/a.txt | /home/usr/a.txt | OK
Command Substitution | `/bin/echo a.txt` | a.txt | Backquotes only
Arithmetic Expansion | $((2+2)) | 4 | not implemented (use AdaScript parameters)
Pathname Expansion | a.* | a.txt a.dat | OK
Word Splitting | a\ word | "a word" | OK

There is no brace expansion, arithmetic expansion or process substitution. Some features support only a subset of the BASH features. For example, many of the special $ substitutions (${...}, $(...) and others) are not implemented. Otherwise, the basic Bourne shell features implemented in BUSH conform to the POSIX standard.

### 3.7 Fundamental Types

All AdaScript variables have a type. Variables must declared so that BUSH knows what that type is. When new variables are created by assignment at the command prompt, BUSH choses an appropriate type for the new variable. In scripts, all variables must be declared.

Universal Types

There are three "universal types":

Type Name | Content | Usage
`universal_string` | unlimited length, 8-bit characters | text
`universal_numeric` | double precision floating point values | numbers
`universal_typeless` | same as universal_string/numeric | text or numbers

The first two types form the basis for all other AdaScript string and numeric types. Variables declared as universal_typeless change their type between universal_string and universal_numeric depending how they are used. If AdaScript cannot decide in a particular context, the variable type defaults to universal_string. Typeless variables correspond to variables in Bourne shells and are provided for as a command line convenience.

Universal types automatically match any type derived from the same universal type. A universal_numeric variable accepts integer or floating point values. A universal_string variable accepts single characters or strings containing many characters.

Universal types are used for all AdaScript literals. For example, a string literal like "hello" is a universal_string and be assigned to any string type. The numeric literal 45.5 is a universal_numeric can be used with float, long_float, or any other numeric type.

Using these three built-in types will give you a minimum amount of type checking, suitable for short scripts or quick command line calculations. Universal types should not be used in large scripts because they will greatly reduce the number of errors BUSH can detect.

Predefined, Non-Universal Types

For more extensive scripts, AdaScript extends the universal string and numeric types into all the predefined Ada language types, plus some AdaScript-specific types:

Type Name | Base Type | Usage | GCC Ada Equivalent
`integer` | `universal_numeric` | number without a radix point | `integer`
`natural` | `universal_numeric` | 0 or integer larger than zero | `natural`
`positive` | `universal_numeric` | integer larger than zero | `positive`
`short_short_integer` | `universal_numeric` | very small integer | `short_short_integer`
`short_integer` | `universal_numeric` | small integer | `long_integer`
`long_integer` | `universal_numeric` | large integer | `long_long_integer`
`long_long_integer` | `universal_numeric` | very large integer | `float`
`float` | `universal_numeric` | floating point number | `float`
`short_float` | `universal_numeric` | small floating point number | `short_float`
`long_float` | `universal_numeric` | large floating point number | `long_float`
`character` | `universal_string` | 8-bit character | `character`
`string` | `universal_string` | unlimited length string | almost `unbounded_string`
`unbounded_string` | universal_string | unlimited length string | almost `unbounded_string`
`duration` | `universal_numeric` | time, float seconds | `duration`
`boolean` | enumerated type | `true` or `false` | `boolean`
`file_type` | limited type | operating system files | `file_type`
`file_mode` | enumerated type | `in_file`, `out_file` or `append_file` | `file_mode`
`command` | limited type | alias for an operating system command | -

The built-in packages may define additional types.

By default, all numeric variables are initialized without any value. Any attempt to use uninitialized numeric variables in an expression will cause an error or exception.

`=> i : integer -- no value specified`
`=> i := i + 1`
`i := i + 1;`
`^ exception raised`

All types are logical types: that is, all numeric types are stored in the same format. A natural, integer or float are all stored as a universal numeric value. There are only minimal checks to make sure that variables of these types conform to their descriptions. However, types provide an indication to the reader of how a variable is intended to be used, and AdaScript will not allow these types to be combined without an appropriate type cast.

`=> i : integer := 5`
`=> f : float := 0`
`=> f := i`
`f := i;`
`^ type 'float' is not compatible with type 'integer'`
`=> f := float(i) -- typecast`
`=> ? f`
`5`

You cannot typecast a numeric type into a string type directly. There are functions in the numerics and strings packages to do these conversions.

Since all values are stored as a universal type, this can cause some unusual side-effects. A character variable can contain more than one character if you really want it to by assigning a string literal. Characters are stored as a universal_string and a string literal is a universal_string type. AdaScript will allow the assignment. However, the type checking will prevent a character variable from being assigned to a string variable.

`c : character;`
`c := "hello"; -- confusing, perhaps stupid, but legal`
`s : string := c; -- ILLEGAL`

AdaScript strings are an unbounded string type--that is, they are stored as an Ada.Strings.Unbounded.Unbounded_String variable. They have an unlimited length and are not implemented as any sort of array. Ada "fixed" strings, the default string type for GCC Ada, are not used because they have limited length and can create array bounds exceptions. Strings are an integral part of scripts and unbounded strings are used instead. AdaScript includes an unbounded_string type (it has the same properties as the string type) which may make porting to GCC Ada easier.

Constants

Constants can be declared with the word "constant" for any type. The use of "constant" doesn't not affect the type of the variable--it simply prevents new values from being assigned by making the variable "read-only".

`program_name : constant string := "Nightly FTP Transfer";`

Limited Types

file_type and socket_type variables are known as limited type variables. Limited types cannot be assigned a new value with an assignment statement

`=> f : file_type`
`=> g : file_type`
`=> f := g`
`f := g;`
`^ limited variables cannot be assigned a value`

BUSH manages the contents of these variables and scripts are not allowed to change the contents.

Complex Types

Variables declared complex represent complex numbers. A complex number is a record with long_float real and imaginary parts. The real field is designated "re" and the imaginary field is designated "im". (See below for more information about using records.)

<>=> c : complex := ( 1.0, 2.0 )
=> ? c.re
1.0
=> ? c.im
2.0
=> c.re := 5.0
=> ? c.re
5.0
=> numerics.set_re( c, 3.0 )
=> ? c.re
3.0
Some of the numerics package subprograms work with complex types.

Complex types are not fully implemented in this version of BUSH: some of the Ada complex number functions are not available.

Command Types

External operating system commands can be declared using command variables. When a command is declared, BUSH will ensure that the command exists and is runnable.

Command types are similar to limited types and have several restrictions.

- they must be declared as constants
- they cannot be assigned to other variables
- they cannot be used in expressions (although they can appear by themselves and are treated as strings)

`=> l : constant command := "/bin/ls"`
`=> m : constant command := "/bin/lt"`
`m : constant command := "/bin/lt";`
`^ "/bin/lt" is not an executable command`
`=> n : constant command := l;`
`n : constant command := l;`
`^ type universal_string is inherently different from a command`
`=> ? l & " is the path"`
`? l & " is the path";`
`^ type command is inherently different from a universal_string`
`=> ? l`
`/bin/ls`

### 3.8 User-defined Types

You can extend the fundamental types to create your own types.

The subtype statement will create a type that is compatible with the original, as if it was a renaming of the original type.

`=> subtype int is integer;`
`=> i1 : integer := 1`
`=> i2 : int := 2`
`=> ? i1 + i2`
`3`

In this case, "int" is equivalent to "integer" and variables of both types can be mixed freely without type casting. Unlike Ada 95, there is no way to place restrictions on a subtype--they are simple renamings in AdaScript.

To make incompatible types, you need to create a new type with the type statement.

`=> type employee_number is new integer;`
`=> type customer_number is new integer;`
`=> en : employee_number`
`=> cn : customer_number`
`=> en := cn`
`en := cn;`
`^ type 'employee_number' is not compatible with type 'customer_number'`

In this case, "employee_number" variables cannot be mixed with "customer_number" (or other) variables without a typecast. Use new types to make sure variables that are logically different don't accidentally mix.

### 3.9 Enumerated Types

AdaScript also has an enumerated type. Enumerated types are naturally incompatible with one another, and the items in the enumerated list cannot be overloaded with other enumerated types.

`=> type fruit is (apple, blueberry, cherry);`
`=> f : fruit`
`=> f := apple`
`=> f := 5`
`f := 5;`
`^ type fruit (an enumerated type) is inherently different from a universal_numeric`

There are two built-in enumerated types. The boolean type is a predefined enumerated type with values "false" and "true". The file_mode type has the values "in_file", "out_file" and "append_file".

AdaScript has no aggregate types except for simple arrays and records. If you need these, your project is probably too complicated for a simple script and should be upgraded to Ada 95.

### 3.10 Arrays

Arrays are lists of values of one type. Each value is accessed by an numeric or enumerated index.

To declare an anonymous array (an array with no type name):

`=> zerbra_population : array(1900..1999) of natural`
`=> type divisions is (america, asia, africa, eurpoe, oceania )`
`=> sales : array (america..oceania) of float`

The first array contains 100 entries and each entry is a natural number. To assign values or to access array entries, put the index number in parentheses after the array name.

`=> zebra_population(1950) := 150000`
`=> ? zebra_population( 1950 )`
`150000`

Attempting to use an out-of-range index number is an error

`=> ? zebra_population( 0 )`
`^ exception raised`

You can create new array types.

`=> type zebra_list is array( 1900..1999 ) of natural;`
`=> zl : zebra_list`

When you declare an array, you can assign a list of initial values or copy the values of another identical array.

`=> type grocery_list is array(1..10) of string`
`=> gl : grocery_list := ( "milk", "bananas", "bread", "butter", "salt", "flour", "pizza", "noodles", "", "" )`
`=> gl2 : grocery_list := gl`
`=> ? gl2(2)`
`bananas`

An empty array can be created using 1..0. This is the only case where the low bound is higher than the high bound.

`=> empty : array(1..0) of integer`

Bush does not support assigning one array to another in an assignment statement, unconstrained arrays or multi-dimensional arrays.

### 3.11 Records

Records (or "structs" in the C language) are a group of variables collected under a single name. Records can serve as tables or help to declare and manage related information. Unlike arrays, records contain values of different types.

BUSH has limited support for record types and record variables.

Before you declare a record, create a record type describing the group of variables a record will represent.

`type customer is record`
`name : string;`
`address : string;`
`balance : float;`
`active : boolean;`
`end record;`

This type describes a record containing five variables (or "fields").

To create a record variable, use this type.

`sushi_express : customer;`

You can assign initial values when you declare the variable.

`united_snorkels : customer := ("United Snorkels", "555 Snorkel Street", 9456.45, true );`
`current_customer : customer := united_snorkels;`

To reference the parts of the record, use dot notation.

`sushi_express.name := "Sushi Express Inc.";`
`put_line( sushi_express.name );`

BUSH supports only a small subset of GCC Ada's record features. Arrays of records, or records with arrays, and default values are not (yet) supported. Assigning records to records is only supported in declarations.

### 3.12 Basic Assignment and Expressions

AdaScript expressions can contain the following operators:

- uniary: +, -, not
- exponentiation: **
- arithmetic: +, -, *, /, & (string concatenation), rem (remainder), mod (modulus), and (bitwise and), or (bitwise or), xor (bitwise xor), * (string duplication)
- relational: =, /= (not equals), >=, >, <=, <, in, not in
- boolean: and, or, xor

The bitwise operators are identical to the boolean operators: BUSH choses which to use on the context of the expression.

Assignment (:=) is a statement, not an operator, and cannot be used in expressions.

`=> x := 5 * ( 7 + 2 );`
`=> s := "hello " & "there!";`

"in" and "not in" test for membership in a range. (In Ada, the range can be a type but under AdaScript types have no bounds.) The range can be an pair of numbers or a pair of enumerated items.

`=> b := green in red..blue;`
`=> b := 5 not in 10..20;`

### 3.13 The @ and % Operands

AdaScript provides a self-referential operand. "@", pronounced "itself", returns the value of the variable on the left side of an assignment statement. Use @ to save yourself unnecessary typing.

`=> total := @ + 1; -- total := total + 1;`

(An operand is used instead of C-style "+=", "-=", and so forth because it's much more resilient to typos. Leaving out the "@" or transposing it with the ":=" or "+" will result in a syntax error. In C, these mistakes usually result in legal assignments.)

`=> result := 10 - @; -- impossible with C-style shortcuts`

When assigning a value to an array, @ refers to the array item being assigned, not the entire array.

`=> zebra_population( 1966 ) := @+1; -- add 1 to 1966 population`

AdaScript provides a last output operand. "%", pronounced "last output", returns the last put_line (or ?) value. This is similar to Python's last output operand.

`=> put_line( 5*2 )`
`10`
`=> put_line( %+5 )`
`15`

The type of the last output is remembered.

`=> put_line( 5 )`
`5`
`=> put_line( % & " is a good number" )`
`put_line( % & " is a good number" );`
`^ type universal_numeric is inherently different from a universal_string`

Use % for quick calculations at the command line.

### 3.14 Command Argument Shortcuts

Parameters to the script are available using the built-in command_line package. However, for compatibility, the Bourne shell syntax can also be used:

- `$?` - the status code for the last shell command executed
- `$0` - the script name (not completely implemented)
- `$1 - $9` - up to 9 arguments given to this script
- `$#` - the number of arguments
- `$$` - the PID of this program, primarily used to uniquely name temporary files

If there are more than 9 arguments, they can be accessed with the command_line package.

The Bourne shell form are intended as command line shortcuts and the command_line package should normally be used in a well-structured script.

`rm ("/tmp/temp." & $$)`
`if $? /= 0 then`
`put_line( standard_error, "unable to delete temp file" );`
`end if;`

The status code of the last command executed is returned from a script when it finishes executing. A specific status code can be returned using the command_line package.

### 3.15 Redirection and Pipelines

There are several operands that control input/output redirection.

- `> f` - redirect standard output to file f, creating or overwriting f (not allowed in a restricted shell)
- `>> f` - redirect standard output to file f, appending to f
- `< f` - redirection input from file f
- `2> f` - redirect error output to file f, creating or overwriting f (not allowed in a restricted shell)
- `2>> f` - redirect error output to file f, appending to f
- `2>&1` - redirect error output to standard output (must appear after a standard output redirection to redirect both to the same file)

The redirection operands should appear after the command.

`=> ls > list_output.txt 2> list_errors.txt`

The redirect operands are considered to be a command line convenience. More powerful redirection is possible using the Text_IO package.

Command pipelines are created by connecting one or more commands using the pipe (|) symbol.

`=> ls | grep ".txt"`

The result from a command pipeline is the result of the last command in the pipeline. Pipelines can only have one input redirection (for the first command), one output redirection and one error redirection (for the final command). Pipelines cannot be run in the background using &.

### 3.16 Command Line Interaction

BUSH recognizes the Linux console arrow keys and common key sequences for the "emacs" and "vi" text editors. The sequences are called key bindings and represent cursor movement and editing functions.

The emacs mode key bindings are:

- control-b - move back (left) one character
- control-f - move forward (right) one character
- control-p - move to the previous command line you typed
- control-n - move to the next command line you typed
- control-x - erase the command line
- control-a - move to start of the line
- control-e - move to end of the line
- control-r - search command lines (history) backwards
- control-] - character search forwards. (Follow with the key to search for.)
- tab - complete the filename
- backspace/delete - delete a character

BUSH remembers up to 40 command lines for the current session, and you can cycle through them using control-p and control-n.

Typing a control-c (sending a SIGINT signal) at the command prompt acts the same as a control-x. Pressing control-c while a script or command is running will cause it to stop.

If you prefer to use vi cursor movement instead, press the escape key to enter vi mode. Press escape again to return to emacs mode. In vi mode, you can use lower-case 'h', 'j', 'k', 'l', '^' and '$'. Filename completion is accomplished with two escape key presses in a row.

### 3.17 Interactive Statements

Interactive sessions refer to a user typing commands at the BUSH command prompt. AdaScript has a number of built-in statements to be used in interactive sessions:

- help - shows summaries of BUSH commands
- env [ident or keyword] - shows a list of all declared identifiers, their types and properties, or the properties of a particular identifier
- trace [ boolean ] - turn execution tracing on or off. trace by itself shows the current status
- unset ident - delete an identifier from the symbol table. Keywords can't be unset, but standard identifiers can. For example, "unset false" works, but "unset if" does not.
- typeset - change the type of a variable, declaring it if necssary
- logout - stop an interactive, login session and leave the BUSH shell
- clear - reset the display and clear the screen

Interactive sessions behave slightly differently than scripts. First, in an interactive session, the ending semi-colon is optional. If it is missing, BUSH will append a semi-colon before executing the command. If an error occurs, the entire line will be shown, including the extra semi-colon.

Second, compound statements (statements that enclose other statements) can be used provided that the complete statement appears on a single line. Semi-colons will have to be placed after every command except the final command.

`=> for i in 1..5 loop put_line( i ) ; end loop`
`1`
`2`
`3`
`4`
`5`

A semi-colon isn't required after the first "loop" because the "for" statement is a compound statement ending with "end loop"--the semi-colon is only required after the final keyword in a compound statement. In this case, the final keyword is also the last keyword on the command line and the semi-colon is optional.

During an assignment, if the variable being assigned isn't declared, it's automatically declared unless pragma ada_95 or pragma restriction( no_auto_declarations ) is used. The type of the variable is the type of the expression being assigned.

`=> y := numerics.sqrt( 9 )`
`=> (Assuming y is a new universal_numeric variable)`

External commands can be grouped into pipelines using the vertical bar character (|). Pipelines are a command line convenience feature and are not intended for use in scripts (this is true in other Linux shells as well).

Interactive sessions can only be terminated with the logout command.

### 3.18 The Current Directory

There are two built-in BASH-style commands for managing your current directory:

- pwd - prints the present working directory
- cd - changes the current directory. The tilde, '~', represents your home directory. The minus sign, '-', represents your previous directory.

The cd command ignores the value of a CDPATH variable.

### 3.19 Database Commands

BUSH understands basic SQL commands. This feature is a great convenience for people who work frequently with databases. The SQL command parameters are given directly to your database. BUSH recognizes the following SQL commands:

- alter - alter a database table
- delete - delete a row from a database table
- insert - add a row to a database table
- select - show the results of a database query
- update - edit a row in a database table

SQL is a different language from AdaScript and the Bourne shell. SQL for one database may not be compatible with another. For example, an asterisk (*) will not expand to a list of files and quote marks indicate strings or table names, not how to expand dollar variables. Your database documentation will explain how to use your version of SQL.
BUSH submits the SQL command to the database with only one change. Bush will search command for variables and will substitute values using a dollar sign ($) and escape characters with a backslash. Single and double quotes have no effect on how the variable is substituted since quote marks used for a different purpose in SQL.
Like a shell command, the output from the database commands can be redirected or captured using backquotes. The commands can be intermixed with the db package database commands.
For example,
=> db.connect( "ken" )
=> select * from users
name | age
-------+------
ken | 38
dan | 37
chris | 40
kati | 36
4 Rows and 2 Columns
=> select * from users where user \> 'dan'
name | age
-------+------
ken | 38
kati | 36
2 Rows and 2 Columns
=> select count(*) from users > temp.tmp
=> cat temp.tmp
count
-------
4
=> s : string := `select age from users;`
=> k := "ken"
=> (Assuming k is a new universal_string variable)
=> select * from users where name = '$k'
name | age
------+------
ken | 38
=> db.disconnect
The format of select statements is the same as db.show in the db package.
Some limitations on database commands:

- Database commands cannot (yet) be used in a pipeline
- BUSH interprets <, >, >>, $, quotes and other symbols (escape them when necessary using \)
- Database commands cannot be used with pragma ada_95 (use the db library instead)

### 3.20 Flow of Control

if statements are used for conditional branching.

`if x > y then`
`put_line( "x is greater than y" );`
`elsif x = y then`
`put_line( x is equal to y" );`
`else`
`put_line( x is less than y" );`
`end if;`

The case statement can test a variable for several different values.

`type country is ( australia, u_k, brazil );`
`...`
`case c is`
`when austraila =>`
`put_line( "Australia" );`
`when u_k =>`
`put_line( "United Kingdom" );`
`when brazil =>`
`put_line( "Brazil" );`
`when others =>`
`put_line( "Unexpected country" );`
`end case;`

Multiple cases can be strung together using a vertical bar (|).

`when brazil | u_k => -- brazil or U.K.`

The "when" cases must not be variables (although constants are OK). The "when others" case is always required.

The while loop is a pre-test loop. The commands in the loop are repeat while the condition is true and the condition is tested each time the first line of the loop is executed.

`while x > y loop`
`x := @ + 1;`
`end loop;`

The for loop increments its index variable by 1 until it iterates through the specified range. The index variable is automatically declared for you and only exists for the scope of the the loop. The range can either be numeric or enumerated.

`for i in 1..10 loop`
`put( "i is " );`
`put_line( i );`
`end loop;`

To loop in reverse in a for loop, use "in reverse" instead of "in".

Any loop can be exited by using either an exit statement or an "exit when" shorthand.

`if x > 100 then`
`exit;`
`end if;`

`exit when x > 100;`

A "loop" loop is a general purpose loop. It can only be exited with "exit".

`loop`
`reply := get_line;`
`exit when reply = "exit";`
`end loop;`

### 3.21 Other Statements/Subprograms

The null statement, "null", doesn't do anything.
The delay statement, "delay", will delay for a specific number of seconds.
The return statement will unconditionally terminate the script, procedure or function. Functions must have a return value.
The system command will give a string to your default shell to execute as a shell command.

`null; -- do nothing`
`delay 2.5; -- wait 2 1/2 seconds`
`system( "date" ); -- execute the Linux date command`
`return; -- quit the program`

### 3.22 External Commands

The purpose of an AdaScript script is, ultimately, to execute shell commands. Any command not understood by AdaScript as a command is assumed to be a shell command. For example,

`=> echo`

will run the Linux echo command and print a blank line to the screen, the same as new_line.

Commands are accepted in one of two different formats. If the command is followed by a "(", the parameters are expected to be in AdaScript format with each parameter separated by a comma (","). These parameters may be any legitimate AdaScript expression and no shell quote removal or file globbing is performed.

`=> ls( "bush.adb" )`
`bush.adb`

If the command is not followed by a "(", the parameters are expected to be in Bourne shell format. This is provided for convenience in interactive sessions. The parameters are shell "words" separated by spaces. Each word has file globbing performed. The words may be enclosed in double quotes to allow embedded spaces, or single quotes to inhibit file globbing. Special characters may also be escaped with backslashes.

`=> ls b*.adb`
`builtins.adb bush.adb`

Bush can insert the values of variables using BASH-style "$" substitutions. "ls $HOME" will show the contents of your home directory.

Command names containing space characters can be quoted with double quotes.

`=> "inventory report"`

When pragma ada_95 is used, shell commands must only use the AdaScript parameter format.

External commands can be run in the background using an ampersand ("&") at the end of the command. With AdaScript parameters, place the ampersand after the closing parenthesis. The jobs command displays the status of any outstanding background commands.

The built-in shell commands are listed in a section above. when a Linux command conflicts with a built-in command, the Linux command can be executed using the command command.

The results of a command can be captured as a string using backquotes. The commands should be ended with a semi-colon. Commands appearing in backquotes will be syntax checked along with the rest of the commands in a script.

`=> date : string := `date;``

If there is a trailing line feed (or carriage return/line feed for Windows) it will be removed.

Standard input, standard error and standard output can be redirected using the Text_IO package.

### 3.23 Block Statements and Subprograms

Bush scripts can be organized using declare blocks, procedures and functions.

Declare blocks allow variables to be declared in the executable part of a script. A new block can be created without declaration any variables by using begin...end without the declare section.

declare
i : integer := 5;
begin
? i;
end;

Repeatable blocks of instructions (like Perl sub or Python def) can be created with the word procedure or function. A procedure is a set of instructions with a name. A function is a set of instructions with a name that returns a value so it can be used in an expression. Like a declare block, local variables can be declared before the word begin.

Procedures and functions cannot be forward declared (yet) as there is no way to handle forward parameters (yet).

procedure print_title is
begin
put_line( "Script to Process New Orders" );
new_line;
end print_title;

Both procedures and functions can have parameters. The parameters are what Ada refers to as "in" parameters: they give additional information to a subprogram and are treated as constants. The word "in" is optional before the type of parameter.

function add_two( number : integer ) return integer is
begin
return number+2;
end add_two;

### 3.24 TCP/IP Sockets

Network sockets can be declared using socket_type variables. Most of the file I/O functions will work with sockets as well as files.

The main difference between a socket and a file is that sockets are always "in" and "out". When opening a socket, do not specify a mode.

The name of the socket is a string containing the name of the server computer, followed by a colon and a port number. The port number is 80 (a web server) if no port is specified. Certain ports, such as those above 32767, are prohibited as a security precaution.

`#!/bin/bush`
`-- download a web page`

`f : socket_type;`
`c : character;`

`open( f, "www.somewebserver.com" );`

`put( f, "GET /index.html HTTP/1.0" & ASCII.CR & ASCII.LF );`
`put( f, "User-Agent: BUSHTest/1.0 (BUSHTest)" & ASCII.CR & ASCII.LF );`
`put( f, ASCII.CR & ASCII.LF );`

`loop`
`get( f, c );`
`put( c );`
`exit when end_of_file( f );`
`end loop;`

`put_line( "End of web page" );`
`close( f );`

### 3.25 Numeric Formatting with Put

BUSH offers numeric formatting for numbers up to 18 digits and 4 decimal places. Formatted numbers are written with the put command, not put_line. Following the number, provide a formatting picture string describing how the number should be formatted.

The picture string may include:

- `'+'` - the number will be printed with a leading + or -
- `'-'` - a negative numbers will be printed with a leading -
- `'<'` and`'>'` - a negative number will be printed with (..)
- `"CR"` - a negative number will be printed with a leading "CR" (credit)
- `"DB"` - a negative number will be printed with a leading "DB" (debit)
- `'$'` - the currency symbol will be printed, or a floating dollar sign if multiple instances
- `'.'` - marks the actual position for a decimal point
- `'V'` - marks the assumed position for a decimal point
- `'9'` - space for a number with leading zeros
- `'#'` - same as '$', except only the leading character is shown
- `'Z'` - space for a numbers with leading blanks
- `'_'`, `'B'`, `'0'`, `'/'`- inserted. 'B' is a blank
- `'*'` - space for a number with leading asterisks

Here are a few examples.

`=> put( 12.34, "***9.99" ) ; new_line`
`**12.34`
`=> put( 12.34, "###9.99" ) ; new_line`
`$12.34`
`=> put( 12.34, "+###9.99" ) ; new_line`
`+ $12.34`
`=> put( 12.34, "-###9.99" ) ; new_line`
`$12.34`
`=> put( 12.34, "<###9.99>" ) ; new_line`
`$12.34`
`=> put( -12.34, "<###9.99>" ) ; new_line`
`( $12.34)`

###

### 3.26 Interpreter Directives

Pragmas, or interpreter directives, provide additional instructions to AdaScript.

- pragma ada_95 - requires the script syntax be as close to Ada 95 as possible, otherwise errors will occur.
- pragma annotate( "text" ) - embed a comment. The contents of any or all annotate pragmas are shown when you use the help command on a script.
- pragma assert( expression ) - evaluates the expression. If it isn't true, the program stops and "assertion failed" is displayed. Requires --debug option or asserts will have no effect.
- pragma debug( `commands` ) - these are a set of debugging commands to run when debugging is turned on with --debug. Make sure the final command ends with a semi-colon. Without a parameter, same as --debug (turn on debugging).
- pragma deprecated( "newscript" ) - another name for pragma depreciated.
- pragma depreciated( "newscript" ) - when script finishes execution, BUSH will warn that the script is obsolete and has been superceded for "newscript".
- pragma export( shell, var ) - export a string variable to the O/S environment. The first parameter must be "shell".
- pragma gcc_errors - same as --gcc-errors. Show simplified gcc-style errors.
- pragma import( shell | cgi, var ) - import a shell or environment variable as a Bush string variable. If the environment variable doesn't exist, BUSH will report an error (see unchecked_import). The first parameter must be "shell".
- pragma inspect( var ) - show a variable's description (as if 'env var' was used) whenever a user breaks to a command prompt. Has no effect if --break option isn't used.
- pragma inspection_point - break to a command prompt as if SIGINT (control-C) was received. Has no effect if --break option isn't used. A "breakpoint".
- pragma no_command_hash - Bush normally remembers the location of a command once it has found it. This pragma forces Bush to search for the location of the command, ignoring the previous location.
- pragma prompt_script( `commands` ) - commands to draw the command prompt. If the string is an empty string, the default "=>" prompt is used. Make sure the final command ends with a semi-colon. Changing your prompt will also change the title of your terminal window.
- pragma restriction( no_auto_declarations ) - disable automatic declaration at the command prompt
- pragma restriction( no_external_commands ) - disable operating system commands. Provides portability by ensuring no commands besides BUSH's built-in commands are executed. Useful for applications using BUSH as a run-time scripting language and not for shell scripting.
- pragma template( text|html [, template] ) - BUSH will act like an HTML template processor (like PHP). When the script finishes executing, BUSH will open a file called "file.tmpl" where file is the name of the script. If an alternate file path is included in the pragma, that file is used as the template instead. A HTTP header is written and BUSH parses the template along with any embedded scripts. For security, the embedded scripts in the template will be run in a restricted shell and with the no_external_commands restriction. Errors are shown in --gcc-errors format using the line number in the template as the line number for the error. The first parameter is the template type: "text" or "html".
- pragma unchecked_import( shell | cgi, var ) - import a CGI or environment variable as a BUSH string variable. If the environment variable doesn't exist, then the BUSH variable is unchanged. The first parameter must be "shell".
- pragma uninspect( var ) - undo a pragma inspect. Don't show a variable's description whenever a user breaks to a command prompt. Has no effect if --break option isn't used.
- pragma unrestricted_template( text|html [, template] ) - BUSH will act like an HTML template processor (like PHP). This pragma is the same as pragma template except that the embedded scripts are executed in a normal shell with no security restrictions.
- pragma volatile( var ) - the variable is assumed to be an environment variable which may change during the script's execution. The variable's value will be updated each time it is referenced in an expression. Only makes sense if the variable is imported as well.

### 3.27 Command Line Options

There are several command options for BUSH.

- --break (or -b) - allow breakout to a shell prompt on a SIGINT or a script error. (e.g. a control-c will give you a shell prompt.) Use "return" to continue execution or "logout" to terminate script.
- --check (or -c) - check the syntax of a script but do not run the script
- --debug (or -d) - enable pragma debug's and assert's. Without this, the pragmas have no effect.
- --exec (or -e) - the script path is not a path but a script to execute.
- --gcc-errors (or -g) - show simple gcc-style error messages to be compatible with smart editors and IDEs. Also disables bold and inverse printing in error messages.
- --help (or -h) - show help on command line options
- --import-all (or -n) - declare and import all environment variables when BUSH starts
- --login (or -l) - simulate a login shell
- --no-check (or -n) - run without checking the syntax first
- --restricted (or -r) - run as a restricted shell.
- --trace (or -x) - same as "trace true". Turn on tracing.
- --verbose (or -v) - show interpreter progress
- --version (or -V) - show version of BUSH and exit
- -- - explicitly end of shell options

### 3.28 Command Reference

Here is a list of the AdaScript built-in commands and statements. Commands found in the built-in packages are documented in Part 4.

begin

see declare

case

Syntax: case var is when constant|literal => ... when others => ... end case
Description: Test a variable for multiple values. "when others" case is required.

cd

Syntax: cd - | dirname
Description: change directory. "-" is the previous directory. A leading '~' is your home directory.

clear

Syntax: clear
Description: reset tty device and clear the screen

close

Syntax: close( file )
Description: close an open file

command [prior to Bush 1.0]

Syntax: command cmd
Description: run a Linux command (instead of a built-in command).

create

Syntax: create( file [, out_file | append_file] [, path ] )
Description: create - create a new file or overwrite an existing file. The default type is out_file. The default path a temporary file name.

declare

Syntax: [declare declarations] begin ... end
Description: begin a new block

delay

Syntax: delay secs
Description: wait (sleep) for a specific time

delete

Syntax: delete( file )
Description: close and delete a file

end_of_file

Syntax: end_of_file( file )
Description: true if an in_file file has no more data

end_of_line

Syntax: end_of_line( file )
Description: true if an in_file file has reached the end of a line with get

else

see if

elsif

see if

env

Syntax: env or env identifier or env (identifier)
Description: show a table of all identifiers, or identify an identifier or keyword.

exit

Syntax: exit | exit when condition
Description: break out of a loop

for

Syntax: for var in [reverse] first..last loop ... end loop
Description: for loop - loop through between first and last assigning value to var. The for starts a new block and the for variable is automatically declared based on the type of first.

get

Syntax: get( [file,] var )
Description: read a character from a line of text.

get_line

Syntax: var := get_line [ (file) ]
Description: read a line of text

history

Syntax: history -c | history [n]

Show or clear the interactive command history. If n, show the n most recent interactive commands.

if

Syntax: if expression then ... [elsif expr then ...] [ else ...]
Description: conditional execution

inkey

Syntax: c := inkey
Description: read a character from standard input without echoing

is_open

Syntax: is_open( file )
Description: true if file is open

jobs

Syntax: jobs
Description: list status of current background jobs

line

Syntax: line( file )
Description: the number of read/written lines

logout

Syntax: logout
Description: terminate an interactive login session

loop

syntax: loop ... end loop
Description: General loop. exit with an exit statement.

mode

Syntax: mode( file )
Description: the file mode (in_file, out_file, append_file)

name

Syntax: name( file )
Description: name of an open file

new_line

Syntax: new_line [(file)]
Description: start a new line

null

Syntax: null
Description: do nothing

open

Syntax: open( file, in_file | out_file | append_file, path )
Description: open an existing file or open a socket

pragma

interpreter directive

put

Syntax: put ( [file], expression [, picture] )
Description: write to output, no new line. If picture is included, format the number according to the picture.

put_line

Syntax: put_line ( [file], expression )
Display: write to output and start new line

pwd

Syntax: pwd
Description: present working directory

reset

Syntax: reset( file [,mode]
Description: reopen a file

return

Syntax: return [status code]
Description: exit script and return status code

set_input

Syntax: set_input( file ), set_output( file ), set_error( file )
Description: input/output redirection

skip_line

Syntax: skip_line [(file)]
Description: discard the next line of input

subtype

Syntax: subtype newtype is oldtype
Description: create an alias for a type

system

Syntax: system( commandstring )
Description: run a BASH shell command

trace

Syntax: trace [true | false]
Description: show verbose debugging information

typeset

Syntax: typeset var [is type]
Description: change the type of a variable, declaring it if necessary. Cannot be used in scripts or with pragma ada_95.

unset

Syntax: unset ident or unset (ident)
Description: delete an identifier. Cannot be used in scripts or with pragma ada_95.

wait

Syntax: wait
Description: wait for all background commands to finish.

while

Syntax: while condition loop ... end loop
Description: while loop - repeat the loop until the condition is false

?

Syntax: ? expression
Description: put_line to standard output. Cannot be used with pragma ada_95.

### 3.29 ASCII Character Set

The ASCII character set is represented by the ASCII enumerated type.

ASCII.NUL - control-@
ASCII.SOH - control-A
ASCII.STX - control-B
ASCII.ETX - control-C
ASCII.EOT - control-D
ASCII.ENQ - control-E
ASCII.ACK - control-F
ASCII.BEL - control-G
ASCII.BS - control-H
ASCII.HT - control-I
ASCII.LF - control-J
ASCII.VT - control-K
ASCII.FF - control-L
ASCII.CR - control-M
ASCII.SO - control-N
ASCII.SI - control-O
ASCII.DLE - control-P
ASCII.DC1 - control-Q
ASCII.DC2 - control-R
ASCII.DC3 - control-S
ASCII.DC4 - control-T
ASCII.NAK - control-U
ASCII.SYN - control-V
ASCII.ETB - control-W
ASCII.CAN - control-X
ASCII.EM - control-Y
ASCII.SUB - control-Z
ASCII.ESC - Escape key
ASCII.FS
ASCII.GS
ASCII.RS
ASCII.US
ASCII.DEL - ASCII 127, delete key
ASCII.Exclam - "!"
ASCII.Quotation - """"
ASCII.Sharp - "#"
ASCII.Dollar - "$"
ASCII.Percent - "%"
ASCII.Ampersand - "&"
ASCII.Colon - ":"
ASCII.Semicolon - ";"
ASCII.Query - "?"
ASCII.At_Sign - "@"
ASCII.L_Bracket - "["
ASCII.Back_Slash - "\"
ASCII.R_Bracket - "]"
ASCII.Circumflex - "^"
ASCII.Underline - "_"
ASCII.Grave - "`"
ASCII.L_Brace - "{"
ASCII.Bar - "|"
ASCII.R_Brace - "}"
ASCII.Tilde - "~"
ASCII.UC_A - "A"
...
ASCII.UC_Z - "Z"
ASCII.LC_A - "a"
...
ASCII.LC_Z - "z"

### 3.30 Common Error Messages

@ is not allowed with pragma ada_95 - @ (itself) is not an Ada 95 feature. Fill in the actual variable name.
% is not allowed with pragma ada_95 - % (last output) is not an Ada 95 feature.
$# not allowed with pragma ada_95 - $# is not an Ada 95 feature. Use the command_line package instead.
$0 not allowed with pragma ada_95 - $0 is not an Ada 95 feature. Use the command_line package instead.
$1..$9 not allowed with pragma ada_95 - $1 to $9 are not an Ada 95 feature. Use the command_line package instead.
absolute paths to commands not allowed in restricted shells - absolute paths are a security risk because they allow a restricted shell or script to run any command (provided they have permission to do so).
access to this TCP/IP port is prohibited - certain URL port numbers are reserved for special functions or are non-standard across different operating systems. Choose a different port number.
alias isn't supported - since BUSH has no access types, the Ada keyword alias isn't supported by BUSH.
already declared - the name is already defined in the symbol table as something else
assertion failed - the condition for the assert pragma evaluated to false.
boolean expression expected - BUSH was expected something that equates to "true" or "false" but found something else instead. For example, "if 2+2 then". Check your expression.
boolean operator expected - BUSH was expecting a AND, OR or XOR. Usually indicates something is missing in the command.
Bourne shell-style parameters not allowed with pragma ada_95 - Bourne shell parameters are not a feature of Ada 95. Use Ada-style parameters instead.
Break - a pragma inspection_point was encountered, or the program was interrupted with control-c (SIGINT).
cannot create an in file - a file must first have data written to it before it can be read. You cannot read a newly created file.
cd is not allowed in a restricted shell - cd is a security risk because the user or script can run different commands if they change their current directory.
character literal more than 1 character - single quotes denote a character literal such as 'a' or '1'. Double quotes denote strings of more one or more characters.
command types not allowed with pragma ada_95 - command types are not a feature of Ada 95. Try implementing them as strings.
command variables must be constant - commands can only be declared as a constant.
create not allowed in a restricted shell - restricted shells and scripts cannot create new files.
current directory not assessible / doesn't exist - your current directory was deleted or had its permissions changed.
else without if - BUSH is unable to find the if that belongs to your else. Check the structure of your if's.
elsif without if - same as above. end of file - your program has attempted to read past the end of the file
end_of_file only applies to in_mode files - the end_of_file function only applied when reading files. When writing or appending to files, you are always at the end of file.
exception raised - the operation was not permitted. For example, dividing by zero or doing arithmetic with a variable that has no value.
file already open - the file_type variable was already opened by open or create but it must be closed before it is reopened.
file not open - the file_type variable hasn't been opened yet with open or create.
file_type expected - BUSH was expected a file_type variable in an open, create, etc. command. Check the type and order of your parameters.
file_type or socket_type variable expected - same as above.
functions not implemented - user-defined functions are not yet implemented
invalid based numeric literal - usually specifying a base and using number characters larger than the base allows
is not an executable command - the command cannot be found or you do not have permission to run it.
limited types cannot be assigned a value - limited types are assigned values by BUSH. They cannot be assigned values.
missing statement or command - block statements must contain statements or commands. Use the null command if there are no statements or commands.
no & - final piped command always runs in the foreground - the last command in a pipeline cannot have a & (run in background). (This is also true in BASH.)
no & - piped commands are automatically run the the background - commands being piped don't need a & (run in background) since they must always run in the background. The & is implicit.
no enclosing loop to exit - exit was used while not in a loop. If you want to quit an interactive session, use logout.
no such argument - the $1..$9 you are referning to doesn't exist.
not declared - the name has not been defined in the symbol table. Often indicates a spelling mistake
number format picture string expected - the put appears to be a formatted put, but there is no format picture or the picture isn't a string.
number not a valid format picture - the number cannot be displayed using the format picture string. For example, the number is too big.
numeric or enumerated type expected - for loops can only loop over numeric or enumerated ranges. For example, for s in "a".."z" loop is a string range.
only numeric types can use a format picture - Only numeric values can be put with formatting. Strings or other types cannot be used.
operation (something) not defined for these types - In this context, the arithmetic operation doesn't make sense. For example, using ** for two strings.
operation not defined for string types - for example, attempting to multiply two strings
operator expected - BUSH was expected an arithmetic operator like +. Usually indicates something missing in the command.
out_file mode not allowed in a restricted shell - files cannot be overwritten in restricted scripts or shells.
packages not implemented - user-defined packages are not yet implemented
pathname should not be null - empty pathnames ("") are now allowed. Omit the pathname if you want BUSH to create a temporary name, or check your string to find out why the pathname is missing.
pipelines are not allowed with pragma ada_95 - pipelines ("|") are not a feature of Ada 95. Use pipe files or share the results using a temporary file.
possible type of - the name has not been defined in the symbol table but appears to be similar to the spelling of another, defined name.
procedures not implemented - user-defined procedures are not yet implemented
protected types not implemented - AdaScript doesn't implement Ada's protected types because there is no multithreading.
return cannot return a status code with pragma ada_95. use command_line package - Bourne shell's return can return a status code, but Ada's return does not permit a status code.
sockets don't have a mode - socket_type variables are always in and out simultaneously. Don't specify a mode.
standard_input (or output or error) cannot be assigned to (output or input) - standard input can only be read. Standard output and error can only be written.
tasks not implemented - AdaScript doesn't implement Ada's tasks or task types because there is no multithreading.
this file is the current (input/output/error) file - you cannot close standard input, output or error. For example, BUSH will not allow you to close the keyboard in an interactive session.
this is not an interactive shell--use return - logout is not permitted in scripts because you are not "logged in".
too many identifiers (symbol table overflow) - BUSH has no space to declare any more identifiers. Your program has too many variables declared. Try breaking up the variables with declare blocks.
too many nested statements (block table overflow) - there are too many nested block statements. For example, very many if statements with no end if.
type name expected, not a number - for example, expected integer but found a 14 insteadtype name expected, not a string literal - for example, expected integer but found "hello world!" insteadtype name expected, not a keyword - for example, expected integer but found then insteadtype name expected, not a symbol - for example, expected integer but found a semicolontypeset is not allowed with pragma ada_95 - typeset is not a feature of Ada 95. Use a different variable with a new type.
typeset is only allowed in an interactive session - typeset is an interactive session convenience. It is not intended for use in scripts because it makes scripts difficult to read.
unable to allocate memory to call command - your system is out of (virtual) memory.
unable to open file - the operating system report a problem while opening the file. For example, you may not have permission to open the file or the file has been locked by someone else.
unable to interpret TCP/IP host - the format of the URL is wrong. For example, a missing hostname may cause this error.
unable to interpret TCP/IP port - the format of the URL is wrong. For example, a colon without a port number may cause this error.
unable to open socket - BUSH was unable to establish a socket to the URL. For example, your Internet connection may be down or the host name is spelled wrong.
unable to delete file - the operating system reported a problem while deleting the file. For example, the file may have been deleted by someone else already.
unable to read file - the operating system reported a problem while reading the file. For example, the file may have been deleted by someone else.
unable to set input (or output or error) - the operating system reports that the file cannot be made into the current source of input or output.
unable to write file - the operating system reported a problem while writing the file. For example, the file may have been locked by someone else to prevent writing.
unexpected arguments after & - when a command is run in the background using &, the & must be the last symbol.
universal/typeless types not supported by pragma ada_95 - universal types are not a feature of Ada 95. Use other types instead.
unset is not allowed with pragma ada_95 - unset is not an Ada 95 feature.
unset only allowed in interactive sessions - unset cannot be used in scripts. It is a interactive session convenience.
unsetting PATH is not allowed in a restricted shell - changing PATH is a security risk because it changes what programs can be run from the restricted shell or script.
use not implemented - this Ada command is not yet implemented.
variable/value expected - BUSH found a keyword but was expecting a variable or a literal. Usually indicates something missing in the command.
variable not allowed as a case - in a case statement, when cases cannot contain variables.
warning: This is an interactive shell. Use logout. - Use logout to stop an interactive session, not return.
when others expected - case statements must always have a when others part.
with not implemented - this Ada command is not yet implemented.

### 3.31 Common PHP Functions and the BUSH Equivalent

    Arrays

              PHP          BUSH Equivalent
              array_sum    arrays.sum
              asort        arrays.bubble_sort
                           arrays.heap_sort
              count        arrays.length
              shuffle      arrays.shuffle
              rsort        arrays.bubble_sort_descending
                           arrays.heap_sort_descending

    Numbers

              PHP          BUSH Equivalent
              abs          abs
              acos         numerics.arccos
              acosh        numerics.arccosh
              asin         numerics.asin
              asinh        numerics.asinh
              atan         numerics.atan
              atanh        numerics.atanh
              base_convert #base#
                           put
              bindec       #base#
                           put
              ceil         numerics.ceiling
              cos          numerics.cos
              cosh         numerics.cosh
              decbin       #base#
                           put
              dechex       #base#
                           put
              decoct       #base#
                           put
              deg2rad      use appropriate cycle
              exp          numerics.exp
              floor        numerics.floor
              fmod         numerics.remainder
              hexdec       #base#
                           put
              log10        numerics.log
              log          numerics.log
              max          stats.max
                           numerics.max
              min          stats.min
                           numerics.min
              octdec       #base#
                           put
              pi           numerics.pi
              pow          **
              rad2deg      use appropriate cycle
              rand         numerics.random
                           numerics.rnd
              round        numerics.rounding
                           numerics.unbiased_rounding
              sin          numerics.sin
              sinh         numerics.sinh
              sqrt         numerics.sqrt
              tan          numerics.tan
              tanh         numerics.tanh

    Strings

              PHP          BUSH Equivalent
              chr         strings.val
              substr_count strings.count
              echo        put
                          put_line
                          new_line
              explode     strings.field
                          strings.lookup
                          strings.csv_field
                          strings.delete
                          strings.insert
              implode     strings.replace
                          strings.csv_replace
                          strings.delete
                          strings.insert
              ltrim       strings.trim
              md5         strings.md5
              rtrim       strings.trim
              ord         strings.pos
              printf      put
              strpos      strings.index
              str_pad     strings.head
              str_repeat  *
              str_replace strings.replace
                          strings.replace_slice
                          strings.delete
                          strings.insert
              strstr      strings.pos
              strchr      strings.pos
              substr      strings.head
                          strings.tail
                          strings.slice
                          strings.element
              strlen      strings.length
              trim        strings.trim
              strtolower  strings.to_lower
              strtoupper  strings.to_upper
              locateconv  strings.to_basic
              ucwords     strings.to_proper
              wordwrap    strings.split