Home Shark Introduction Shark Reference Guide Purchase Menu ☰

LIST OF SHARK FUNCTIONS:

A function is just like an operation; the addition operation (+) requires two arguments (numbers) and returns their sum; a function requires some arguments (0 to 3) and returns some value.

Every function has a type: numeric, string, or logical, depending on the values it returns.

A function has arguments; the values put into the function between the parentheses, separated by commas. Shark functions have at most three arguments; a few have none. Some arguments may be optional.

The arguments can be variables or expressions of type string: str var or str exp, or of type numeric: num var or <num exp>. (The details and inner workings of Shark functions can always be found in Shark Elements)

The available Shark functions:


!(
# (number)
$(
@(
ABS(
ACOS(
ASC(
ASIN(
ASTERISK (*)
AT(
ATAN(
BIT(
BLANK(
BOF
BOF(
CEIL(
CEN(
CHR(
CLOSE(
COL(
COS(
COSH(
CTONUM(
DATE(
DAYS(
DBF(
DBFX(
DELETED(
DESCEND(
DIR(
DIRF(
DIRX(
EOF(
EOF
EXP(
FIELD(
FILE(
FLD(
FLOOR(
GET(
IFF(
IFKEY(
IN(
INKEY(
INSERT(
INT(
LEFT(
LEN(
LOC(
LOG(
LOG10(
LOWER(
LTRIM(
MASK(
MAX(
MENU(
MIN(
MOD(
MONTHS(
NDX(
NTX(
NUMTOC(
OUT(
PIC(
POW(
PRINTER(
PUT(
RAND(
RANK(
READ(
RECNO(
REMLIB(
REPLACE(
RESET(
RIGHT(
ROPEN(
ROW(
SEEK(
SET(
SIN(
SINH(
SPACE(
SQRT(
SSEEK(
STR(
SUBSTR(
TAN(
TANH(
TEST(
TIME(
TRIM(
TYPE(
UPPER(
VAL(
WOPEN(
WRAP(
WRITE(
Within the above list are some specific Mathematical Functions. The mathematical functions may be divided into five groups::

Logarithmic functions:


EXP( e to the power <num exp>
LOG( natural logarithm of <num exp>
LOG10( base 10 logarithm of <num exp>
POW( <num exp1> to the power <num exp2>
SQRT( square root of <num exp>

Trigonometric functions:


SIN( sine of <num exp> in radians
COS( cosine of <num exp> in radians
TAN( tangent of <num exp> in radians
ASIN( arc sine of <num exp>; returns a value in radians between -𝜋/2 and 𝜋/2
ACOS( arc cosine of <num exp>; returns a value in radians between 0 and 𝜋
ATAN( arc tangent of <num exp>; returns a value in radians between -𝜋/2 and 𝜋/2

Hyperbolic functions:


SINH( hyperbolic sine of <num exp>
COSH( hyperbolic cosine of <num exp>
TANH( hyperbolic tangent of <num exp>

Integer-valued functions:


CEIL( ceiling integer: the integer equal to or just above a given number
FLOOR( floor integer: the integer equal to or just below a given number
INT( the integer part of a given number (the fractional part is discarded); useful for currency "rounding", for example.

Note that for positive numbers, INT( and FLOOR( return the same result, but for negative numbers, INT( and CEIL( also produce the SAME result. This is because discarding the decimal part of a real number reduces its distance from zero.

Real-valued functions:


ABS( displays the absolute value of <num exp>
MOD( evaluates remainder of a division of a <num exp> by a different <num exp>

Examples:

 
1>:PICTURE='999.999999'
1>? EXP(1)
  2.718282    ;this is the value of e
  
1>? LOG(3)
  1.098612
  
1>? LOG10(3)
  0.477121
  
1>? POW(2,4)
 16.000000
 
1>? POW(2,.5)
  1.414214
  
1>? SQRT(4)
  2.000000
  
1>? SQRT(2)
  1.414214
  
1>? SIN(2)      ;2 is in radians
  0.909297
  
1>? ASIN(1)
  1.570796
  
1>? 2*ASIN(1)
  3.141593      ; this is, of course, 𝜋; store this to a variable if you need 𝜋
  
1>? CEIL(3.14)
  4.000000
  
1>? FLOOR(3.14)
  3.000000
  
1>? INT(23.45)
 23.000000
 
1>? INT(-23.45)
-23.000000

1>x=23.45
1>? INT(10*x)
234.000000

1>x=23.999
1>? INT(x)
 23.000000
 
1>? INT(3.14)
  3.000000
1>? FLOOR(-3.14)
 -4.000000
 
1>? INT(-3.14)   ;note that for negative numbers, INT(  and FLOOR( give different values
 -3.000000 
 
1>? MOD(5,2)     ;this is the remainder of 5 divided by 2
  1.000000 
  
1>? MOD(-3.14, .7)
 -0.340000
 
1>? ABS(-3.14)
  3.140000
  
1>:PICTURE='9999999.99'

1>x=15.689

1>? INT(x*100+.5)/100      Note: this is an example of rounding to the nearest 1 cent
     15.69 
	 
1>x=15.244

1>? INT(x*100+.5)/100
     15.24


Within the above list of all functions are some specific Comparative Functions:


MASK(: Manipulates bits in a string based on comparison between 2 strings MAX(: Compare two expressions of any type and return the larger.



ALPHABETICAL LIST OF ALL SHARK FUNCTIONS:

!(

Converts a string to upper case.

!(<str exp>)

<str exp> is the text to be converted to upper case

Type: character

All lower-case letters in the <str exp> are converted into upper case by the !( function. See also the LOWER( function.

Examples:

1>a='Aa12b'
1>? !(a)
AA12B
1>? !('David!')
DAVID!

Note that only the lower-case letters are changed.

#

Gets the current record number.

#

Type: numeric

This function returns the record number of the current record of the selected file. Note that ? # displays the current record number in the form specified by the system variable :PICTURE (see Section 2.7). Shark also has a more general form of this function, RECNO(, which allows the user to specify a file other than the selected file.

When used with the option RECNO(filenum), it gives the record number of the current record in file filenum.

Examples:

1>USE employee
1>? #
     1.00
1>GO BOTTOM
1>? #
     6.00
1>GO TOP
1>? #
     1.00
1>SKIP 2
1>? #
     3.00
1>? recno(2); selects current record in file #2	 

$( (substring)

This is shorthand for the SUBSTR( function.

ASTERISK (*)

Determines whether a record is deleted. Type: logical

In the selected file, the current record pointer points at a record. If this record has been marked for deletion (in BROWSE or EDIT, or with the DELETE command), then * gives the value T; otherwise, it is false.

Example:

1>USE employee
1>DELETE RECORD 2
      1 DELETE(S)
1>GO 2
1>? *
T

Do not confuse this function with * command (NOTE), or with the * comment marker.

@( (at)

Gets the location of a substring.

@(find str exp, <str exp> [,start)

find str exp    the string searched for
<str exp>         the text to be searched

Option:

start byte position at which to start looking for find str exp within the string: <str exp>. If it occurs, the function returns the character position of the first (left-most) substring of <str exp> which is the same as find str exp; if it does not occur, the function returns a 0.

@( and its equivalent, the AT( function, can easily search for successive occurrences of a substring within a string.

Consider the previous paragraph. How many occurences are there of the substring "string"? How many of "s"? This function can determine the answer as follows if the paragraph is stored as a single string in the variable STR:

STR='@( and its equivalent, the AT( function, can easily search for successive occurrences of a substring within a string.

SUBSTR='s'
COUNT=0
START=0
LEN_STR=LEN(STR)
DO WHILE START<LEN_STR
   START=@(SUBSTR,STR,START+1)
   IF START>0
      COUNT=COUNT+1
   ELSE
      BREAK
   ENDIF
ENDDO

Be sure that start always advances; if it stays in the same place, it will perform the same operation indefinitely since it will never get to the end.

Ambitious programmers will have noted that, if substr is longer than one byte, start should begin at 1-LEN(SUBSTR) and advance each time by the length. Furthermore, the condition on the DO WHILE line should then be:

start<=len_str-len_sub

(assuming you've saved the length of the substring in this last variable).

Examples:

1>greeting='Good morning'
1>? @('oo', greeting)
      2.00
1>? @('good',greeting)
      0.00

In a program:

IF @(answer,'YNQynq')>0

checks whether the user response is correct.

This program segment finds and marks every occurrence of a specified string in a page of text displayed on the screen:

CLS                                ;start by erasing the screen
DO WHILE t                         ;set up continuous loop -break embedded in segment
   IF row()<mLineNumber            ;stop at end of screen
      IF .not. read(mPrintLine,1)  ;be sure there's more to display
         BREAK                     ;if not, break out of loop
      ENDIF
      ?? mPrintLine                ;display the line, no linefeed
      IF mText>' '                 ;if looking for input text
         mPrintLine=!(mPrintLine)  ;capitalize line from file
         mSearchPos=1              ;start search at 1
         DO WHILE t
            mSearchPos=@(mText,mPrintLine,mSearchPos)
            IF mSearchPos=0        ;no more to find, so...
            BREAK               ;   get out
            ELSE
* we found something...highlight it and increment search-start position
               COLOR colorFind,row(),mSearchPos-1,row(),mSearchPos+mTextLen-2
               mSearchPos=mSearchPos+mTextLen
            ENDIF
         ENDDO
      ENDIF
      ?                            ;emit carriage return/linefeed pair
   ELSE
      BREAK                        ;stop when screen is full
   ENDIF
ENDDO

ABS(

displays the absolute value of a <num exp>

Example:

1>? abs(
1>? @('oo', greeting)
      2.00
1>? @('good',greeting)
      0.00

ACOS(

arc cosine of a <num exp> returns a value in radians between 0 and π

ASC(

Converts a character to its ASCII number.

ASC(<str exp>)
<str exp> the first character of this string is converted

Type: numeric

The characters in the character set used by the computer are numbered from 0 to 255. For the first character of the string <str exp>, ASC( returns the corresponding number. RANK( is a synonym for ASC(. See also the functions CHR(, CTONUM(, and NUMTOC(.

Examples:

1>? ASC('x')
   120.00
1>? ASC('xyz')
   120.00
   

Note that only the first character of the string matters.

ASIN(

arc sine of <num exp> returns a value in radians between -π/2 and π/2

ATAN(

arc tangent of <num exp> returns a value in radians between -π/2 and π/2

AT(

Gets the location of a substring . . . a synonym for @(

AT(find str exp, <str exp>, [start]

find str exp the string searched for <str exp> the text to be searched

Option:

[start]         byte position at which to start looking for

Type: numeric

This function finds out whether a string: find str exp occurs in the string: <str exp>. If it occurs, the function returns the character position of the first (left-most) substring of <str exp> which is the same as find str exp; if it does not occur, the function returns a 0.

@( and its equivalent, the AT( function, can easily search for successive occurences of a substring within a string.

Consider the previous paragraph. How many occurrences are there of the suBstring "string"? How many of "s"? This function can determine the answer as follows if the paragraph is stored as a single string in the variable STR:

Example:

SUBSTR='s'
COUNT=0
START=0
LEN_STR=len(str)
DO WHILE start<len_str
   start=@(substr,str,start+1)
   IF start>0
      count=count+1
   ELSE
      BREAK
   ENDIF
ENDDO

Be sure that start always advances; if it stays in the same place, it will perform the same operation indefinitely since it will never get to the end.

Ambitious programmers will have noted that, if SUBSTR is longer than one byte, START should begin at 1-LEN(SUBSTR) and advance each time by the length. Furthermore, the condition on the DO WHILE line should then be

START<=LEN_STR-LEN_SUB

(assuming you've saved the length of the substring in this last variable).

Examples:

1>greeting='Good morning'
1>? @('oo', greeting)
      2.00
1>? @('good',greeting)
      0.00

In a program:

IF @(answer,'YNQynq')>0

checks whether the user response is correct.

This program segment finds and marks every occurrence of a specified string in a page of text displayed on the screen:

CLS                                ;start by erasing the screen
DO WHILE t                         ;break embedded in segment
   IF row()<mLineNumber            ;stop at end of screen
      IF .not. read(mPrintLine,1)  ;be sure there's more to display
         BREAK                     ;if not, get out
      ENDIF
      ?? mPrintLine                ;display the line, no linefeed
      IF mText>' '                 ;if looking for input text
         mPrintLine=!(mPrintLine)  ;capitalize line from file
         mSearchPos=1              ;start search at 1
         DO WHILE t
            mSearchPos=@(mText,mPrintLine,mSearchPos)
            IF mSearchPos=0        ;no more to find, so...
               BREAK               ;   get out
            ELSE
* we found something...highlight it and increment search-start position
               COLOR colorFind,row(),mSearchPos-1,row(),
mSearchPos+mTextLen-2
               mSearchPos=mSearchPos+mTextLen
            ENDIF
         ENDDO
      ENDIF
      ?                            ;emit carriage return/linefeed pair
   ELSE
      BREAK                        ;sop when screen is full
   ENDIF
ENDDO

BIT(

Bit-set function determines if a given bit is 0 or 1

BIT(string,bit position)

string a string or string variable to test bit position a numeric expression; position of a given bit within string

Type: logical

Each character in the ASCII character set is identified by an eight-bit binary number from 0 to 255 inclusive. Each bit may be either 0 or 1; for example, the letter A has a decimal value of 65 and a binary value of 01000001.

When used with the SET( and RESET( functions, which turn specific bits to 1 or 0 respectively, the BIT( function can be used to access large amounts of logical data much more compactly than in a set of logical variables. BIT( returns T (true) if the specified bit is set (0), F (false) if not set (0).

NOTE: Bit positions are counted differently than in some other schemes. In these functions, all bits are counted from the left of the string starting at 1, so that each character contains bits numbered as follows: 1. Bits 1 to 8. 2. Bits 9 to 16. 3. Bits 17 to 24. . . . and so on

Example in a program:

To print the binary value of each character in an input string:

SET RAW ON         ;eliminates spaces between listed output
DO WHILE t
   ACCEPT 'Enter a short string or binary representation: ' TO string
   IF string=' '
      BREAK
   ENDIF
   ?
   REPEAT LEN(string)*8 TIMES VARYING position
      ?? IFF(BIT(string,position),'1','0')
      IF MOD(position,8)=0
         ?? ' '
      ENDIF
   ENDREPEAT
ENDDO

Now run the program:

Enter a short string for binary representation: Bit <--- enter text "Bit"
01000010 01101001 01110100   <--- result displays on screen
Enter a short string for binary representation: <--- prompt reappears

BLANK(

Creates a string of blanks or other specified characters.

BLANK(<num exp>[,charnum)

<num exp> a number from 0 to 255

Option:

charnum    the ASCII number of the character used to fill the
                  blank string; default is 32, the blank character

Type: character

This function creates a string of <num exp> blanks or other specified characters.

When charnum is specified, many interesting effects can be created, particularly by using the special pattern characters in the IBM screen character set, 176-178, and the solid block character, 219.

Examples:

1>name='DAVID'
1>? name+BLANK(15)+name
DAVID               DAVID
1>num=23
1>? name+BLANK(num+5)+name
DAVID                            DAVID
1>? BLANK(20,65)
AAAAAAAAAAAAAAAAAAAA
1>? BLANK(20,196)
--------------------

BOF

Gives the beginning-of-file flag for the currently selected data file.

BOF

Type: logical

If the current record pointer is on the first record of the file in use and a SKIP -1 is issued, BOF returns T (true); otherwise it is F (false). Since SKIP -n is treated as n SKIP -1 commands, BOF returns true if SKIP -n goes past the last record.

To check an open data file other than the currently selected one, use the BOF( function.

Examples:

1>USE employee
1>GO 3
1>SKIP -2
1>? #
      1.00
1>? BOF
F
1>SKIP -1
1>? BOF
T
1>GO 4
1>SKIP -5
1>? #
      1.00
1>? BOF
T

BOF(

Gives the beginning-of-file flag for a specified data file.

BOF(<filenum>)

Option:

<filenum> the number of the data file to be checked

Type: logical

For the data file number specified, if the current record pointer is on the first record and a SKIP -1 is issued, BOF( returns T (true); otherwise it is F (false). Since SKIP -n is treated as n SKIP -1 commands, BOF( returns true if SKIP n goes past the first record.

An extended form of the BOF function which, since it takes no parameter, works only on the currently selected data file. If no <filenum> is specified, the current file is assumed.

Examples:

1>USE employee
1>GO 3
1>SKIP -2
1>? #
      1.00
1>? BOF()
F
1>SELECT 2
2>USE inventry
2>GO TOP
2>? #
      1.00
2>? BOF()
F
2>SKIP -1
2>? #
      1.00
2>? BOF()
T
2>SELECT 1
1>? BOF(2)
T

CEIL(

ceiling integer: the integer equal to or just above a given number

Related functions: CEIL( = the integer equal to or just above a given number; FLOOR( = the integer equal to or just below a given number; INT( = the integer part of a mixed number after discarding the fractional part; MOD( = the balance after truncating a mixed number.

CEN(

Centers a line of text.

CEN(<str exp>,<num exp>)

 <str exp>    the text to be centered
 <num exp>    the line width

Type: character

This function centers (from the present position) the text <str exp> in a line (column) with <num exp> characters.

Examples:

1>compiler='Shark'
1>? CEN(compiler,40)
                  Shark
1>@ 10,20 SAY CEN('Center this',40)

Note: the last command centers the text between columns 20 and 60.

CHR(

Converts an ASCII number to character.

(To convert a numeric value to a string, use STR()

CHR(<num exp>)

<num exp> a number from 0 to 255

Type: character

The characters in the character set used by the computer are numbered from 0 to 255; this number for a character is called the ASCII number. For a given <num exp> in this range, CHR(<num exp>) is the corresponding character.

This function is useful to send control codes to the printer. For instance,

1>? CHR(27)+CHR(120)+CHR(1)

puts the Epson LQ-1500 printer into letter quality mode.

The functions ASC( and RANK( do the reverse. These functions combine nicely. If the memory variable LETTER contains a letter of the alphabet (other than z or Z), then LETTER=CHR(ASC(LETTER)+1) places in LETTER the next letter of the alphabet.

Examples:

1. To send unprintable or other characters to a printer

1>? CHR(27)

sends ESC to the printer

1>letter='C'
1>? CHR(RANK(letter)+1)

sends "D" to the printer

2. To set a standard IBM or Epson printer into double-wide mode:

1>SET PRINT ON
1>? CHR(14)+'First line.'

prints:

First line. 

NOTE: the character '0' is difficult to send to a printer since it represents the end-of-line instruction. A better method of sending characters is the

PSTR

command, which permits sending any character to the printer. Example:

PSTR 27,W,1Bh,41h,3h

For more information, see the PSTR command.

CLOSE(

Closes a file.

CLOSE([filenum])

Option:

<filenum>      the DOS file number (between 1 and 4)

Type: logical

This function closes the DOS file (in particular, the sequential file) opened with the ROPEN( or WOPEN( function. It returns T if successful, F otherwise. See the functions ROPEN(, WOPEN(, SEEK(, SSEEK(, READ(, WRITE(, GET(, PUT(, IN(, OUT(, and CLOSE).

If filenum is not specified, filenum=1 is the default.

Example:

1>ok=ROPEN('a:label.prg',3)
1>? ok
T
1>ok=CLOSE(3)

COL(

Gets print column position.

COL()

Type: numeric

This function gives the current column position of the cursor; if the printer is on, it returns the column position of the printer head. See the commands SET PRINT ON and SET FORMAT TO PRINT, and the function ROW(.

Example:

@ ROW(),COL()+3 SAY 'Hello'

prints 'Hello' starting three characters to the right of the end of the last printing.

COS(

cosine of <num exp> in radians

COSH(

hyperbolic cosine of <num exp>

CTONUM(

Convert a hexadecimal string into a decimal number.

CTONUM(type,string exp)

type         the length of the numeric value to be returned
string exp   the string to be evaluated as a hexadecimal value

Type: numeric

A general conversion function for converting hexadecimal values into decimal numbers. Input can be any length string or string variable up to eight characters as follows:

 Type     String Length  Returns
   1      1 byte         integer 0 to 255
   2      2 bytes        integer -32768 to 32767
   4      4 bytes        integer +/- 2 billion
   8      8 bytes        a floating point number

If string is shorter, conversion still assumes the string is the format of the given width. When type is 1, this function is equivalent to RANK( or ASC(.

The NUMTOC( and CHR( functions convert numbers into strings.

Do not confuse these function with STR( and VAL(, which convert decimal numbers into their string representations, and vice versa.

Examples:

1>? CTONUM(1,'a')
     97.00
1>? CTONUM(2,'ab')
  25185.00
1>? CTONUM(4,'abc')
6513249.00
1>? CTONUM(4,'abcd'); number too large for format in :PICTURE

DATE(

To display a date in a specific format, or to update :DATE with the computer's system date.

DATE([type],<str exp>)

type being one of nine type basic date-output formats:

DATE(1)
DATE(2)
DATE(3), etc

Option: <str exp> the date to be converted

Type: character

This function has three distinctly different purposes and results:

1. with only type specified in the range 1-9, rewrites the current Shark date in :DATE in the format specified by the type, and returns the result.

2. with two parameters (the format in the range 1-9, and the date) returns the given date in the specified format. :DATE is not affected.

3. with type specified as zero, for example "date(0)", updates the Shark date with the computer's current system date, and the computer time with the current system time. The Shark and system dates are always the same when Shark is started, but the Shark does not automatically advance at midnight as the computer's system date does. When Shark is in continuous use overnight, or even for days at a time, it may be important to ensure that these dates are kept in synchronization. Date(0) updates calendar date; returns a string of length zero.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

Type            Date-output format
-----------     -----------------------------------------------------------------
0               a string of length zero representing the full current system date
                displayed as in Type 4 on this list, and updates the :DATE system variable with date(4)
1 or YMD        6-character format without slashes: yymmdd
2 or MDY        8-character format with slashes: mm/dd/yy
3 or Char       Spelled out: Month dd, yyyy
4 or Full       Spelled out: Weekday, Month dd, yyyy
5 or Lchar      Last day of month spelled out in format 3 (Char)
6 or DMY        11-byte string in format dd-MMM-yyyy (example 03-NOV-1990)
7 or Variable   formatted without slashes according to SET DATE TO command (See SET DATE TO)
8 or Long       8-character format without slashes: yyyymmdd
9 or Last       Last day of month in format 1 (YMD) or 8 (Long), depending on whether SET DATE TO command sets year to 'YY' or 'YYYY'

Shortcut: When specifying type by name, only the first character is usually required. The exception is for Lchar, Long, and Last, which require two characters to resolve ambiguity. If only one is given, Lchar is assumed. It's possible to just use the number.

Note: No name equivalent is provided for type 0, which updates the Shark date from the computer BIOS calendar setting.

<str exp> must contain the date in one of the following formats:

mmddyy      ddmmyy       yymmdd   mmddyyyy   ddmmyyyy   yyyymmdd (<-- This last format is the ISO-8601 STANDARD format)

Optionally, a slash, a hyphen, or a space may be used to separate the elements of these formats. For example, YY/MM/DD, YY-MM-DD, DD MM YYYY are all equally valid.

There should be two digits each for month and the day, and two or four digits for the year. 01 3 92 is not acceptable. If <str exp> is not acceptable, then DATE( returns a string of blanks.

In the event of ambiguity, dates will be decoded in accordance with the format set in the SET DATE TO command. For example:

SET DATE TO    date           is interpreted as   Comment
-------------  -----          ---------------     --------
'ddmyy'        11/03/99       March 11, 1999      Difficult to use for commerce
'mmddyy'       11/03/99       November 3, 1999               "
'mmddyy'       11/03/60       November 3, 2060               "                  
'yyyymmdd'     20110419       2011 April 19       ISO-8601 STANDARD FORMAT					  

This variety of date formats caters to many varied uses. However, the only reliable date format in business and science is the completely unambiguous ISO8601 'yyyymmdd' format shown above.

See also the system variable :DATE and the command SET DATE TO.

Examples:

 
1>:DATE= '10/05/22'
1>? :DATE
10/05/22

1>? DATE()
20221005

1>? :DATE
20221005

1>? DATE(1)
221005

1>? :DATE
221005

1>? DATE(2)
10/05/22

1>? :DATE
10/05/22

1>? DATE(3)
October 5, 2022

1>? :DATE
October 5, 2022

1>? DATE(4)
Saturday, October 5, 2022

1>? :DATE
Saturday, October 5, 2022

1>? DATE(4,'12/08/21')
Tuesday, August 21, 2012

1>? :DATE
Sunday, December 8, 2021

1>? DATE(5,'20-03-27')
March 31, 2020

1>? DATE(6,'21-03-27')
27-Mar-2021

1>? :DATE
Saturday, October 5, 2022

1>? :DATE(8)
20110419

The date can be recalled with any of the above date() functions, and styled to suit the user. For example, using the PIC( function, put the following in the SHARKNET.CNF file so any Shark program can access it at any time:

:DATE=DATE(8)
:UNDOC=PIC(DATE(8),"XXXX.XX.XX") or
:TITLE=PIC(DATE(8),"XXXX.XX.XX")

Calling :UNDOC OR :TITLE in this example will display "2019.12.25". You can save the current date in any unused Shark system variable where it will be available for any purpose. It's automatically updated by calling "date(0)".

Then the system variable :UNDOC when recalled will display:

1>? :UNDOC
2019.12.25
1>?

Thus, a preferred date format can be stored in Shark's .CNF file as a system variable. It's then visible to all applications in Shark:

Most of the time, the Shark programmer will save preferred date formats in an available system variable such as :UNDOC or :TITLE, and will rarely change date formats once a preferred setup is implemented. Date-dependant records are thus maintained by including the raw calendar date stored in the :DATE variable, or the formatted calendar date stored in the :UNDOC system variable.

Maintaining Calendar Date:

Upon starting Shark, Shark fetches the computer system date and stores it in the system variable :DATE where it's accessible by Shark for the duration of the session. It's not possible to reset the COMPUTER system :DATE manually; it must be reset by calling the DATE(0) function within a Shark program. From then on, your programs will always display/use today's date

If the time has passed midnight during the current run of Shark, Shark continues with date/time unchanged until the user restarts Shark, or the user updates the Shark date with DATE(0) as follows:

1>? DATE(3)
Sunday, October 5, 2019
1>? DATE(0) <-- updates :DATE system variable
1>? DATE(3)
Sunday, October 6, 2019

By simply putting this line at the top of your home program (or every program):

? DATE(0)

your Shark program date will always be using today's date! :DATE will also be refreshed if you begin a new session by restarting Shark. This is important for VP-Info users since VP-Info doesn't have the date(0) update function available.

NOTE: Formatting the date display has no effect on date calculations.

A NOTE FOR PROGRAMMERS & TECH TYPES:

Shark keeps all file dates in pre-Y2K MS-DOS format. Each date component before year 2000 is saved simply as the last 2 digits of each component. The 20th century is epoch "00". "1998" for example is stored as "0098". An old file from "April 15,1998" will show its file date as "4-15-98". It's actually saying "04-15-0098", but omitting the zeros. If you type "DIR" or "DIRF(" at the prompt, this is the date format you will see.

After the epoch rolls over to the next millenium (the 21st century), the "00" of the 19th millenium will become "01" and Shark will display the DOS date not as "0120", but as "120", again dropping the leading zero. "April 15,2000" will thus display as "4-15-120".

Shark automates this formatting using the "SET DATE TO" instruction, so the display task is automated. However, the date display when listing files still remains in the older MS-DOS display format. Only rarely will the Shark programmer see this.

When doing occasional file searches or backups, Shark programmers sometimes work with this display quirk by writing a simple formatting subroutine to always display the dates in a preferred display format when listing files:

* DISPDATE.PRG
* A date display subroutine to sort out a file listing display:
*
if VAL($(dirx(5),7,3))<100
mdatprefx='19'; set a 20th century date prefix
MDAT=mdatprefx+$(DIRX(5),7,2)+"."+IFF($(DIRX(5),1,1)=' ','0'+$(DIRX(5),2,1),$(DIRX(5),1,2))+"."+$(DIRX(5),4,2)
else
mdatprefx='20'; set a 21st century date prefix
MDAT=mdatprefx+$(DIRX(5),8,2)+"."+IFF($(DIRX(5),1,1)=' ','0'+$(DIRX(5),2,1),$(DIRX(5),1,2))+"."+$(DIRX(5),4,2)

endif

Thus you can set your date display as you prefer. The dates in Shark are absolute and are unaffected by any display choices, so your files and dates will always be correct regardless of your display choices. The above subroutine will show dates in a program like this:

BEFORE:
1>dirx vpi*.*
VPI.EXE       260326  4-08-91  10:56a
VPI.MSG        15809  4-08-101 10:57a
VPI.SGN         1972  4-08-121 10:58a

AFTER:  Using the DISPDATE subroutine will display the same files & dates as follows:

VPI.EXE       260326  1991.04.08 10:56a
VPI.MSG        15809  2001.04.08 10:57a
VPI.SGN         1972  2021.04.08 10:58a

Refer to the TIME( function for similar tools for managing the clock time display.

DAYS(

Computes dates and date differences in days.

DAYS(<str exp1>,<str exp2>) Example: DAYS(2005-03-18,2005-06-27)
DAYS(<str exp>,<num exp>) Example: DAYS(2005-03-18,30)

In the first form: str exp1 and str exp2 are dates

In the second form: <str exp> is a date and <num exp> is a number

Type: numeric/character

In the first form, DAYS( returns the number of days between two dates. The result is an integer.

In the second form, DAYS( returns the date (as a string) which is <num exp> days past or before the date <str exp>.

The string expressions containing dates can be of many different formats (see the DATE( function for more examples):

	yyyy/mm/dd  2005/03/18
	yyyy-mm-dd  2005-03-18
	yyyy mm dd  2005 03 18	
	  mm/dd/yy  03/18/05
	  mm-dd-yy  03-18-05
	  mm dd yy  03 18 05

There should be two digits each for yy, mm, and dd, and four digits for yyyy. 01 3 90 is not acceptable (dd contains only 1 digit).

In the second form, the date is returned in the format set with the SET DATE TO command (default: mmddyyyy). If you wish a different format, use the DATE( function. See also MONTHS( and SET DATE TO.

Examples:

1>? DAYS('04 06 90','04 29 90')
     23.00
1>? DAYS('01/01/88','01 23 90')
    753.00
1>? DAYS('01/01/90','01 23 88')
   -708.00
1>? DAYS('01/01/91','01 02 91')
      1.00
1>? DAYS('01/02/91','01 01 91')
     -1.00
1>? DAYS('04 03 90',30)
050290
1>? DAYS('02 03 90',30)
030590
1>? DAYS('02 03 90',-3)
010490
1>? DAYS('020390',-30)
010490
1>monthday='0203'
1>offset=30
1>? DAYS(monthday+'90',offset+1)
030690

Note that the MONTH( and DATE( functions always count the days in leap years:

	 
1>? DAYS('02/28/88','03 01 88')    ;leap year
      2.00
1>? DAYS('02/28/90','03 01 90')    ;not a leap year
      1.00

Thus, DAYS(2005-03-18,-365) may not give the same result as MONTHS(2005-03-18,-12)

DAYS( and DATE( may be combined to form complex expressions. For instance, the end of the month closest to today in the form set in the SET DATE TO command:

DATE(7,DAYS(DATE(2),-15))

The end of NEXT month:

DATE(5,DAYS(DATE(2),30))

See DATE( and MONTHS( functions, and SET DATE TO command.

DBF(

Allows access to data-file attributes of a file in use.

 DBF(type[,<filenum>)

 type      the information required from the data file header

Option:

 <filenum>   the data file number; default is the currently
               selected data file

Type: character/numeric

Each data file has a file head which contains information about its structure, most of which is displayed with the LIST STRUCTURE command.

Using the DBF(, DBFX( and FLD( functions provides users access to this information in a programmable form suitable for display and use in expressions.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

TYPE             EXPLANATION                             RESULT
1 or (T)ype      File type ("0", "1", "2" or "3")        string
2 or (N)ame      File name                               string
3 or (F)ields    Number of fields in structure           integer
4 or (R)ecords   Number of records in file               integer
5 or (I)ndexes   Number of indexes currently open        integer
6 or (M)aster    Index number of master index            integer

NOTE: Keep in mind that the following DOS-only DBF( arguments will show different results in an emulator such as vDOS because the root drive C\: will have been mounted in a different location from your computer's root location during the setup of your emulator:

7                DOS File name from FILES structure      string
8                DOS File name from DOS                  string                

Shortcut: When specifying type by name, only the first character is required.

Examples:

1>? DBF(type),DBF(n),DBF(fields),DBF(recs),DBF(indexes),DBF(master)
0 CUSTOMER.DBF       9.00       4.00       2.00       1.00
1>? DBF(2)
CUSTOMER.DBF
or:
1>? DBF(7)
C:\DBF\CUSTOMER.DBF
NOTE: "DBF(7)" is a request for DOS information reported by Shark which therefore also works inside an emulator!
or:
1>? DBF(8)
C:\SHARK\DBF\CUSTOMER.DBF
NOTE: "DBF(8)" is a request for direct DOS information and will not work inside an emulator!

1>USE#1 CUSTOMER READ
1>SET INDEX TO NAME
1>APPE BLANK
1>GO TOP <--- takes you to blank (NEWLY APPENDED) record of indexed table
1>GO BOTT <--- takes you to last record before new record appended to table
1>GOTO DBF(R) <--- takes you to the last (NEWLY APPENDED) record in table

Since appended record is blank, it won't show as the last (BOTTOM) record in an indexed table. DBF(R) will take you to the last record in the table.

DBFX(

Gives additional information about an open data file; an extension to the DBF( function.

 DBF(type[,<filenum>)

 type      one of three types of information as listed below

Option:

 <filenum>   the data file number; default is the currently
               selected data file

Type: logical

The DBF( and FLD( functions provide information contained in the data file headers.

Shark provides this extended function to give three additional types of information in a programmable form suitable for display and use in expressions.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

TYPE           EXPLANATION
1 or Filter    TRUE if a FILTER is in effect
2 or Limit     TRUE if a LIMIT is in effect
3 or Relation  TRUE if file is related to another
4 or Write     TRUE if current record has changes to be written to disk

Shortcut: When specifying type by name, only the first character is required.

In a program, the programmer has control over whether filters, limits and relations are established, so the first three options are primarily helpful in Conversational SharkBase, in program debugging and in displaying the current environment for the aid of end-users.

The fourth option, however, is extremely helpful in programming, especially on networks, for it allows the programmer not only to check whether the user actually wants to save changes made to the record, but to avoid locking and changing records when the user was only looking.

A second valuable use of this feature is to time-stamp changes and leave a record of who made them.

Examples:

1>USE customer
1>SET FILTER TO state='CA'
1>? DBFX(Filter) or DBFX(1)
T
1>? DBFX(R) or DBFX(3)
F

In a program segment, starting with the READ command):

READ
IF DBFX(w)
   @ 22,0 say CEN('Record changed. Save the Changes (Y/N)?',80)
   CURSOR 23,39
   IF !(CHR(INKEY()))='Y'
      REPLACE changedby WITH DATE(1)+user+TIME(1)
      FLUSH
   ELSE
      NOUPDATE      ;all changes are discarded
   ELSE
ENDIF

The same approach is used in programming for SHARE files on a network, but the actual technique is beyond the scope of this section due to the many different ways networking-data-indegrity is implemented by various operating systems. See specific network sections of your SharkBase documentation for more on this topic.

DELETED(

Determines whether a record is deleted.

 DELETED(<filenum>)

Option:

 <filenum>    the number of the data file to be checked

Type: logical

In a specified data file, the current record pointer points at a record. If this record has been marked for deletion (in BROWSE or EDIT, or with the DELETE command), then DELETED( gives the value T; otherwise, it is false.

This is a more general form of the * function, which operates the same way as DELETED( but, because it allows no parameter, works only with the currently selected data file.

Examples:

1>? DELETED(4)
T

DESCEND(

The main use of DESCEND( in Shark is to create indexes that are in reverse, or descending, order.

Remember that an index arranges its keys in order of the value of the characters making up the keys. "A" comes before "B" because the value 65 is smaller than 66.

In C Language terms, Shark reverses all bits in string; equivalent to NOT of string. Shark uses this function to reverse the order of an indexed file.

DESCEND(string)
 string    the string to be converted; every "1" bit is returned
               as "0", and every "0" bit is returned as "1"

Type: character

Each character in the ASCII character set is identified by an eight-bit binary number from 0 to 255 inclusive. Each bit may be either 0 or 1; for example, the letter A has a decimal value of 65 and a binary value of 01000001, while the letter B has a decimal value of 66 and a binary value of 01000010.

The DESCEND( function returns a "mirror image" of the input string . . . i.e., one in which evey bit set to 1 is reset to 0, and every 0 is set to 1.

The result is familiar to programmers who use C and other low-level languages, who would use the NOT operator to obtain the same result.

The main use of DESCEND( in Shark is to create indexes that are in reverse, or descending, order.

But suppose the index expression, instead of being on the key expression itself is on the NOT value of it, as in:

INDEX ON DESCEND(NAME) TO REVERSE

Now you have an index called REVERSE.NDX in which B comes before A.

This function is especially useful in creating reports. For example, suppose you want to report transactions for your customers in reverse date order (latest transactions first). Your index command could be:

INDEX ON CUST+DESCEND(DATE) TO CUSTREPT

Note: if you create an index using the DESCEND( function, you will have to use the same function to modify any find strings if you need to use the index to FIND, SEEK, etc.

Example in a report form:

TITLE - Transactions by Customer, with Dates in Descending Order
FILE - trans
INDEX - cust+descend(date) to custrept
FILE - cust index cust1
RELATION - custnum to 2
FIELDS - date(6,date),desc,amount
HEADING - Date;===========,Description;==============================;Amount;==========
PICTURE - ,,9999999.99
SUBTOTAL - custn
MESSAGE - 'Customer: '+pic(custnum,'xxx-x-xx  -- ')+name#2

Note: This report form includes a number of features worth noting, including the fact that it creates its own index, sets up a relation to a second file, includes underlined headings and subtotals, and includes one line split into two. In report forms, the comma (,) is a continuation character when it is the last character on a line. See REPORT.

DIR(

Get file information from disk directory.

 DIR(filespec) (referred to as "Form 1")
 DIR()         (referred to as "Form 2") 

Option:

filespec  refers to a string or string expression containing a file name (or skeleton using ? and/or * wildcards), with optional drive and/or path specification (enclosed in single quotes)

Type: character

Searches for specific files specified by the drive path, subdirectory and/or filename and provides specific information on files found.

If an argument is given as shown in Form 1, it must be a string or string expression naming a file, with * and ? wildcards optional). Returns the first file name found matching filespec. If no match was found, blank is returned.

If no argument is given as shown in Form 2, the previous filespec is used to find the next matching file. If no more matching file names are found, blank is returned.

DIR( differs from DIRF( in that DIR( requires the user to specify the pathname unless the search is to be confined to the current directory. DIRF( (see below) is usually preferable since it searches the directory as which a current FILES structure points for the file name specified. See DIRF(.

Examples:

? DIR('c:\path\*.bak')

locates and displays the name of the first file with extension BAK in the subdirectory \PATH, while

? DIR('*.bak')

locates and displays the name of the first file with extension BAK in the current directory.

If a file is found, entering DIR() with no parameters will locate the next file meeting the filespec. This will continue until the response is a blank, indicating there are no more files meeting the filespec.

Once a file is identified with DIR(, the DIRX( function may be used to obtain additional information from the DOS directory in a form suitable for use in a program.

DIRF(

Get file information from disk directory.

 DIR(filespec) (referred to as "Form 1")
 DIR()         (referred to as "Form 2") 

Option:

filespec  a string or string expression containing a file name (or skeleton using ? and/or * wildcards), with optional drive and/or path specification (enclosed in single quotes)

Type: character

Searches for specific files specified by the filename and the path supplied from the FILES structure (see FILES...ENDFILES), and provides specific information on files found.

If an argument is given (Form 1), it must be a string or string expression naming a file, with * and ? wildcards optional). Returns the first file name found matching filespec. If no match was found, blank is returned. If a disk name is supplied, the path supplied by the FILES structure is ignored.

If no argument is given (Form 2), the previous filespec is used to find the next matching file. If no more matching file names are found, blank is returned.

DIR( differs from DIRF( in that DIR( requires the user to specify the pathname unless the search is to be confined to the current directory. See DIR(.

Examples, assuming the following FILES structure is in effect:

FILES
*.prg,c:\shark\prg
*.frm,c:\shark\prg
*.bak,c:\shark\prg
*.db*,c:\shark\data
*.ntx,c:\shark\ntx
*.cpl,c:\shark\cpl
ENDFILES
DIRF('*.prg')

locates the first file with extension PRG in the subdirectory C:\SHARK\PRG. NB: this request only LOCATES the file information and doesn't display any result! Read further for instructions on how to DISPLAY needed information.

DIRF('*.bak')

locates the first file with extension BAK in the subdirectory C:\SHARK\PRG.

NOTE that the above instruction only locates the file and doesn't display any result. To display the found file, you must type:

? DIRF('*.bak')
DIRF('*.dbt')

locates the first file with extension DBT in the subdirectory C:\SHARK\DATA.

DIRF('*.txt')

locates the first file with extension TXT in the current directory, since there was no matching filename pattern in the FILES structure.

If a file is found, entering DIRF() with no parameters will locate the next file meeting the filespec. This will continue until the response is a blank, indicating there are no more files meeting the filespec.

Once a file is identified with DIRF(, the DIRX( function may be used to obtain additional information from the DOS directory in a form suitable for use in a program.

DIRX(

Obtain additional information about file located with the DIR( or DIRF( function.

 DIRX(type)

 type    the name or number of the information required about a file

Type: character/numeric

Once a file is identified with DIR( or DIRF( additional information can be obtained from the DOS directory in a form suitable for use in a program.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

Type           Explanation                                    Result
1 or Name      last file name found with DIR(                 string
2 or Size      size in bytes of last name found with DIR(     integer
3 or Attribute DOS file attribute as follows                  integer
                    1 - directory
                    2 - system
                    3 - hidden
                    4 - read only
                    5 - normal
4 or Time      time file created or last updated              string
5 or Date      date file created or last updated              string
6              directory
7              sub-directory

Shortcut: When specifying type by name, only the first character is required.

These functions have many uses. Use them to write a program that backs up recently modified files, a program that lists files so the user can pick one, etc.

Examples:

DIRX(n) returns the filename (e.g. "Name")
DIRX(a) returns 4 if the file is read only (e.g. "Attribute")

EOF(

Gives the end-of-file flag for a specified data file.


 EOF(<filenum>)

Option:

 <filenum>    the number of the data file to be checked

Type: logical

For the data file number specified, if the current record pointer is on the last record and a SKIP is issued, EOF( returns T (true); otherwise it is F (false). Since SKIP n is treated as n SKIP commands, EOF( returns true if SKIP n goes past the last record.

Also, if a LOCATE or CONTINUE command is unsuccessful, or if NEAREST does not find an index key equal to or greater than the FIND string, EOF( returns T.

If no <filenum> is specified, the current file is assumed.

An alternate form of the function - EOF - works only on the currently selected data file, since it takes no parameter. See EOF.

Examples:

1>USE employee
1>GO 4
1>SKIP 2
1>? #
      6.00
1>? EOF()
F
1>SELECT 2
2>SKIP
2>? EOF()
T
2>GO BOTTOM
2>SKIP
2>? #
      6.00
2>SELECT 1
1>? EOF(2)
T

EOF

Gives the end-of-file flag for the currently selected data file.

EOF

Type: logical

If the current record pointer is on the last record of the file in use and a SKIP is issued, EOF returns T (true); otherwise it is F (false). Since SKIP n is treated as n SKIP commands, EOF returns true if SKIP n goes past the last record. Also, if a LOCATE or CONTINUE command is unsuccessful, or if NEAREST does not find an index key equal to or greater than the FIND string, EOF returns T.

Examples:

1>USE employee
1>GO 4
1>SKIP 2
1>? #
      6.00
1>? EOF
F
1>SKIP
1>? EOF
T
1>GO 4
1>SKIP 3
1>? #
      6.00
1>? EOF
T

EXP(

e to the power <num exp>

FIELD(

Get the number of the Get Table entry corresponding to a variable or field name.

  
 FIELD(<name>) 

<name> =the name of field or variable in a Get Table

Type: numeric

While in full-screen editing mode (with READ, BROWSE, EDIT, etc.), each input variable and field is put into a Get Table that can be controlled with an ON FIELD structure.

FIELD( returns the number from 1 to 64 of any editing field on screens created with @ GET and TEXT macros. This function is usually used on an ON FIELD structure to redirect the sequence of data entry.

See READ and ON FIELD in the Command Reference section.

Example in a program:

ON FIELD
FIELD qty
   IF qty<0
      @ 22,0 say CEN('Quantity cannot be negative. Press any key',80)
      cc=INKEY()
      ERASE 22,22
      :FIELD=FIELD(qty)
   ENDIF
ENDON

See also System Variable :FIELD

FILE(

Verifies whether a file exists.

 FILE(<str exp>)

 <str exp>   = a file name   

Type: logical

This function looks up the file whose name is given by <str exp>; if the file is found, the function returns T, otherwise it returns F.

If no extension is given in the file name, DBF is assumed (a data file is looked for).

Examples:

1>? FILE('employee')
T
1>? FILE('a:read.me')
T
1>mfile='read.me'
1>? FILE(mfile)
F
1>? FILE('a:'+mfile)
T

FLD(

Get information about a field in a data file.

  
 FLD(type,<fieldnum> [,<filenum>])          
                                              
 type       one of the four attributes of a field            
 <fieldnum>  = the number of the field to be checked

Option:

 <filenum>    the number of the data file to be checked

Type: character/numeric

Each field in a data file has four attributes as shown with the LIST STRUCTURE command: name, type, width and (for numeric variables) number of decimal places. The FLD() function is often used in conjunction with the DBF() function.

These attributes can be retrieved in a form suitable for use in a program with the FLD() function.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

Type           Explanation                              Result
1 or Name      string containing field name             string
2 or Type      string containing field type             string
3 or Width     number containing width of field         integer
4 or Decimals  number of decimal places in field        integer

Shortcut: When specifying type by name, only the first character is required.

Example in a program:

REPEAT DBF(records) TIMES varying fldnum
   REPEAT 4 times VARYING type
      ?? FLD(type,fldnum)
   ENDREPEAT
   ?
ENDREPEAT

FLOOR(

floor integer: the integer equal to or just below a given number

Related functions: CEIL( = the integer equal to or just above a given number; FLOOR( = the integer equal to or just below a given number; INT( = the integer part of a mixed number after discarding the fractional part; MOD( = the balance after truncating a mixed number.

GET(

Gets a string from a DOS file.

 GET(str var,<width num exp>[,filenum])

str var     stores the string
<width num exp>   = the width of the string requested (must be in range 1 to 254)

Option:

 filenum            the DOS file number (between 1 and 4)

Type: logical

This function imports a string of <width num exp> characters from a DOS file opened with the ROPEN( function; the character number pointer is normally positioned with the SEEK( function.

If successful in getting all the bytes requested, GET( returns T (true) and sets str var to the string imported from the file. If str var does not exist, GET( will create it.

If the function is unsuccessful, it returns F (false). This will be the result if the GET( function tries to get data beyond the end of the file. Note, however, that even if GET( returns F, one of more characters may still have been imported from the file; it is wise to check the value and width of str var to ensure part of a file is not lost.

If filenum is not given, filenum=1 is assumed.

GET( READ(, IN(, and WRAP( are the only functions that change the contents of the memory variable used as an argument.

See also the functions ROPEN(, WOPEN(, CLOSE(, SEEK(, and PUT(.

Example in a program:

IF ROPEN('test',3)
   DO WHILE GET(string,80,3)
      ? string
   ENDDO
ENDIF
ok=CLOSE(3)

IFF(

Allows inline IF...THEN logic in expressions.

 IFF(cond,<exptrue>,<expfalse>)

 cond       a logical expression
 <exptrue>    the expression to be returned if cond is TRUE
 <expfalse>   the expression to be returned if cond is FALSE

Type: Type: character/numeric/logical

This function returns <exptrue> if cond is true, <expfalse> otherwise. The type of the value returned is the same as the expression selected by the condition. IFF( is very useful in the FIELDS line of reports or in commands such as SUM, AVERAGE, REPLACE, or LIST.

Examples:

1>? IFF(married,'Married','Single ')
1>SUM IFF(quant>500, quant*price, 0),IFF(state='NY',1,0)

The first command prints "Married" or "Single" according to the value of a logical field named MARRIED. The second command will return the sum of all quantities for transactions where quantity is greater than 500, and a count of all records where STATE='NY', thus combining two separate commands (SUM FOR and COUNT FOR) into one.

Caution: do not use expressions of different types or widths in reports, since this may cause the REPORT command to fail.

IN(

Inputs a single character from a sequential file.

 IN(str var[,<filenum>])

 str var      stores the character

Option:

 <filenum>      the DOS file number (between 1 and 4)

Type: logical

This function reads the next character of the DOS file (opened with the ROPEN() function into the string variable str var; if str var does not exist, it will be created. str var cannot be a matrix variable.

If filenum is not given, filenum=1 is assumed. IN( returns T if successful, F otherwise.

This function is especially useful to communicate over the standard COM1, COM2 devices, for conversion of WordStar or other non-standard files to standard ASCII files, to encrypt/decrypt a file through a translation table.

IN(, GET(, READ(, and WRAP( are the only functions that change the contents of the memory variable used as an argument.

See the functions OUT(, ROPEN(, WOPEN(, SEEK(, SSEEK(, and CLOSE(.

IFKEY(

Tests if a character is waiting in the keyboard buffer.

 IFKEY()

Type: logical

It is often useful to test whether a key has been pressed on the keyboard without waiting indefinitely if a key is not pressed.

The IFKEY( function returns T (true) if a keystroke is waiting in the keyboard buffer, F (false) if not. The keyboard buffer is not affected.

Example in a program, to create a timing loop that ends as soon as any key is pressed:

start=VAL(TIME(seconds))
DO WHILE VAL(TIME(seconds))-start<3
   IF IFKEY()
      BREAK
   ENDIF
ENDDO

INKEY(

Every key on a keyboard has a numeric value. INKEY() waits and gets the numeric value of a key-press.

INKEY()

Type: numeric

This function suspends program execution until a key is pressed. It returns a number identifying the key. Nothing is displayed on the screen. Any key can be read (except Alt, Ctrl, and shift which merely affect the characters produced by other keys) including all function keys, editing keys, and alternate keys. (Depending on your computer, function keys may be pre-programmed in a variety of ways. It's even possible that F11 and F12 may not recognized by your computer's BIOS program, and may be ignored by Shark. Although it's possible, it's more likely that your PC will recognize these keys.)

Standard keys are identified with their ASCII number. Other keys return values between 256 and 511.

Examples:

             Key                     INKEY()
             Ctrl-C                    3
             A                        65
             Alt-A                   285
             <F1>                    315
             Shift-<F1>              340
             Ctrl-<F1>               350
             Alt-<F1>                360
             F12                     390

To find out the number identifying a key, give the command:

1>? INKEY()

Then (1) press <ENTER>, then (2) the key. The key's character number will be displayed.

Using INKEY() the user can program his own EDIT, set up cursor controlled menus, and so on.

A simple example showing the many uses of INKEY():

INKEY() makes a more attractive screen than the WAIT command. INKEY() can also be used to make choices:

DO WHILE t
CLS
@ 10,25 SAY "Hello! Press Any Key"
WAIT=INKEY()
DO CASE
CLS
@ 3,30 say "Some Announcements:"
BOX 2,15,4,65
@ 7,27 say "Select from the following:"
@ 10,20 say "<--- <R>eturn to Start   or   <Q>uit --->"
COLOR 112,10,25,10,27
COLOR 112,10,50,10,52
CURSOR 24,79
:KEY=0
WAIT=INKEY()
* if <R> or <r>, <R>eturn to opening menu
CASE :KEY=114 .or. :KEY=82
LOOP
* if <Q> or <q>
CASE :KEY=81 .or. :KEY=113
CLS
CANCEL
OTHERWISE
CLS 22,22
RING
@ 15,20 SAY CEN("PLEASE TRY AGAIN!",40)
WAIT=INKEY()
CLS
@ 10,30 "Thank you!"
ENDCASE
ENDDO

INSERT(

Overwrites a string at a given position with another string.

 INSERT(str expover,<str exp>,<num exp>)

 str expover    the string expression to overwrite
 <str exp>          the string expression to overwrite with
 <num exp>        the position

Type: character

This function takes the string in str expover and overwrites the string with <str exp> starting at position <num exp>.

Examples:

1>line='                              '
1>customer='John Smith'
1>ponumber='32109'
1>amount='910.56'
1>line=INSERT(line,customer,1)
1>? line
John Smith
1>line=INSERT(line,ponumber,15)
1>? line
John Smith    32109
1>line=INSERT(line,amount,25)
1>? line
John Smith    32109     910.56
1>line='            c                 '
1>newline=INSERT(line,customer,@('c',line))
1>? newline
            John Smith

Note: The last example shows the use of INSERT( with "templates". The line variable is the template. The character "c" in it designates the place where the customer has to be inserted. Such templates are useful in report generators or for creating screen displays.

INT(

Gives the integer part of a given number (the fractional part is discarded); useful for currency "rounding", for example.

Related functions: CEIL( = the integer equal to or just above a given number; FLOOR( = the integer equal to or just below a given number; INT( = the integer part of a mixed number after discarding the fractional part; MOD( = the balance after truncating a mixed number.

Example:

1> ? int(3.14159)
1> 3.00

LEFT(

Gets the left part of a string.

 LEFT(<str exp>, <num exp>)

 <str exp>   the string from which the new string is formed
 <num exp>   the number of characters to place in the new string

Type: character

This function takes the first <num exp> characters from the string <str exp>. It is equivalent to, but more efficient than:

1>$(<str exp>, 1,<num exp>).

If <num exp> is greater than the width of <str exp>, this function returns all of <str exp>.

Wherever an expression calls for a substring starting at the beginning, use LEFT( instead of $( or SUBSTR(.

Example:

1>a='David Bark'
1>? LEFT(a,5)
David
1>? LEFT(a,50)
David Bark

LEN(

Gets the width (length) of a string.

 LEN(<str exp>)

 <str exp>  is the string being measured

Type: numeric

This function returns the width (including trailing blanks) of the string <str exp>.

Examples:

1>name='David Barberr'
1>? LEN(name)
    13.00
1>? LEN(name+' is a nice boy')
    27.00

Note that the width of a string is at least 1!

LOC(

LOC( Gets the current byte position in a file opened with ROPEN( or WOPEN(.

 LOC(<filenum>)

Option:

<filenum> is the number of the sequential or random file, 1 to 4 (default 1)

Type: number

Whenever a file is opened with the ROPEN( or WOPEN( function, Shark maintains a pointer at a current position, which is where any PUT( or GET( function would take effect. The position pointer is set with the SEEK( and SSEEK( functions, and reset every time the IN(, OUT, READ(, WRITE(, PUT(, and GET( function is used.

If filenum is not given, filenum=1 is assumed.

A common use of LOC( is to get the current position before a SEEK( so that the pointer can be reset to the original position after some operation.

LOG(

LOG( <num exp>)

gives the natural logarithm of <num exp>

Type: number

Example:

1>? log(100)
1> 4.60

LOG10(

gives the base 10 logarithm of <num exp>

Type: number

Example:

1>? log10(100)
1> 2.00

LOWER(

Converts the string <str exp> to lower case.

 LOWER( <str exp>)

<str exp> is the text to be converted to lower case

Type: character

All upper-case letters in the <str exp> are converted into lower case by the LOWER( function. See also the !( and UPPER( functions.

Examples:

1>a='Aa12b'
1>? LOWER(a)
aa12b
1>? LOWER('David!')
david!

Note that only the upper-case letters, A-Z, are changed (to a-z). No other characters are affected.

LTRIM(

Trims blanks from the left-hand side of a string:

 LTRIM(<str exp> )

<str exp> the string to be trimmed

Type: character

This function gets rid of the blanks on the left of a string. See also TRIM( which removes the blanks on the right side of a string.

Examples:

1>a='    David     '
1>? a
    David
1>? LEN(a)
    14.00
1>? LTRIM(a)+' is trimmed on the left'
David      is trimmed on the left
1>? LEN(LTRIM(a))
     9.00
1>blank='     '
1>? LEN(LTRIM(blank))
     1.00

Note: LTRIM(blank) is a single blank.

MASK(

MASK(<operation>,<string>,<mask>)    Manipulates bits in a string based on comparison between 2 strings     
 <operation>       a number representing one of the three masking operations supported by SharkBase: AND, OR, and XOR      
 <string>          the string to be modified by the operation     
 <mask>            the string used to modify the bits in string1   

Type: character

Each character in the ASCII character set is identified by an eight-bit binary number from 0 to 255 inclusive. Each bit may be either 0 or 1; for example, the letter A has a decimal value of 65 and a binary value of 01000001, while the letter B has a decimal value of 66 and a binary value of 01000010. Although SharkBase has functions to set individual bits to 1 or 0 (SET( and RESET( respectively), MASK( can be used to change any number of bits at once.

The three MASK( operations are used to return a string that is the result of bitwise operations between two strings, comparing each bit in one string with the bit in the same position in the other string. If the two bits are both 1 (on or true), AND and OR both produce a 1 in that position, while XOR (exclusive OR) returns a 0. If one is a 1 and the other a 0, OR and XOR both produce a 1 and AND produces a 0. Finally, if both are 0, all three produce a 0.

There is one other operator of this type, known as the bitwise NOT, but it is not implemented through the MASK( function. Since the primary use of the bitwise NOT is to create indexes in decending order, this operation is implemented through the DESCEND( function. See DESCEND(.

The use of AND, OR and XOR is the same as in C and other low-level languages that permit access to data at the bit level, and will rarely be used by most SharkBase programmers. Those who require these operations already know how to use them and need no additional instructions for SharkBase.

Example in a program:

Given any screen color (See COLOR and SET COLOR), determine the reverse that SharkBase would use in highlighting input windows during READ operations (useful in using the same color to highlight messages and other text on the screen):

CLS
DO WHILE t
   INPUT 'Color.... ' to in
   low=mod(in,16)             ;separate the low-order and high-order bits
   hi=int(in/16)
   out=low*16+hi              ;the rest of these operations are too complex to explain...just be assured it works
   new=int(in/16)+16*mod(in,16)      
   part1=mask(and,chr(out),chr(127))
   part2=mask(and,chr(in),chr(128+8))
   rev=mask(mask(or,part1,part2))
   rev=asc(mask(o,mask(a,chr(int(in/16)+16*mod(in,16)),chr(127)),mask(1,chr(in),chr(128+8))))
   :color=in
   ? 'Main Color..',in
   :color=rev
   ? 'Reverse.....',rev
ENDDO

MAX(

Given any two expressions of the same type, MAX( returns the higher value. It must be remembered that string comparisons are based on the ASCII value of the characters in the two strings. Comparing two logical expressions has no meaning.

You may find that a comparison between a numeric expression and a numeric field results in an error. This can be avoided by ensuring both arguments are an expression, accomplished most easily by adding 0 to a field.

Examples:

1>? MAX(123,amount+0)         ;adding 0 ensures handling as an expression
   5241.34
1>? MAX('hello','goodbye')
hello
MAX(<exp1>,<exp2>)     Compare two expressions of any type and return the larger.                                                                                                                    
 <exp1>    any expression                                           
 <exp2>    any expression of the same type as <exp1>      

Type: Type: character/numeric/logical

MENU(

Lightbar menu function; allows point-and-shoot selection from an on-screen menu.

 
MENU(<choices>/<hotkeys>,<width>[,<seconds>]) 
                                           
choices     the number of choices offered by the menu
hotkeys     one character for each possible option, beginning
                   with zero (normally the exit option)
width       the width of the menu lightbar

Option:

seconds   exit MENU( after this many seconds; function returns value of 65

Type: numeric

The MENU( function pauses program execution and superimposes a movable lightbar (reverse-video line) over a menu of selections previously written to the screen, usually with TEXT.

The menu lightbar is moved up and down with the up arrow and dn arrow keys. If you press down arrow while on the bottom, the lightbar cycles automatically to the top. Similarly, pressing up arrow while on the top cycles to the bottom.

The user can select any item by moving the lightbar over it and pressing Enter, or entering its line number as a one-digit number. In either case, the line number selected is returned by the function, and the key pressed stored in the system variable :KEY. Both the function value and :KEY can be tested in a subsequent DO CASE structure to determine the program's next actions. The inkey() function displays the :KEY value:

CLS
DO WHILE t
@ 10,0 SAY "To display a key code, press any key . . ."
? inkey()
ENDDO

If the user presses 0 or <Home> , MENU( returns zero, although the first line covered by the lightbar is 1. Options over 9 can be accessed only by the lightbar.

Alternately, you may choose to use the <hotkeys> option for this function's first argument. Instead of the number of choices, a string may be supplied. The length of the string determines the number of choices and the letters in the string math the numbers of the choice. For example, if if you supplied a string literal or variable with the value "Qmdn" for <hotkeys>, pressing "Q" or "q" would return zero, "M" or "m" would return 1, "D" or "d" would return 2, and "N" or "n" would return 3. <Hotkeys> may be caps or lower case; MENU( is not case-sensitive.

If any cursor key except , and <Home> is pressed, MENU( returns the number of the line highlighted by the lightbar, and :KEY contains the key number that would be returned by the INKEY( function. (If SET FUNCTION OFF, all function keys have the same effect as these cursor keys.)

While the MENU( function is active, all other typewriter keys are ignored.

Note: If an ON KEY structure is in effect, it is ignored while MENU( is waiting for input.

Examples:

1. This is a program which shows specifically the values returned by Menu( when any key is pressed:

CLS
@ 19,46 say 'Returns'
@ 19,64 say ':KEY'
DO WHILE t
   CURSOR 5,20
   var=MENU(10,20)
   @ 20,50 say var
   @ 20,65 say :KEY
ENDDO

2. In a simple real-life program:

CLS
TEXT

            MONTH-END MENU:

           [0] EXIT TO MAIN MENU
           [1] PREPARE SALES TOTALS
           [2] CALCULATE TAX SUMMARY FOR A TAX PERIOD
           [3] PRINT OUT SALES TRANSACTIONS & MARGINS  
           [4] REVIEW DEPOSITS JOURNAL

ENDTEXT
CHOICE=0
CURSOR 8,12 ; positions cursor at row 8, column 12 (at the "[1]"
CHOICE=MENU(4,1); 1-wide lightbar moves up and down over 4 menu rows, saves 
value to CHOICE. In this example, the CHOICE "0" must be explicitly selected.
*
DO CASE
*** *** *** *** ***
CASE CHOICE = 0
  ... etc
CASE CHOICE = 1
  ... etc

3. Another real-life program:

ERASE
WINDOW 1,2,23,77 double            ;draw frame around screen
@ 1,3 say DATE(full)
@ 3,3 say CEN(:company,74)
@ 5,3 say CEN('Payroll Menu',74)
WINDOW 8,25,22,75 blank            ;use WINDOW to position TEXT
TEXT paymenu                       ;menu text in external file
WINDOW
CURSOR 10,23
ans=MENU(8,35)
IF ans=0 .or. :key=335
   CHAIN MENU
ENDIF
@ ans+9,23 say CHR(149)             ;• character as bullet
DO CASE
CASE ans=1
   ... etc.

4. Part of the same program using both hotkeys and timeout:

WINDOW 8,25,22,75 blank            ;use WINDOW to position TEXT
TEXT paymenu                       ;menu text in external file
WINDOW
CURSOR 10,23
hotkeys='Qeprsmwgf'                ;hotkeys can be a string variable
*                                  ;  this allows 8 options plus zero (quit)
ans=MENU(hotkeys,35,60)
IF ans=0 .or. :key=335 .or. ans=65 ;return of 65 means program timed-out
   CHAIN MENU
ENDIF
@ ans+9,23 say CHR(149)             ;• character as bullet
DO CASE
CASE ans=1
   ... etc.

MIN(

Compare two expressions of any type and return the smaller.

  
 MIN(exp1,exp2)                           
  

exp1 any character or numeric expression exp2 any expression of the same type as exp1

Type: character/numeric

Given any two expressions of the same type, MIN( returns the lower value. It must be remembered that string comparisons are based on the ASCII value of the characters in the two strings. (Comparing two logical expressions has no meaning.)

You may find that a comparison between a numeric expression and a numeric field results in an error. This can be avoided by ensuring both arguments are an expression, accomplished most easily by adding 0 to a field.

Examples:

  
1>? MIN(123,amount+0)         ;adding 0 ensures handling as an expression
    123.00
1>? MIN('Hello','Goodbye')
Goodbye

MOD(

The MODULO function returns the remainder of one number divided by another.

MOD(<num exp1>,<num exp2>)

For example:

1>? MOD(5,2) gives the remainder of 5 divided by 2, e.g.
  1.000000                        
1>? MOD(-3.14, .7)
 -0.340000
    MOD(<num exp1>,<num exp2>)  <num exp1> modulo <num exp1>: returns 0 if  <num exp2> is 0; returns the value num with the same sign 
	                                  as <num exp1>, less than  <num exp2>, satisfying  <num exp1>=i*<num exp2>+num  for some integer i.

1>? MOD(5,2)                    this is the remainder of 5 divided by 2
  1.000000                        
1>? MOD(-3.14, .7)
 -0.340000

Related functions: CEIL( = the integer equal to or just above a given number; FLOOR( = the integer equal to or just below a given number; INT( = the integer part of a mixed number after discarding the fractional part; MOD( = the balance after truncating a mixed number.

MONTHS(

Computes dates and date differences in months. See the similar DAYS( function.


 MONTHS(<date1>,<date2>) or
 MONTHS(<date1>,<num exp>)
 
 <date1>      a string expression containing a valid date
 <date2>      a string expression containing a valid date
 <num exp>    a numeric expression such as a number of months
 

When <date2> is specified, MONTHS( returns number of months between the two dates.

When <num exp> is specified, MONTHS( returns date that many months away

MONTHS( computes the difference between the two dates in months, or computes a date a given number of months before or after a specified date. Fractional parts of months are discarded (SharkBase only).

If a computed date is after the last date of the month, the date will be adjusted to the last day of the month. For example, MONTHS(date(8),-3) results in "20190731".

Examples:

1>? MONTHS('04 06 90','04 29 90')
      0.00
1>? MONTHS('01/01/90','02/01/90')
      1.00
1>? months('2022/06/15','2022/03/17')
      -3.00
1>? MONTHS('02/01/2019','01/01/2019')
     -1.00
1>? MONTHS('01/01/90','01/01/92')
     24.00
1>? MONTHS('02/01/90',10)
120190
1>? MONTHS('01/01/90',-6)
070189

Notes: (1) MONTH(, DAYS(, and DATE( functions always count the days in leap years: (2) The result in each case depends on your default date formats set up in your SHARK.CNF (or SHARKN.CNF for multi-user operations)file!

Thus, DAYS(2005-03-18,-365) may not give the same result as MONTHS(2005-03-18,-12)

This function is most useful for setting up billing and accounting applications.

NDX(

Get information on index files in use.

 NDX(type [,indexnum] [,<filenum>])

type = the name or number of the information required

Options:

    the number of the index being checked (1 to 7);
                default is the master index
 <filenum>    the number of the data file to be checked

Type: character/logical

NDX( is used to primarily in programs to get the information on the current environment in a form suitable for use in expressions.

The type can be given in either of two forms, a name or number (numeric expression) as follows:

Type           Explanation                          Result
1 or Name      name of index file                   string
2 or Key       key on which index was created       string
3 or DBF_Name  name of data file on which index
                 was created                        string
4 or Filter    TRUE if filter or FOR clause was
                in effect when index was created    logical

Shortcut: When specifying type by name, only the first character is required.

Examples:

1>? NDX(n),NDX(key),NDX(dbf),NDX(filter)
CUST1.NDX CUSTNUM  CUSTOMER.DBF F

NTX(

This is an obsolete function identical to NDX(, which refers to the earlier Clipper .ntx file type. The older Clipper NTX indexes are no longer used in Shark.

NUMTOC(

Convert a decimal number to a hexadecimal string.

 NUMTOC(type,number)

type the length of the string to be created number the number to be converted

Type: character

A general conversion function for converting decimal numbers into hexadecimal values. Input can be any number, and the returned string length can be up to eight characters as follows:

The type can be given in either of two forms, a name or number (numeric expression) as follows:

 Type      Range of Number            String Length Returned
   1      integer 0 to 255                  1 byte
   2      integer -32768 to 32767           2 bytes
   4      integer +/- 2 billion             4 bytes
   8      a floating point number           8 bytes
 

Shortcut: When specifying type by name, only the first character is required.

Types 1, 2 and 4 return hexadecimal integers. Any fractional parts are ignored.

When type is 1, this function is equivalent to CHR(. Values outside the range of 0 to 155 return the modulus of 256 for type 1.

The CTONUM(, RANK( and ASC( functions convert strings into numbers.

Do not confuse these function with STR( and VAL(, which convert decimal numbers into their string representations, and vice versa.

Examples:

1>? NUMTOC(1,97)
a
1>? NUMTOC(2,25185)
ab
1>? NUMTOC(4,6513249)
abc

OUT(

Outputs a single character to a sequential file.

OUT(str var [,<filenum>]) 

str var contains the character

Option:

<filenum>  the DOS file number (between 1 and 4) 

Type: logical

This function outputs the character in str var to the sequential file (opened with the WOPEN( function).

If filenum is not given, filenum=1 is assumed. OUT( returns T if successful, F otherwise.

This function is especially useful to communicate over the standard COM1, COM2 devices, for conversion of Word Star or other non-standard files to standard ASCII files, to encrypt/decrypt a file through a translation table.

See the functions IN(, ROPEN(, WOPEN(, CLOSE(, SEEK(, SSEEK(, READ(, and WRITE(.

PIC(

Formats the PICTURE of a number or string.

 
 PIC(exp,format)
                                              
 exp                  is the number or string to be formatted 
 format              the format clause      

Type: character

This function returns the exp formatted with the format clause format. See the command @ for the description of the format clauses. PIC( is especially useful in preparing numeric values for printing.

PIC( always returns a string, even when a number or numeric expression is being formatted.

Examples:

1>number=1123.89
1>format='9,999.99'
1>? PIC(number,'9,999.99')
1,123.89
1>? PIC(number,format)
1,123.89
1>format='9999'
1>? PIC(number,format)
1123
1>format='$$$,$$$.99'
1>? PIC(number,format)
 $1,123.89
1>format='$$$,$$$.999'
1>? PIC(number,format)
 $1,123.890
1>string='abcd'
1>format='xX9!'
1>? PIC(string,'xx9!')
abcD
1>? PIC(string,format)
abcD
1>format='X-X-X-X'
1>? PIC(string,format)
a-b-c-d
1>SET ZERO ON
1> ? 0,"*",str(0,5,2),"*",pic(0,"99.99"),"*","0"
      0.00 *  0.00 *  0.00 * 0
1>SET ZERO OFF
1> ? 0,"*",str(0,5,2),"*",pic(0,"99.99"),"*","0"
           *  0.00 *       * 0


POW(

<num exp1> to the power <num exp2> 

Example:

1>:PICTURE='999.999999'
1>? POW(2,4)
16.00000

PRINTER(

This is an MS-DOS function to test whether a printer is ready to print in an MS-DOS environment.

  
 PRINTER(printernum)                      
 

Option: printernum = the number of the LPT port (1 or 2)

Type: logical

Whenever a program has to print in an MS-DOS environment, it needs a printer turned on and on-line. When it is unsuccessful in printing, Shark intercepts the customary DOS error (the infamous "Abort, Retry, Ignore?") and ends execution.

The PRINTER( function gives programmers a way to ensure the printer is correctly set up before sending output to the screen. This makes it possible to suspend execution under program control, prompt for correction action, or even SPOOL the output to a disk file instead of the printer.

Examples in programs:

  
DO WHILE .NOT. PRINTER()
   WINDOW 10,10,15,69 DOUBLE
   @ 12,10 SAY CEN('Turn on printer and press any key . . .',60)
   RING
   CURSOR 13,39
   cc=INKEY()
   WINDOW
ENDDO
IF .NOT. PRINTER(2)                 ;test LPT2
   SPOOL printfil
ENDIF
IF PRINTER()
   SET PRINT ON
ENDIF

Modern emulators such as vDOS and DOSbox-X can intercept the MS-DOS printer stream and either spool the output to a file, or send it to Windows printer. See the SPOOL command.

PUT(

Puts a string into a DOS file.

 
 PUT(<str exp>[,filenum])

 <str exp>         the string to overwrite with   

Option:

<filenum>         the DOS file number (between 1 and 4) 

Type: logical

A DOS file was opened with the WOPEN( function; the character number pointer was normally positioned with the SEEK( function. This function overwrites the file from the character chosen by the character number pointer with the string <str exp>.

If filenum is not given, filenum=1 is assumed. PUT( returns T if successful, F otherwise.

See also the functions ROPEN(, WOPEN(, CLOSE(, SEEK(, and GET(.

Examples:

1>byte=CHR(13)
1>ok=WOPEN('test',3)
1>ok=SEEK(5221)
1>ok=PUT(byte,3)

RAND(

Gives a random number in the range 0<=n<1.

 
 RAND(seed)
 

Option:

seed = a number used to initiate the random series

Type: numeric

A series of successive calls to the RAND( function will return a uniform distribution of random numbers.

The first time RAND( is called, <seed> (any numeric expression) may be specified. All subsequent calls should be without the seed. If no initial seed is provided, a random seed is chosen by the program.

RAND( always returns a number equal to or greater than 0 and less than 1. If you need a random series of integers between zero and 5000, use 5000*RAND().

Note: if you provide the initial seed, every execution of RAND( ) will return the same series of numbers.

RANK(

Converts a character to its ASCII number.

 RANK(<str exp>)

<str exp> the first character of this string is converted

Type: numeric

The characters in the character set used by the computer are numbered from 0 to 255. For the first character of the string <str exp>, RANK( returns the corresponding number. See also the functions ASC(, CHR(, CTONUM(, and NUMTOC(.

Examples:

1>? RANK('x')
   120.00
1>? RANK('xyz')
   120.00

Note that only the first character of the string matters.

READ(

Reads a line of a sequential file.

 
 READ(str var[,<filenum>])
                                              
 str var      stores the line read in 

Option:

<filenum>      the DOS file number (between 1 and 4) 

Type: logical

This function reads the next line of the sequential file (opened with the ROPEN( function) into the string variable str var. If str var does not exist, it will be created; str var cannot be a matrix variable.

A line is terminated by the carriage return character (ASCII 13). Since the line is read into a string variable, it cannot be longer than 254 characters.

If filenum is not given, filenum=1 is assumed. READ( returns T if successful, F otherwise.

In Shark programs, READ( normally appears in an IF or DO WHILE command.

READ(, IN(, GET(, and WRAP( are the only functions that change the contents of the memory variable used as an argument.

See the functions WRITE(, ROPEN(, WOPEN(, CLOSE(, IN(, OUT(, and SSEEK(.

Examples:

1. In Conversational Shark:

1>ok=ROPEN('a:label.prg')
1>ok=READ(line)
1>? line

2. Two programs to print a text file, TEST (in the second version it is assumed that TEST has no more than 20 lines):

SET WIDTH TO 80
SET PRINT ON
IF ROPEN('test')
   DO WHILE READ(line)
      ? line
   ENDDO
   ok=CLOSE()
ENDIF
DIM CHAR 80 matrix[20]
SET WIDTH TO 80
SET PRINT ON
IF ROPEN('test',1)
   REPEAT 20 times VARYING num
      IF READ(input,1)
         matrix[num]=input,
      ELSE
         BREAK
      ENDIF
   ENDREPEAT
   IF CLOSE(1)
      ? matrix
   ENDIF
ENDIF

RECNO(

Gets the current record number in any open data file.

 RECNO(<filenum>)    

Option:

                                             
 <filenum>    the number of any open data file; default is the selected data file  

Type: numeric

This function returns the record number of the current record of any specified data file; if no <filenum> is given as in recno(), returns the record number the selected file. Note that ? RECNO() displays the current record number in the form specified by the system variable :PICTURE (see Section 2.7).

Shark also has a more limited form of this function, #, which applies only to the selected data file.

Examples:

 
1>USE employee
1>USE#2 customer
1>? RECNO(1)
     1.00
1>GO BOTTOM
1>? RECNO(1)
     6.00
1>GO TOP
1>? RECNO()
     1.00
1>SKIP#2 2
1>? RECNO(2)
     3.00

REMLIB(

Removes a library entry.

REMLIB(volume)

volume the number of the library entry to be removed.

Type: logical

This function deletes a library entry. The function accepts the library volume number you wish to delete as its argument and returns T (true) if the delete operation was successful, F (false) if not.

Once a library entry (volume) is deleted, its space in the library is made available for new text.

Libraries are created with the SET LIBRARY TO command.

Example:

1>? REMLIB(50)
T

REPLACE(

Replaces, in a string expression, all occurrences of a string with another string.

 REPLACE(<str exp>,<str exp1>,<str exp2>)  

Replace in the string expression <str exp> all occurrences of the string <str exp1> with the string <str exp2>

Type: character

This function looks up the first occurrence of . This process continues as long as <str exp1> occurs in <str exp>.

Examples:

1. A field contains a number as right justified characters, padded on the left with blanks. The following REPLACE( changes these numbers to right justified numbers padded on the left with zeros.

1>number='     123'
1>number=REPLACE(number,' ','0')
1>? number
00000123

2. In writing checks, dollar amounts may be left padded with dollar signs:

1>number='     123.11'
1>number=REPLACE(number,' ','$')
1>? number
$$$$$123.11

3. Renaming a variable in a program line. The variable OLDN is renamed FIRSTNUMB.

1>line='newn=oldn+oldn+(oldn/3)'
1>line=REPLACE(line,'oldn','firstnumb')
1>? line
newn=firstnumb+firstnumb+(firstnumb/3)

RESET(

Sets a bit in a string to 0.

 RESET(<str exp>,bit position)
                                              
 <str exp>       the string or string expression on which the  
                   function is to act         
 bit position  the number of the bit, numbered from the left 
                   starting at 1, which is to be set to zero   

Type: logical

A bit is any of the eight binary digits in a character's ASCII number representation. Each bit can have only one of two possible values, 0 and 1.

The SET( and RESET( functions are used to manipulate the bits within a string or string expression. SET( makes a bit 1, and RESET( makes a bit 0. The BIT( function tests the value of a specific bit.

Among the chief uses for these functions is compression of logical (true/false) data by using just one bit for each data item instead of an entire byte for a logical field or two bytes for a logical variable.

See the BIT( function for programming examples.

Examples:

1>str='PS'
1>? BIT(str,15)
T
1>str=RESET(str,15)
1>? str,BIT(str,15)
PQ F

RIGHT(

Gets the right-hand part of a string.

 RIGHT(<str exp>, <num exp>)  

<str exp> the string from which the new string is formed <num exp> the number of characters to place in the new string

Type: character

This function returns the last (that is, the rightmost) <num exp> characters from the string <str exp>.

If <num exp> is greater than the width of <str exp>, this function returns all of <str exp>.

Example:

1>a='David Bark'
1>? RIGHT(a,5)
 Bark
1>? RIGHT(a,50)
David Bark

ROPEN(

Opens a DOS file for reading.

 ROPEN(<str exp> [, <filenum> ])                  
                                              
 <str exp>   the file name

Option:

<filenum>   the DOS file number (between 1 and 4) 

Type: logical

This function opens <str exp>, a DOS file (in particular, a sequential file or input device, such as COM1), for reading only. The current position pointer (see the SEEK( function) is set to the beginning of the file.

If filenum is not given, filenum=1 is assumed. If no file extension is given, the extension TXT is used.

ROPEN( returns T if successful, F otherwise.

See the functions WOPEN(, CLOSE(, READ(, WRITE(, IN(, OUT(, GET(, PUT(,SEEK(, and SSEEK(.

Examples:

1>? ROPEN('a:label.prg')
T

In an Shark program, ROPEN( normally appears in an IF command:

IF ROPEN('file',2)
   DO WHILE READ(data,2)
      ? data
   ENDDO
   ok=CLOSE(2)
ENDIF

ROW(

Gets print row position.

 ROW() 

Type: numeric

In an MS-DOS system, this function gives the current row (line) position of the cursor; if the printer is on, it returns the column position of the printer head. See the commands SET PRINT ON and SET FORMAT TO PRINT, and the function COL(.

Example:

@ ROW()+1,COL()+3 SAY 'Hello'

prints 'Hello' starting on the next line three characters to the right of the end of the last printing.

SEEK(

Goes to a given character number in a plain text file.

 SEEK(<num exp> [,filenum])  

<num exp> the character number

Option:

 <filenum>  a Shark file number (between 1 and 4)

Type: logical

This function repositions the character number pointer in the text file (opened with the ROPEN( or WOPEN( function) to the value given by <num exp>.

If filenum is not given, filenum=1 is assumed. If no file extension is given, the extension TXT is used.

If SEEK( is successful, it returns T (true); otherwise F (false). In a Shark program, SEEK( normally occurs in an IF or DO WHILE command.

Once the character pointer is properly positioned, use the GET( and PUT( functions to manipulate the characters.

Related functions: SSEEK(, ROPEN(, WOPEN(, CLOSE(, GET(, and PUT(.

Example:

1>ok=ROPEN('a:label.prg',4)
1>ok=SEEK(522,4)

SET(

Sets a bit in a string to 1.

 
 SET(<str exp>,bit position)                
                                              
 <str exp>        the string or string expression on which the  
                             function is to act         
 bit position  the number of the bit, numbered from the left 
                             starting at 1, which is to be set to 1   

Type: logical

A bit is any of the eight binary digits in a character's ASCII number representation. Each bit can have only one of two possible values, 0 and 1.

The SET( and RESET( functions are used to manipulate the bits within a string or string expression. SET( makes a bit 1, and RESET( makes a bit 0. The BIT( function tests the value of a specific bit.

Among the chief uses for these functions is compression of logical (true/false) data by using just one bit for each data item instead of an entire byte for a logical field or two bytes for a logical variable.

See the BIT( function for programming examples.

Examples:

1>str='PQ'
1>? BIT(str,15)
F
1>str=RESET(str,15)
1>? str,BIT(str,15)
PS T

SIN(

sine of <num exp> in radians

SINH(

hyperbolic sine of <num exp>

SQRT(

square root of <num exp>

SPACE(

Gets the amount of space left in the data space. SPACE()

Type: numeric

This function returns the available memory in the 64K data space (see Appendix A).

Example:

1>? SPACE()
 27155.00

As a general rule, when SPACE is down to less than 500.00, there is not a lot of room left for code & variables!

SSEEK(

Goes to a given line number in a sequential file.

  
 SSEEK(<num exp> [,<filenum>)                

 <num exp>      the line number    

Option:

                                             
 <filenum>      the DOS file number (between 1 and 4)

Type: logical

This function repositions the line number pointer in the sequential file (opened with the ROPEN( function) to the value given by <num exp>.

If filenum is not given, filenum=1 is assumed. If no file extension is given, the extension TXT is used.

If filenum is not given, filenum=1 is assumed. If no file extension is given, the extension TXT is used.

See the functions SEEK(, ROPEN(, WOPEN(, CLOSE(, READ(, IN(, and OUT(.

Example:

1>ok=ROPEN('a:label.prg',4)
1>line=''
1>ok=SSEEK(5,4)
1>? ok
T
1>ok=READ(line,4)
1>? line
GOTO top
1>ok=SSEEK(900,4)
1>? ok
F

STR(

Type: character

Converts a number to a string.

  
 STR(<num expression>,<width num expression>[,<decimals num expression<])           
                                              
 <num expression>        the number to be converted 
 <width num expression>  the width of the string
 

Example:

1> ? STR(1234,4) 
1>     1234
1> ? STR(1234,12) 
1>             1234

 

Option:

                                              
 <decimals num expression> the number of decimals    

This function gets a number by evaluating the <num expression>, and converts it into a string of given width. Optionally, the number of decimals can be specified (the default is 0). See also PIC(.

Examples:

1>x=123.456
1>? STR(x,8)
     123
1>? LEN(STR(x,8))
     8.00
1>? STR(x,10)
       123
1>? STR(x,10,1); NOTE 'x' is the num expression; '10' is the width of the num expression; and '1' is the number of decimals
     123.4

When combined with the VAL( function, STR( is a convenient way of rounding decimal numbers with a given precision.

For example:

1>:PICTURE='9999.99999'
1>a=29.95748
1>? a
  29.95748
1>? VAL(STR(a+.005,10,2))
  29.96000
1>? VAL(STR(a+.00005,10,4))
  29.95750

SUBSTR(

Type: character

Gets a substring of a string.

  
 SUBSTR(<str exp>, <start num exp>, <width num exp>)
                                              
 <str exp>         the string from which the new string is formed   
 <start num exp>   the position from which the new string is taken                    
 <width num exp>   the number of characters to place in the new string
 

This function, a synonym for the $( function, takes the string in <str exp> from position <start num exp> (fractions are thrown away); the number of characters taken is <width num exp>. (In both numeric expressions, the fractions are disregarded).

Two examples:

1>name='David Barberr'
1>? SUBSTR(name, 7,3); or $(name, 7,3)
Bar
1>? SUBSTR(name, 7,12)
Barberr
1>? LEN(SUBSTR(name,7,12))
      7.00

If date has been formatted as "date(8)":

1>use#1 invoices read
1>brow fields name,invnum,date
1>mdate=substr(date,1,4); or mdate=$(date,1,4)
1>? mdate
2016

Note that SUBSTR(name,7,12) is of width 7, not 12; there are only 7 letters left in name from position 7.

1>s=3
1>t=1
1>? SUBSTR(name+name,(s+t)/2,1.9)
a

Note that 1.9 was taken as 1.

TAN(

tangent of <num exp> in radians

TANH(

hyperbolic tangent of <num exp>

TEST(

Tests a string whether it is a valid expression.

TEST(<str exp>)                              
                                              
 <str exp> the string to be tested 

 Type: logical

This function tests the string in <str exp> as to whether it is a valid expression; in particular, all variables must be defined and must be of the proper type. It returns T if it is, F otherwise. If the test is successful, TYPE( can be used to find the type of the expression.

In a Shark program, use TEST( to find out whether a selection criteria typed in by the user is correct. Or use it to ensure that a variable exists in a subroutine that may be called from several programs.

Examples:

1>? TEST('check=0')
F                                   false because check is not defined
1>check=0
1>? TEST('check=0')
T
1>? TEST('check=0.or.check=1')
T
1>? TEST('check="A".or.check=1')
F                                   false because "A" is of character
                                    type
1>? TEST('num')
F
1>num=5
1>? TEST('num')
T
1>? TEST('num+')                    false because the second operand
                                    is missing
F
IF .NOT. TEST('check')
   check=0
ENDIF

TIME(

Gets the system time.

  
 TIME(type)

Option:

                                              
 type      one of three types of information requested, as listed below    

Type: character

This function returns a string containing the current system time, and changes the format of the system variable :TIME to this format. (See the system variable :TIME in Section 2. Recall that :TIME is initialized when Shark starts up, but can be reinitialized with a :TIME= command.)

The type can be given in either of two forms, a name or number (numeric expression) as follows:

Type                Explanation                                      Example
1 or HMS         Hours,minutes,seconds,hundredths                17:26:36.07
2 or AMPM        Hours,minutes with AM/PM                        5:36 pm
3 or Seconds     Seconds since midnight                          62804.80

Shortcut: When specifying type by name, only the first character is required. The default parameter is 1, the time in the 24-hour format hh:mm:ss.hh.

Examples:

1>? :TIME
15:45:59
1>? TIME(2)
 3:46 pm
1>:TIME
 3:46 pm
start=VAL(TIME(seconds))
program lines
finish=VAL(TIME(seconds))
? 'Program execution took',start-finish,'seconds.'

This displays how long the running of <program lines> took, in seconds.

TRIM(

Trims blanks from the right-hand side of a string.

  
 TRIM(<str exp>)                              
                                              
 <str exp>        the string to be trimmed  

Type: character

Shark stores strings in fields padded on the right with blanks. In actual use, these blanks may get in the way. TRIM( gets rid of the blanks on the right of a string. TRIM( can be used in the key of an index. See also LTRIM( .

Examples:

1>a='Vancouver     '
1>b='BC'
1>? a+','+b
Vancouver     ,BC
1>? LEN(a)
    14.00
1>? trim(a)+','+b
Vancouver,BC
1>? LEN(TRIM(a))
     9.00
1>blank='     '
1>? LEN(TRIM(blank))
     1.00

Note: TRIM(blank) is a single blank.

TYPE(

Gets the type of an expression.

 TYPE(exp)

exp = any expression

Type: character

For an expression, exp, this function returns the type of the expression as a one character string:

C    for character
L    for logical
N    for numeric
M    for memo 
F    for float      ;a type used by other xBase languages; treated as N internally
D    for date       ;a type used by other xBase languages; treated as C internally
U    Undefined      ;created by GLOBAL or VARIABLES command, but not yet given
                     a value or type

To test whether a string is a valid expression, use the TEST( function.

Examples:

1>a='name'
1>? TYPE(a)
C
1>? TYPE(a+a)
C
1>n=12
1>? TYPE(a+n)
1. Invalid variable type found when executing an expression.
1>? TYPE(a<a)
L
1>? TYPE(a<a .OR. n<5)
L
1>? TYPE(note)
M
1>? TYPE(date)
D
1>TYPE(n+5/10)
N

UPPER(

Converts a string to upper case.

 
 UPPER(<str exp>) 

<str exp> = the text to be converted to upper case

Type: character

All lower-case letters in the <str exp> are converted into upper case by the UPPER( function, which is a synonym for the !( function. See also the LOWER( function.

Examples:

 
1>a='Aa12b'
1>? UPPER(a)
AA12B
1>? UPPER('David!')
DAVID!
Note that only the lower-case letters are changed.

VAL(

Converts a string to its numeric value.

VAL(<str exp>)
                                              
 <str exp>      the string to be evaluated   

Type: numeric

This function takes the string <str exp> which is a number, and returns it as a number. If the whole string cannot be interpreted as a number, it takes as much of the front part as it can.

Examples:

1>a='123.23'
1>? VAL(a)
   123.23
1>? VAL(123.23)
1. Invalid variable type found when executing an expression.
1>? VAL('a12')
     0.00
1>? VAL('12a')
    12.00
1>? VAL(DATE(2))
yields the current month as a number.

WOPEN(

Opens a DOS file for writing.

  
 WOPEN(<str exp>[,<filenum>])                 
                                              
 <str exp>      the file name

Option:

<filenum>      the DOS file number (between 1 and 4)          

 Type: logical    

This function opens the DOS file, and in particular, the sequential file <str exp> (or output device, such as COM1:) for writing; if the file does not exist, it will be created. If filenum is not given, filenum=1 is assumed. If no file extension is given, the extension TXT is used. It returns T if successful, F otherwise.

See the functions ROPEN(, CLOSE(, GET(, PUT(, SEEK(, SSEEK(, WRITE(, READ(, IN(, OUT(.

Example:
1>ok=WOPEN('a:label.prg')
1>? ok
T

In an Shark program, WOPEN( normally appears in an IF command:

IF WOPEN('file',2)

2. Two programs to print a text file, TEST (in the second version it is assumed that TEST has no more than 20 lines):

SET WIDTH TO 80
SET PRINT ON
IF ROPEN('test')
   DO WHILE READ(line)
      ? line
   ENDDO
   ok=CLOSE()
ENDIF

WRAP(

Wraps DOS text for output in a DOS system.

 WRAP(str var, <num exp>)                   
                                              
 <str exp>        the string to be wrapped    
 <num exp>        the line width   

Type: character

This function returns one line of text with word wrapping from the string in str var; str var now contains what is left of the string. In other words, the string returned will contain as many words as will fit in a line (the line width is given by <num exp>). If the whole contents of str var is one line, str var becomes the blank string (of length 1)

WRAP(, IN(, GET(, and READ( are the only functions that change the contents of the memory variable used as an argument.

Examples:

1>text='This text line is going to be wrapped in a printed line of width 30.'
1>? text
This text line is going to be wrapped in a printed line of width 30.
1>temp=text
1>WRAP(temp,30)
This text line is going to be
1>? temp
wrapped in a printed line of width 30.
1>WRAP(temp,30)
wrapped in a printed line of
1>? temp
width 30.
1>WRAP(temp,30)
width 30.
1>? temp
1>? LEN(temp)
     1.00

WRITE(

Writes a new line into the sequential file.

 WRITE(str var[,<filenum>])                 

 str var   the line to be written  

Option:

<filenum>      the DOS file number (between 1 and 4)  

Type: logical

This function writes (appends) the contents of the string variable str var to the end of a sequential file opened with the WOPEN( function.

If filenum is not given, filenum=1 is assumed. WRITE( returns T if successful, F otherwise. See the functions ROPEN(, WOPEN(, READ(, IN(, OUT(, GET(, PUT(, and CLOSE(.

Example:

1>ok=WOPEN('customer.frm',2)
1>ok=WRITE('FIELDS - cust,orderno,amount',2)
1>ok=CLOSE(2)

Or:

creates the CUSTOMER.FRM report form file containingf a single line as follows:

FIELDS - cust,orderno,amount

Now, assuming the CUSTOMER file is currently in use, the command REPORT CUSTOMER will run the report. This example illustrates how a program can be written that creates a report form file. In an Shark program, WRITE( normally appears in an IF command:

IF WRITE('file',2)