ML Functions

From Color 64 BBS Wiki

Programming Features - ML Functions

The ML functions are used where the ML commands and ML variables will not be able to perform more complex operations. Simply put, a function is like a variable that can perform a subroutine before returning a computed value. Some functions also have parameters which are used to perform the function's specific operation. Since the ML variables cannot return string values, the functions also take care of this need as well.

All functions begin with an "@" at sign, followed by one or two digits (the function number). Functions are either string or numeric functions, as will be indicated. Some functions have parameters that are required and/or optional; parameters are included in parenthesis after the function number.

Example:

1000 a$=@5:sr=st:a=val(a$):ifa<>0thenprint@1(a) 
1010 ifsr=.then1000     

The above example would perform the following:

  • Use the function @5, which reads in a line of disk data like the .01 command and then returns the line of data as its value.
  • Then the routine tests to see if what was read in was numeric characters. If it was then it will use the @1 function to print the value of the input without a leading space.
  • The routine continues reading in data until the end of the file.

The table below lists the ML Functions and descriptions.

ML Function Descriptions
Function Format and Description
@0 Format: @0 : STRING

This is the equivalent of LEFT$(TX$,!40). This is used for when lines are returned from disk input (.01) or from key input (.02).

Example: .01:A$=@0

@1 Format: @1( <number> ) : STRING

This returns the equivalent of STR$(<number>), but it will not include the leading blank that accompanies positive numbers.

Examples:

@1(500) will return the string "500"

@1(-10) will return the string "-10"

This is better than MID$(STR$(<number>),2) because it will not strip a negative sign.

@2 Format: @2( <string1> , <string2> [ , <number> ] ) : NUMERIC

This will search for and return the position of <string1> inside <string2>, searching from the first character to the end of <string2>. If <string1> cannot be found in <string2>, then 0 is returned. If you include <number>, then the @2 function will return the position of the <number> occurrence of <string1> in <string2>. If <number> is 0, then the @2 function will return the number of occurrencess of <string1> in <string2>.

Examples:

  • @2("b","abc”) would return 2, the position of b in abc
  • @2("b","def") would return 0, because b is not in def
  • @2("b","abcdabc",2) would return 6, the position of the second b
  • @2("b","bobby",0) would return 3, the number of b's in bobby

The !52 variable will contain the value of the most recent find but will be 0 if the find command was used to find the number of occurances of <string1>.

@3 Format: @3( <string> , <number> ) : STRING

This function returns a string with <number> characters of the first character of <string>. Example: @3("A",5) would return the string "AAAAA".

<number> can range from 0 to 255. If the string is a null string, then a null will be returned.

@4 Format: @4 : STRING

This function is for input from the modem and returns a character as if you had used a GET statement.

Example: A$=@4. If there are no characters in the modem input buffer, then a null (nu$) will be returned.

@5 Format: @5 : STRING

This is the same as the @0 function, except it executes a .01 (get line from disk) command before returning the string.

Example: A$=@5:SR=ST:PRINT#9,A$;

@6 Format: @6( <string1> [ , <string2> ] ) : NUMERIC

This is an extended ASC function. Its operation varies depending on the number characters you use in each string (regardless of if you use two strings or not).

Here is a table of the possible outcomes:

  • One string, length of 0 or 1:
This will return the PET ASCII value of <string1>, and will return 0 if it is a null string (not an error like ASC).
Example: GET#8,A$:I=@6(A$)
  • One string, length of 2:
This will return the 16-bit value of the string. The formula is 256*<2nd char> + <first char> using the characters' appropriate PET ASCII values.
Example: IFLEN(I$)=2THENL=@6(I$)
This version is not as useful as the next one:
  • Two strings, any lengths:
This is useful for when a GET# command reads from disk two characters which represent the low and high byte of a 16-bit value. <string1> represents the low-byte character, and <string2> represents the high-byte character.
Example: GET#8,A$,B$:L=@6(A$,B$)
L would contain the 16-bit value of the 2-byte input. Only the first character of each of these strings will be used in the calculation. If a string is a null string, then its value is considered zero.
@7 Format: @7( <number> ) : STRING

This is an extended CHR$ function. It will return a two-character string representing the low and high bytes of <number>, respectively. This is useful for the relative file positioning command.

Example: PRINT#15,"p"CHR$(104)@7(RN)CHR$(1)

@8 Format: @8 : STRING

This is the same as @0, except it executes an .02 (Get keyed line of input) command before returning the string.

Example: I$=@8:P=!01:IFP=0THENRETURN

@9 Format: @9 : NUMERIC

An enhanced FRE function. This returns the amount of free memory as a positive number (unlike how FRE sometimes returns a negative number). This routine does not perform a garbage collection (the slow delay often accompanying using the FRE function), but instead uses a routine that calculates free memory accurately.

Example: I=@9:IFI>3000THENRETURN

@10 Format: @10( <string> [ , <number> ] ) : STRING

This function returns <string>, but with all graphics control characters stripped from it. This is useful for determining the exact width of the set of normal characters in the string (for centering, etc.). If you include <number>, then only the first <number> characters will be returned, just like the LEFT$ function. <number> can range from 0 to 255. Example: A$=@10(@0,15)

@11 Format: @11 : STRING

This function returns the current time in the format "HH:MM am" or "HH:MM pm", where HH is the current hour and MM is the current minute. The !45 and !44 variables are also changed. !45 will contain the hour, and !44 will be 0 if the time is AM, or non-zero if the time is PM.

@12 Format: @12( <string1> , <string2> , <number> ) : STRING

This function returns a string that is <string2> with <string1> overlayed (replacing existing characters) at position <number>. <number> can range from 1 to 255. If the strings do not overlap, then the space in between them will be padded with spaces.

Examples:

  • @12("there","Hello",7) will return the string "Hello there"
  • @12("*","++++++++",4) will return "+++*++++"

The @12 function can also be used in conjunction with the @2 and @25 search-string functions as a "search and replace" function. If 0 is used for <number> in the @12 function, then the value of the MOST RECENT @2 or @25 function will be used. If that value is 0, then an ILLEGAL QUANTITY error will occur. Also, if the @2 or @25 function was used to find the number of occurrences of a string rather than the position, then an error will occur.

Example of the replace function:

1000 IF @2(".",I$)>0 THEN I$=@12("/",I$,0):GOTO 1000

The above routine will keep replacing all the "." characters in I$ with a “/" character until no more are found. See lines 2400-2403 in √bbs.msgs (the routine that sifts merged messages for unauthorized MCI usage) for an example of the use of the @12 function.

@13 Format: @13 : STRING

This function is used in the crash routine to determine what the BASIC error message was at the crash.

@14 Format: @14 : STRING

This function is also used in the crash routine. It returns the error line number as a string.

@15 Format: @15( <year> , <month> , <day> ) : NUMERIC

This function returns an ADN (absolute day number) using the year, month, and day parameters. If either the year, month, or day is invalid, then negative one is returned.

@16 Format: @16( <number> ) : NUMERIC

This function converts the ADN in <number> to a date and returns the YEAR of the date. The month and day are returned in the !43 and !42 variables, respectively. If the ADN is invalid, then the results will be unpredictable.

@17 Format: @17( <number> ) : NUMERIC

This function returns the day of the week using the ADN in <number>. The value will be 0 to 6 for Sunday through Saturday.

@18 Format: @18( <number> ) : STRING

This function will return a string in the format "MM/DD/YYYY" using the AND in <number>. If the ADN is invalid, then the string "--/--/----" will be returned.

@19 Format: @19( <string> ) : NUMERIC

<string> is a date in the format "MM/DD/YYYY". This function will return the ADN calculated from <string>. If the date is invalid, then the function will return negative 1.

@20 Format: @20 : STRING

This function returns the file name of the BASIC overlay currently in memory. It is used by the crash routine to get the name of the current overlay.

@21 Format: @21( <string> ) : STRING

This function returns a string that is <string> stripped of all characters that are not alphabetic. It will also convert any uppercase letters to lowercase.

Example: @21("This Is A Test") would return "thisisatest".

This function is used for the password file to enable a search for users who have uppercase characters and graphics in their username.

@22 Format: @22( <number> ) : STRING

This function will return a special compressed version of <number> for writing to a disk file. It is like a STR$ function, but packs two digits into each byte, cutting the length of the string in half.

Programmer's note: This does NOT convert the number to BCD (Binary Coded Decimal). Rather, it uses a special method to avoid ever creating a carriage return character in the string (because such a character would not enable the compressed number to be read in from disk).

Example: PRINT#8,@22(I)

@23 Format: @23( <string> ) : NUMERIC

This function performs the opposite of the @22 function and uncompresses the number stored in <string>. An invalid string will cause unpredictable results.

Example: INPUT#8,I$:I=@23(I$)

@24 Format: @24( <string> , <number> ) : STRING

This function is used to pad relative file records to get them ready to print to disk.

If <string> is less than <number> characters in length, then <string> will be returned with enough carriage returns padded on the end to make it <number> characters in length.

If <string> is the same as or more than <number> characters in length, then <string> will be truncated to <number> minus one character, and a carriage return will be added, so the resulting string will be <number> characters in length.

If <string> is a null, or <number> is less than 2 characters, then there will be unpredictable results:

Example: F$=F$+@24("name",15)

@25 Format: @25( <string1> , <string2> [ , <number> ] ) : NUMERIC

This works the same as the @2 function, except the search for the string proceeds from the END of <string2> to the beginning (backwards).

@26 Format: @26( <string1> , <string2> , <number> ) : STRING

This function returns the <number> section of <string2> separated by the character in <string1>.

Example: @26("!","cp6!i6!cd//directory",2) would return "i6", because the "!" is the separator character, and "i6" is the second section divided off by the "!" character.

This function is used by the drive command routine for dividing up the drive command into its sections. If <number> is 0, then an error will result.

@27 Format: @27( <number1> , <number2> ) : NUMERIC

This function calculates the calendar age from two ADN's. The age is the number of calendar years from the ADN in <number2> to the ADN in <number1> (like subtracting <number2> from <number1>).

For example, to calculate someone's age on the BBS system, the formula would be: age=@27(DA,BD) where DA is the system date ADN, and BD is the birth date ADN.

@28 Format: @28( <string> , <array> ) : NUMERIC

This function is a search function which will search through an array to find <string>. <array> is the name of a one-dimensional string array, but the name should not include either the $ character or the array parenthesis (e.g. the string array "a$()" would simply be "a"). The function will return the index of <array> where the string was found. If the string is not found, will return a negative one. The function will search through the entire array, and the string must match the array element exactly. If <array> is not found in memory or is more than one dimension, then an error will result.

Example: I=@28(A$,A):IFI<0THEN#"not found!"

@29 Format: @29( <number> ) : STRING

This function is like @5, except that <number> is how many characters you want read in. It is a viable alternative to the GET# command in some cases. It does not check for End of File and it does not stop at the End of Line character stored in !04.

@30 Format: @30( <number> ) : STRING

This function is used in conjunction with the variables !49, !50, and !51. It returns the drive init command for one of the three boot drives: 0=Boot drive, 1=Program drive, 2=External drive.

Next section: Basic Variables Table

Programming Features