Home Page | Introduction | Tutorials | Reference | Packages | Hacking |
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.
Ada is case-insensitive and programs may need to have the
capitalization
of keywords changed to fit the case expected by AdaScript.
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 |
return 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.
=> ? 16#FFFF#
65535
Characters are enclosed in single quotes.
Strings are enclosed in double quotes.
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 |
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.)
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.
=> 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
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.
=> 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.
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.
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.
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;
=> 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.
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.
=> 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
&.
The emacs mode key bindings are:
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.
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.
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;
null; -- do nothing
delay 2.5; -- wait 2 1/2 seconds
system( "date" ); -- execute the Linux date command
return; -- quit the program
=> 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.
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;
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 );
The picture string may include:
=> 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)
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.
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"
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