More actions
StackFault (talk | contribs) Created page with " The Mystic BBS Programming Language Documentation Copyright (C) 1998-2015 By James Coyle. All Rights Reserved All mentioned programs are copyrighted by thei..." |
StackFault (talk | contribs) No edit summary |
||
(2 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
The Mystic BBS Programming Language Documentation | |||
Copyright (C) 1998-2015 By James Coyle. All Rights Reserved | |||
All mentioned programs are copyrighted by their respective authors | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
''' Introduction to Mystic Programming Language (MPL) ''' | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
The Mystic Programming Language (refered to as MPL from here on out) is | |||
not complete. In the state that it's in now, its still more powerful | |||
than most BBS script languages, but its still not to the point where | |||
it is as powerful as it should be. | |||
The documentation for the MPL is also not complete. This documentation | |||
as well as the Mystic BBS documentation will be worked on as time | |||
permits and may not be completed for quite some time. There are some | |||
example programs included with the distribution (found in the scripts | |||
directory) which may help assist you in getting the hang of the MPL | |||
structure and commands. | |||
If you have written any useful MPL programs, please send them via e-mail | |||
to [email protected] so they can be included for download on the | |||
various Mystic BBS support sites. | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
''' General Notes About Using The MPL ''' | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
The syntax of the Mystic BBS Programming Language follows closely to | |||
that of the Turbo Pascal series of programming compilers. At one time, | |||
the language was almost 100% Turbo Pascal compatible (except for the | |||
BBS functions) but it has been slightly changed to make it a little | |||
more friendly to the programmer. | |||
Two versions of the programming compiler are available in the scripts | |||
directory. The first one, MIDE.EXE, is a fully functional IDE for | |||
creating and compiling MPE programs. This program looks similar to the | |||
Turbo Pascal IDE, including syntax highlighting of all command keywords! | |||
The second version of the compiler is MPLC.EXE. This is a command line | |||
compiler supplied so you are not forced to use MIDE.EXE to write | |||
programs. If you do not find the MIDE interface to be satisfactory, then | |||
you can use your favorite text editor and MPLC.EXE to create programs! | |||
The following are some quick notes about the syntax of the language as | |||
well as some notes about things that aren't working as they probably | |||
should be: | |||
'''1. All text after a number sign (#) is considered a comment. It will ''' | |||
''' be ignored until the next line of code. For example: ''' | |||
WriteLn ('Hello There') # This is a comment and will be ignored. | |||
''' 2. Operation types: ''' | |||
The MPL does not follow the order of operations when doing | |||
mathmatical equations (ie PEMDAS - parenthesis, exponents, | |||
multiplication, division, addition, subtraction). So math | |||
functions are done in the order that they appear in the expression. | |||
This doesn't mean its not POSSIBLE to do PEMDAS-ordered expressions, | |||
it will just take a little more effort on the programmer's behalf. | |||
The following operation codes are supported for mathmatical | |||
equations: | |||
- Subtract | |||
+ Addition | |||
* Multiplication | |||
/ Division | |||
% Modulus Operator | |||
''' 2a. Bitwise math: ''' | |||
MPL fully supports bitwise math and operators! The following are | |||
implemented: | |||
AND - Bitwise AND | |||
OR - Bitwise OR | |||
XOR - Bitwise exclusive OR | |||
SHL - Bitwise shift left | |||
SHR - Bitwise shift right | |||
''' Example: ''' | |||
Const | |||
UserDeleted = $04; // established bit for userdeleted from records.pas | |||
// note: this value has changed check records.pas! | |||
Begin | |||
GetThisUser | |||
If UserFlags AND UserDeleted <> 0 Then | |||
WriteLn('User is deleted'); | |||
End; | |||
3. Defining variables: All variables are global to all of the program, | |||
including procedures. The syntax for declaring a variable follows: | |||
Var <VarName> : <VarType> | |||
Examples: | |||
var dummy : byte | |||
var str : string | |||
var | |||
dummy : byte, | |||
str : string | |||
The following variable types are supported: | |||
Type Format Range | |||
--------------- -------------- ----------------------------------- | |||
Boolean FALSE/TRUE 0..1 | |||
Char Text 1 character | |||
String Text Sequence of 1..255 characters | |||
Byte Numerical 0..255 | |||
Integer Numerical -32767..32767 | |||
Word Numerical 0..65535 | |||
LongInt Numerical -2147483648..214748364 | |||
Real Numerical 9.99 | |||
All variables exept ARRAYs can be initialized when when defined. | |||
Var TotalBases : LongInt = GetMBaseTotal(False) | |||
Var Int : Integer = 33 | |||
Var Str : String = 'This is a string' | |||
ARRAY multi-dimensional variables are supported. The syntax for | |||
declaring an array variable is: | |||
<nowiki> Var <VarName> : ARRAY[<Low>..<High>] of <VarType></nowiki> | |||
<nowiki> Var <VarName> : ARRAY[<L>..<H>, <L>..<H>] of <VarType></nowiki> | |||
<nowiki> Var <VarName> : ARRAY[<L>..<H>, <L>..<H>, <L>..<H>] of <VarType></nowiki> | |||
''' Examples: ''' | |||
<nowiki> | <nowiki> Var Dummy : Array[1..10] of Byte</nowiki> | ||
<nowiki> | <nowiki> Var Str : Array[5..10] of String</nowiki> | ||
<nowiki> Var Int : Array[1..10,1..10,1..10] of Integer</nowiki> | |||
HEXIDECIMAL values are supported. They can be used in numeric | |||
variable assignment numerical evaluation, and in numeric constant | |||
variables. A hex value must begin with a $ character. | |||
Some examples: | |||
Const | |||
MyHexValue = $1F; | |||
Value := $10; | |||
If Value = $10 Then WriteLn('Value is 16 <in decimal>'); | |||
''' 3b. Record structures: ''' | |||
Groups data in to records. This command | |||
allows you to create a datatype of multiple different variable | |||
types. | |||
Defining the record: | |||
Type | |||
testrec = record | |||
x : byte; | |||
y : byte; | |||
<nowiki> d : array[1..10,1..5] of string[9]</nowiki> | |||
end | |||
Declaring the record: | |||
Var struct : testrec | |||
Using the record: | |||
struct.x:=1 | |||
struct.y:=10 | |||
struct.d[1,1]:='abc123' | |||
3c. CODE BLOCKS: When using multiple lines (more than one line) within a | |||
IF/ELSE/WHILE/CASE blocks, the lines need to be grouped into | |||
blocks between BEGIN and END statments. If there is only one line | |||
following the IF/ELSE/WHILE/CASE blocks, then no blocking statements | |||
are needed. | |||
Examples: | |||
If X = 1 Then | |||
Begin | |||
WriteLn('X = '+Int2Str(X)) | |||
X:=X+1 | |||
WriteLn('X = '+Int2Str(X)) | |||
End | |||
The same is true for the ELSE block. | |||
If X = 1 Then | |||
Begin | |||
WriteLn('X = '+Int2Str(X)) | |||
X:=X+1 | |||
WriteLn('X = '+Int2Str(X)) | |||
End | |||
Else | |||
Begin | |||
WriteLn('X = '+Int2Str(X)) | |||
X:=X-1 | |||
WriteLn('X = '+Int2Str(X)) | |||
End | |||
4. FOR LOOPS (FOR/FEND): The syntax for a for loop is as follows: | |||
For <variable> := <start number> <TO> or <DOWNTO> <end number> Do. | |||
For A := 1 to 10 Do | |||
WriteLn (A) | |||
For A := 10 DownTo 1 Do | |||
Begin | |||
WriteLn (A) | |||
WriteLn (A) | |||
End | |||
5. REPEAT/UNTIL: The syntax for a repeat until loop is as follows: | |||
Repeat | |||
<nowiki><Code here></nowiki> | |||
Until <Boolean Expression> | |||
IE: | |||
Repeat | |||
WriteLn ('Blah blah') | |||
Until A > 0 or A = 5 | |||
6. WHILE: The syntax for a while loop is as follows: | |||
While <Boolean Expression> Do | |||
<nowiki><Code Here></nowiki> | |||
IE: | |||
While A > 0 and A = 5 Do | |||
WriteLn ('Blah') | |||
OR: | |||
While A > 0 and A = 5 Do | |||
Begin | |||
WriteLn ('Blah') | |||
WriteLn ('More Blah') | |||
End | |||
7. PROCEDURES: The syntax for defining a procedure is as follows: | |||
Procedure <Proc Name> (<varname vartype>, <varname vartype>) | |||
<nowiki><Code here></nowiki> | |||
IE: | |||
Procedure Hello_World | |||
WriteLn ('Hello World') | |||
OR: | |||
Procedure SomeProc (Str String, A Byte) | |||
WriteLn ('Str = ' + Str) | |||
WriteLn ('A = ' + A) | |||
End | |||
OR: | |||
Procedure SomeProc (Str String) | |||
Var | |||
Str2 : String, | |||
Str3 : String | |||
Begin <--- The keyword "BEGIN" is ignored by the compiler | |||
WriteLn (Str) just to maintain a "Pascal-like" feel. | |||
End | |||
8. IF THEN/ELSE/END: The syntax of an if/else/end statement: | |||
If <boolean statement> Then | |||
<True code here> | |||
Else If <boolean statement> Then (optional) | |||
<True code here> | |||
Else (optional) | |||
<False code here> | |||
If Not fEof(fptr) Then | |||
WriteLn (<nowiki>'We''re not at the end of the file.'</nowiki>) | |||
The above example is the same as the following example, except we've | |||
added an else statement: | |||
If fEof(fptr) = False Then | |||
WriteLn (<nowiki>'We''re not at the end of the file.'</nowiki>) | |||
Else | |||
WriteLn ('This is the end of the file.') | |||
If A = 1 Then | |||
WriteLn ('A is 1') | |||
Else If A = 2 Then | |||
WriteLn ('A is 2') | |||
Else If A = 5 Then | |||
WriteLn ('A is 5') | |||
Else | |||
WriteLn ('A is not 1, 2, or 5...') | |||
8a. CASE statements | |||
This has actually been expanded on | |||
from the Pascal standard but still follows the same syntax. It has been | |||
expanded to allow CASE of more variable types, such as strings. See | |||
the included MPLTEST.MPS for examples. | |||
Var I : Integer = 10 | |||
Case I Of | |||
1 : WriteLn('I = 1') | |||
2 : Begin | |||
I:=I+1 | |||
WriteLn('I = 3') | |||
End | |||
2,3,4,5,6,7,8,9: WriteLn('Not 1, 2, or 10') | |||
End | |||
Var S : String = 'ABCDEFG' | |||
Case S[3] Of | |||
'A': WriteLn('S[3] = '+S[3]) | |||
'B','C','D': WriteLn('S[3] = '+S[3]) | |||
Else | |||
WriteLn('This is the default choice') | |||
End | |||
9. The USES command must be declared before ANY other variables | |||
or your program may not function properly. See documentation for | |||
the USES command for further information. | |||
10. FUNCTIONS: The syntax for defining a function is as follows: | |||
Function <Function Name> (<varname vartype>) : <result type> | |||
IE: | |||
Function AddTen (Num Byte) : Byte | |||
Begin | |||
AddTen := Num + 10 | |||
End | |||
11. CONST VARIABLES: The syntax for a constant variable is as follows: | |||
String constants: | |||
Const | |||
SomeStr = 'Hello World!' | |||
Numerical constants: | |||
Const | |||
SomeNum = 69 | |||
Constant variables, like regular variables, can be separated with a | |||
comma: | |||
Const | |||
SomeNum = 69, | |||
SomeStr = 'Hello World!' | |||
At the moment, constant variables cannot be used in certain places | |||
within the MPE engine. If you are assigning a value to a variable, | |||
constant values will not be recongnized. | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
General Functions and Procedures | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
Function ABS (Num: LongInt) : LongInt | |||
This function takes a signed integer and returns the absolute value. | |||
Example: | |||
Var Int : LongInt = -1234 | |||
WriteLn('The absolute value of '+Int2str(Int) +' is '+Abs(Int)+'.') | |||
Function ALLOWARROW (Boolean) | |||
Used to turn on arrow key processing in the READKEY function. It is | |||
also used outside of MPL so use with caution. | |||
Example: | |||
AllowArrow := True | |||
ReadKey | |||
Variable ALLOWMCI (boolean) | |||
This function toggles on/off MCI code parsing. This is used outside of | |||
MPL so adjust this with caution. | |||
Procedure APPENDTEXT (FileName, Text: String). | |||
This procedure will append a single line of text onto a text file. If | |||
the file does not exist, it will be created. Example: | |||
Function BITCHECK (B : Byte; I : Integer) : Boolean | |||
This function accepts a bit position and checks it against an integer, | |||
returning true or false if the bit is on. So for example in the | |||
Records, the third bit in UserFlags is UserDeleted: | |||
GetThisUser | |||
If BitCheck(3, UserFlags) Then WriteLn('User is marked deleted'); | |||
Procedure BITSET (B : Byte; I : Integer) | |||
This procedure accepts a bit position and an integer and sets the | |||
bit ON/OFF based on a boolean: | |||
GetThisUser | |||
BitSet(3, UserFlags, True); // user is marked as deleted | |||
Procedure BITTOGGLE (B : Byte; I : Integer) | |||
This procedure accepts a bit position and an integer and toggles the | |||
bit. | |||
GetThisUser | |||
BitToggle(3, UserFlags); // undeletes if they are deleted or deletes if | |||
// they are not deleted. | |||
Variables CFGCHATSTART CFGCHATEND. | |||
These return the byte of the chat hour start and end variables from the | |||
System Configuration | |||
Procedure CLRSCR | |||
This function will clear the screen. | |||
Example: | |||
CLRSCR | |||
Writeln ('The screen was just cleared.') | |||
The above function will clear the screen and write the text "The | |||
screen was just cleared." to the screen. | |||
Function DATE2DOS (Str : String) : LongInt | |||
This function takes a MM/DD/YY format date and converts it to | |||
DOS packed datetime format. | |||
Var DStr : String = '01/01/14' | |||
Var PDt : LongInt | |||
PDt := Date2Dos(DStr) | |||
Function DATE2JULIAN (Str : String) : LongInt | |||
This function takes a MM/DD/YY format date and converts it to a | |||
Julian date format. | |||
Function DATEG2J (Str : String) : LongInt | |||
This function takes a gregorian date format (MMDDYY) and converts | |||
it to a Julian format | |||
Function DATEJ2G (LI : LongInt) : String | |||
This function takes a julian date format and converts it to a | |||
gregorian format (MMDDYY). | |||
Function DATEJULIAN : LongInt | |||
This function returns the Julian value of the current date. | |||
Function DATESTRJULIAN (JD : LongInt) : String | |||
This function returns the MM/DD/YY string value of the julian date. | |||
Function DATEVALID (Str : String) : Boolean | |||
This function takes a MM/DD/YY date and returns true or false | |||
depending on if the date is valid (ie, month is 01-12, etc). | |||
Function DAYOFTHEWEEK | |||
Returns a number between 0-6 depending on the day of the week: | |||
0 = Sun, 1 = Mon, 2 = Tue, 3 = Wed, 4 = Thu, 5 = Fri, 6 = Sat | |||
Function DAYSAGO (JD : LongInt) : Integer | |||
This function takes the Julian date value and returns the number | |||
of days between the current date and the passed date. | |||
Function DAYOFWEEK : Integer | |||
This function will return a number between 0-6 depending on the | |||
day of the week: | |||
0 = Sun, 1 = Mon, 2 = Tue, 3 = Wed, 4 = Thu, 5 = Fri, 6 = Sat | |||
Procedure DELAY (MS: Word) | |||
This procedure will delay for a specified number of milliseconds. | |||
Example: | |||
DELAY (1000) | |||
The above example will delay the program for one second. | |||
Function DOSERROR : Byte | |||
This function returns the current DosError and is used with the | |||
FindFirst and FindNext functions. The possible values which may | |||
be returned by DosError are as follows: | |||
Value Meaning | |||
----- --------------------- | |||
0 No error | |||
2 File not found | |||
3 Path not found | |||
5 Access denied | |||
6 Invalid handle | |||
8 Not enough memory | |||
10 Invalid environment | |||
11 Invalid format | |||
18 No more files | |||
----- --------------------- | |||
Example: | |||
FindFirst ('*.*', AnyFile) | |||
While DosError = 0 Do Begin | |||
WriteLn ('File Name: ', DirName) | |||
FindNext | |||
End | |||
FindClose | |||
The above example will list all files in the current directory. | |||
The DosError function is used to return when there are no more | |||
files to be listed. For more information on this see the reference | |||
for the FindFirst and FindNext functions. | |||
Procedure FINDCLOSE | |||
This function is used along with the FindFirst and FindNext | |||
functions. It is called only after all "Find" procedures have | |||
completed. See the "FindFirst" and "FindNext" command references | |||
for more information. | |||
Procedure FINDFIRST (Mask : String, Attributes) | |||
This function is used to search a drive for files using a supplied | |||
file mask and attribute list. The results of the search are held | |||
in the DIR variables as listed below. | |||
Mask : The mask variable must contain at least a file mask | |||
(ie "*.*") but can also contain a drive and directory name | |||
as well (ie "C:\MYSTIC\TEXT\*.*"). | |||
Attributes : The file attributes are used to specify what type of | |||
files to return in the DIR variables. The following | |||
is a list of supported file attributes: | |||
Dec Description Returns | |||
--- ----------- ----------------- | |||
001 ReadOnly files marked as "read only". | |||
002 Hidden files marked as "hidden". | |||
004 SysFile files marked as "system files". | |||
008 VolumeID files marked as "volume ID". | |||
016 Directory files marked as "directory". | |||
032 Archive files marked as "archive". | |||
066 AnyFile any and all files. | |||
These attributes can be combined when passed to | |||
FindFirst. For example: 1 + 2 will return | |||
any files which have been marked as "readonly" OR | |||
"hidden". Example: 16 (DIRECTORY) will only return names | |||
of directories. | |||
DIR Variables : The DIR variables are what contain the information | |||
returned by the FindFirst command. If your program | |||
is going to use these variables, it must be declared | |||
with the USES statement at the beginning of your | |||
program source code. The following DIR variables | |||
are supported: | |||
DirName : Holds the file name. | |||
DirSize : Holds the file size. | |||
DirAttr : Holds the file attributes | |||
DirTime : Holds the file date and time in packed | |||
date format. The DateSTR and TimeSTR | |||
functions will need to be used in order | |||
to display these. | |||
Example: | |||
USES DIR | |||
WriteLn ('The following files are in the C:\ directory:') | |||
WriteLn (<nowiki>''</nowiki>) | |||
FindFirst ('C:\*.*', 66) | |||
While DosError = 0 Do | |||
Begin | |||
WriteLn ('File Name: ', DirName) | |||
WriteLn (' Size: ', DirSize) | |||
WriteLn (' Date: ', DateSTR(DirTime), 0) | |||
WriteLn (' Time: ', TimeSTR(DirTime), 1) | |||
Write ('Press a key to search for more.~PN') | |||
FindNext | |||
End | |||
FindClose | |||
WriteLn ('No more files have been found.') | |||
The above example will list all files which fit the file mask of | |||
"C:\*.*" and fit the attributes of either ReadOnly or Archive. | |||
The DOSERROR function is used to determine when there are no more | |||
files found (See the DOSERROR reference). If a file has been | |||
found, it will then be printed to the screen using the DIR | |||
variables. The FindNext functon is used to find the next file | |||
that matches the name and attributes specified in the earlier call | |||
to FindFirst. FindClose is used when all "Find" functions have been | |||
completed. | |||
Procedure FINDNEXT | |||
This procedure is used to find the next file which matches the file | |||
mask and attibutes specified in the last call to FindFirst. | |||
Example: | |||
Uses DIR | |||
FindFirst ('*.*', 32) | |||
While DosError = 0 Do | |||
Begin | |||
WriteLn ('File Name: ', DirName) | |||
FindNext | |||
End | |||
FindClose | |||
The above example uses the FindFirst/FindNext functions to do a | |||
listing of all files in the current directory. The DosError | |||
function is used to determine when no more files have been found. | |||
Procedure GOTOXY (X: Byte, Y: Byte) | |||
This procedure will move the cursor to a specified X and Y | |||
position on the screen. This only works for users who have ANSI | |||
graphics. | |||
Example: | |||
CLRSCR | |||
GotoXY (1, 10) | |||
WriteLn ('Hello') | |||
The above example will clear the screen then goto the first column | |||
of the tenth line and output the text "Hello" to the screen. | |||
Procedure HALT | |||
This procedure will exit the program and return the user back to | |||
the BBS immediately. | |||
Example: | |||
If Graphics = 0 Do | |||
Begin | |||
WriteLn ('Sorry, you do not have ANSI graphics.') | |||
Halt | |||
End | |||
The above example will check to see if the user has ANSI graphics | |||
and if not, display "Sorry, you do not have ANSI" and exit the | |||
program immediately by using the HALT command. | |||
Function INITIALS (String) : String | |||
This function takes a user name and attempts to return one or two | |||
character initials. | |||
S := Initials('Jack Phlash'); // should return "JP" | |||
Function INPUT (Field: Byte, Max: Byte, Mode: Byte, Default: String) : String | |||
This function gives input to the user, and returns the result of | |||
the input as a string variable. | |||
The Field parameter is the size of the input field (in characters) | |||
that the user will be able to see. If the field size is smaller | |||
than the maximum number of characters allowed in the input, the | |||
input line will scroll when the user reaches the end. This field | |||
is usually set to the same as the Max parameter. | |||
The Max parameter is the maximum number of characters that | |||
Input will allow to be entered. Note that the Field parameter, in | |||
most cases, should be set to the same value as this. | |||
The Mode parameter is the type of input that will be accepted, and | |||
can be any one of the following input types: | |||
1 : Standard input. All characters allowed. | |||
2 : Upper case input. Allows all characters, but will convert | |||
any lower case letters into upper case. | |||
3 : Proper input. Allows all characters, but will convert | |||
the first letter in each word to an upper case letter. | |||
4 : Phone input. Allows only numbers and will pre-format them | |||
using the USA-style phone numbers. IE: XXX-XXX-XXXX. | |||
Note that the length of this input should always be 12, | |||
as that is the length of the USA phone number format. | |||
5 : Date input. Allows only numbers and will pre-format them | |||
using the date format (ie XX/XX/XX) that is currently | |||
selected by the user. NOTE: The date input will always | |||
return the date in the MM/DD/YY format, regardless of what | |||
format the user has selected. For example, if the user | |||
has selected the DD/MM/YY format, Input will expect the | |||
user to enter the date in that format, but will then | |||
convert it to MM/DD/YY when it returns the date back to | |||
the MPE program. | |||
6 : Password input. Allows all characters, but will convert | |||
any lower case letters into upper case. The character | |||
that is typed is NOT echoed to the screen. Instead, it | |||
is replaced by the * character so that what they have | |||
entered will not be shown on the screen. | |||
7: Lowercase Allows characters but will be lowercase. | |||
8: User Defined Input (from system config) | |||
9: Standard Input with no CR | |||
10: Number Input numbers only and +- | |||
NOTE: If any of the above input values are increased by 10, Input | |||
will create an input field using the foreground/background color | |||
that has been defined for that language. For example, input type | |||
11 will function the same as input type 1, but will fill an input | |||
field to the maximum field length. | |||
The Default parameter can be used to force a default text into | |||
the input field. If you do not wish to have any default text in | |||
the buffer, supply a blank string parameter (ie <nowiki>''</nowiki>). | |||
EXAMPLE: | |||
Var Str : String | |||
Write ('Enter something: ') | |||
Str := Input (30, 30, 1, <nowiki>''</nowiki>) | |||
The above example will print the text "Enter something: " to the | |||
screen and the allow input of up to 30 characters in length, using | |||
input type 1 (allows all characters). No default text has been | |||
supplied so the input field will be empty by default. | |||
Var Str : String | |||
Write ('Enter something: ') | |||
Str := Input (30, 30, 11, 'Default') | |||
The above example will function just like the first example, except | |||
it will create an input field background and stuff the text of | |||
"Default" into the input field. | |||
Function INPUTNY (Text: String) : Boolean | |||
This function prompts the user with a Yes/No question, defaulting | |||
to No. TRUE will be returned if the user answered Yes, or FALSE if | |||
the user answered No. The passed Text variable is the text that is | |||
displayed to the user asking the question. | |||
Example: | |||
If Not InputNY('Do you want to run this program? ') Then | |||
Halt | |||
The above example will prompt the user with the Yes/No question | |||
If | passed as <Text>. This question will default to No. If the user | ||
answers No, the program will halt from being executed. | |||
Function INPUTYN (Text: String) : Boolean | |||
This function prompts the user with a Yes/No question, defaulting | |||
to Yes. TRUE will be returned if the user answered Yes, or FALSE | |||
if the user answered No. The passed Text variable is the text | |||
that is displayed to the user asking the question. | |||
Example: | |||
If Not InputYN('Do you want to run this program? ') Then | |||
Halt | |||
The above example will prompt the user with a Yes/No question, | |||
asking "Do you want to run this program?". If the user responds | |||
No, the program will not run, using the Halt command. | |||
Function ISARROW : Boolean | |||
This function is used along with the READKEY function. After | |||
READKEY is called, this function can be checked to process various | |||
extended keys, such as arrow keys. When ISARROW is true, READKEY | |||
will return the following: | |||
ASCII # Char Key Pressed | |||
------- ---- ----------- | |||
71 G Home | |||
72 H Up Arrow | |||
73 I Page Up | |||
75 K Left Arrow | |||
77 M Right Arrow | |||
79 O End | |||
80 P Down Arrow | |||
81 Q Page Down | |||
83 S Delete | |||
The character returned by READKEY can be checked by either the | |||
ASCII # or the actual character. Below is an example: | |||
Example: | |||
Var Ch : Char | |||
Ch := ReadKey # Input one key | |||
If IsArrow Then # Is key returned an arrow key? | |||
If Ch = 'H' Then | |||
WriteLn ('Up arrow') | |||
Else If Ch = Chr(80) Then | |||
WriteLn ('Down arrow') | |||
Else # No arrow key. A normal character | |||
WriteLn ('You entered character: ', Ch) | |||
The above example reads a key with READKEY and then uses the | |||
ISARROW function to process the Up Arrow and Down Arrow keys. | |||
Function ISUSER (String) : Boolean | |||
This function takes a string value which can contain either a user | |||
realname, handle, or user perm index number. If the user exists, | |||
it will return a TRUE result or FALSE if the user does not exist. | |||
Function KEYPRESSED : Boolean | |||
This function returns TRUE if a key has been pressed either | |||
remotely or locally. Keep in mind two things about this | |||
function: | |||
(1) It doesn't check for inactivity timeout. If you are | |||
using this function to wait for a key to be pressed then | |||
function | you may want to use the TIMER function and check for | ||
inactivity. | |||
(2) This function only returns whether a key was PRESSED. | |||
It does not actually read the key out of the buffer. | |||
See the READKEY function for reading keys from the | |||
buffer. | |||
Example: | |||
Repeat | |||
Until KeyPressed | |||
WriteLn ('You pressed a key!') | |||
The above example will wait for a key to be pressed and then | |||
write to the screen "You pressed a key!". | |||
Function MCI2STR (String) : String | |||
This function will take the value of the supplied 2-character MCI | |||
code (without pipe) and returns the string value of that code. | |||
Ex: | |||
Var BBSName : String | |||
BBSName:=MCI2Str('BN') | |||
WriteLn('The name of this BBS is "'+BBSName+'"') | |||
Function MCILENGTH (String) : Integer | |||
This function works just like LENGTH except it tries to ignore MCI | |||
codes. It doesn't check for actual validity of MCI codes. | |||
Var B : Byte; | |||
B := MCILength('|15Hello|UH'); | |||
WriteLn ('Length should be 5: ' + Int2Str(B)); | |||
Function MOREPROMPT : Char | |||
This function displays the system more prompt and returns a Char | |||
value of either Y N or C depending on what the user selected. | |||
Var C : Char | |||
C:=MorePrompt | |||
Procedure MOVEX (Pos : Byte) | |||
This procedure is used to move the cursor to the passed X coordinate | |||
on the screen. It only works if the user has ANSI graphics enabled. | |||
Example: | |||
MoveX (20) | |||
WriteLn ('This text starts on the 20th space') | |||
Procedure MOVEY (Pos : Byte) | |||
This procedure is used to move the cursor to the passed Y coordinate | |||
on the screen. It only works if the user has ANSI graphics enabled. | |||
Example: | |||
MoveY (10) | |||
WriteLn ('This is on the 10th line of the screen') | |||
Function PARAMCOUNT : Byte | |||
This function is used to determine the number of command line | |||
options which have been passed to the MPE program. For more | |||
information, see the PARAMSTR function. | |||
Example: | |||
If ParamCount < 2 Then Begin | |||
WriteLn ('Invalid command line.') | |||
Halt | |||
End | |||
The above example will check to see if less than 2 command line | |||
options have been passed to the MPE program. If there are less | |||
than two, the program will terminal with a "invalid command line" | |||
message. | |||
Function PARAMSTR (Number : Byte) : String | |||
This function returns the command line option specified by the | |||
NUMBER parameter. A command line is the optional data which | |||
is passed on the "Data" field of a menu command. For example, | |||
when defining a menu command which executes an MPE program in | |||
the menu editor, the text after the program name becomes command | |||
line options. | |||
Menu Command: GX | |||
Data : BULLETIN p1 p2 p3 p4 | |||
If the above was defined in the menu editor, the following would | |||
be true: | |||
ParamCount would return 4 | |||
ParanStr(0) would return "BULLETIN" | |||
ParamStr(1) would return "p1" | |||
ParamStr(2) would return "p2" | |||
ParamStr(3) would return "p3" | |||
ParamStr(4) would return "p4" | |||
Note that ParamStr(0) will ALWAYS return the file name of the | |||
MPE program being executed. Even when there are no other | |||
parameters defined. | |||
Procedure PAUSE | |||
Envokes the Mystic pause prompt as defined in the current | |||
language file. | |||
Function PAUSEPOS : Byte | |||
This function gives access to Mystic's internal line | |||
counter used for screen pauses. | |||
Function RANDOM (Max: Word) : Word | |||
This function will return a random number within the range | |||
specified. | |||
Example: | |||
Var A : Byte | |||
A := Random(255) | |||
WriteLn (A) | |||
The above example will generate a random number within the range | |||
of 0 to 255 in the variable A and then print it to the screen. | |||
Function READKEY : Char | |||
This function will read a key from the buffer and return it as | |||
a char variable. If there are no keys in the buffer, readkey will | |||
wait for a key to be pressed. | |||
Example: | |||
Var Ch : Char | |||
Repeat Until KeyPressed | |||
Ch := ReadKey | |||
WriteLn ('You entered: ', Ch) | |||
The above example will wait for a key to be pressed by using the | |||
KEYPRESSED function. Afterwards, the key will be read into the | |||
CH variable using readkey, and then print it to the screen. | |||
Procedure SETPROMPTINFO (N : Integer; S : String) | |||
This allows you to set Mystic's internal "changing" PromptInfo MCI | |||
codes (the |&X codes). For example: | |||
SetPromptInfo(1, 'Hello!'); | |||
WriteLn ('This MCI code would like to say: |&1'); | |||
As a side note, there is NOT a GetPromptInfo because you can simply use | |||
MCI2STR: | |||
WriteLn('This MCI code would like to say: ' + Mci2Str('&1')); | |||
Procedure STUFFKEY (S : String) | |||
This function will stuff a string of text into the keyboard | |||
buffer. This can be used to force your program into thinking | |||
the user had actually typed <nowiki><S>.</nowiki> | |||
Example: | |||
Var Ch : Char | |||
StuffKey ('A') | |||
Ch := ReadKey | |||
WriteLn ('You entered: ', Ch) | |||
The above example will stuff the character "A" into the input | |||
buffer, where it will be read into Ch using the ReadKey function. | |||
It is possible to stuff entire strings of text into the buffer | |||
too. | |||
Example: | |||
Var Str : String | |||
StuffKey 'Hello World' | |||
Str := Input (20, 20, 1, <nowiki>''</nowiki>) | |||
The above example will stuff "Hello World" into the input buffer. | |||
This will cause the input function to think the user has actually | |||
typed in "Hello World". In this case, the above is the same as | |||
supplying "Hello World" in the <DEFAULT> field of the Input | |||
function. | |||
Function TIMER : LongInt | |||
This function will return the current number of seconds which have | |||
passed since midnight. This function can be used to time how long | |||
a user is doing something. | |||
Example: | |||
Var StartTime : LongInt | |||
Var EndTime : LongInt | |||
Var Total : LongInt | |||
Var Str : String | |||
StartTime := Timer | |||
Write ('Enter something: ') | |||
Str := Input (40, 11, 'Nothing') | |||
EndTime := Timer | |||
Total := EndTime - StartTime | |||
WriteLn ('You took ', Total, ' seconds to type something!') | |||
The above example will prompt the user to type something and time | |||
how long in seconds they took. WriteLn will then display the | |||
number of seconds the user took to the screen. | |||
Function TIMERMIN : LongInt | |||
This function works just like TIMER except returns minues | |||
instead of seconds. | |||
Function WHEREX : Byte | |||
This function returns the current X coordinate of the cursor. | |||
Example: | |||
Var X : Byte | |||
Var Y : Byte | |||
X := WhereX | |||
Y := WhereY | |||
WriteLn (' World') | |||
GotoXY (X, Y) | |||
WriteLn ('Hello') | |||
The above example will save the current X and Y cursor positions | |||
and then write the text "World" to the screen. After which, it | |||
will return to the saved X and Y position and write the text | |||
"Hello" to the screen. The end result will be the text of | |||
"Hello World" written to the screen. Note: GotoXY can only be | |||
used if the user has ANSI graphics mode. | |||
Function WHEREY : Byte | |||
This function returns the current Y coordinate of the cursor. | |||
For more information on this function, please see the definition | |||
of the WHEREX function. | |||
Procedure WRITE (Text) | |||
This procedure is used to write text to the screen without | |||
going to the next line (ie, without sending a carriage return). | |||
All text to be printed to the screen should be enclosed inside of | |||
' characters. If you wish to print the value of a variable to | |||
the screen, just include the variable name without the ' | |||
characters. If you wish to combine multiple text and variables, | |||
they must be separated by commas. | |||
Examples: | |||
Write ('Hello ') | |||
Write ('World') | |||
This example will write the text "Hello World" to the screen. | |||
Write ('Hello World') | |||
This example does the exact same thing as the function above, but | |||
makes a little more sense. | |||
Var Str : String | |||
Str := 'Hello World' | |||
Write (Str) | |||
This example will write the value held in the variable Str to the | |||
screen. The resulting output will be "Hello World" | |||
Var Str : String | |||
Str := 'Hello ' | |||
Write (Str, 'World') | |||
This example will write the value of the variable Str to the | |||
screen, followed by the text "World". The resulting output will | |||
be "Hello World". An unlimited number of variables and text can | |||
be outputted with the Write statement, but they must all be | |||
separated by a comma, as shown above. | |||
If a ' character needs to be printed to the screen, it can be done | |||
by doubling the ' character. For example: | |||
Write (<nowiki>'This is how it''s done.'</nowiki>) | |||
The resulting screen output will be "This is how it's done", with | |||
only one ' character. | |||
All MCI display codes can be used within the Write statement. If | |||
you wish to change the display colors, use the MCI color system to | |||
do so. For example: | |||
Write ('~14Hello World') | |||
This example will write the text Hello World in yellow to the | |||
screen. All MCI display codes are available to the write | |||
statement. | |||
Procedure WRITELN (Text) | |||
This procedure outputs text to the screen. It functioning is | |||
identical to the WRITE statement except that it goes to the next | |||
line after the text is printed (ie, it sends a carriage return). | |||
For example: | |||
WriteLn ('Hello') | |||
WriteLn ('World') | |||
The above example will write the text "Hello" on one line, and | |||
then the text of "World" on the next line. | |||
Procedure WRITEPIPE (Text) | |||
This function works just like WRITE but only parses pipe color | |||
codes instead of all MCI codes. | |||
Procedure WRITEPIPELN (Text) | |||
This procedure works just like WRITEPIPE but with a CRLF at the end. | |||
Procedure WRITERAW (Text) | |||
This procedure works just like WRITE except it does not parse | |||
any pipe color codes OR MCI codes. | |||
Procedure WRITERAWLN (Text) | |||
This procedure is the same as WRITERAW, but with a CRLF at the end. | |||
Procedure WRITEXY (X,Y,Z: Byte; Str : String) | |||
This procedure writes a string of text at the defined X/Y location with a | |||
specific text color attribute 'Z'. This of course requires the user has | |||
ANSI to function properly. This function will NOT parse MCI pipe codes. | |||
Example: | |||
WriteXY (1, 10, 8, 'Prints at X:1 Y:10 with dark grey text'); | |||
Procedure WRITEXYPIPE (X,Y,Z: Byte; Len: Integer; Str : String) | |||
This procedure writes a string of text at the defined X/Y location with a | |||
specific text color attribute 'Z'. This of course requires the user has | |||
ANSI to function properly. This function will NOT parse MCI pipe codes. | |||
Example: | |||
WriteXYPipe (1, 10, 8, 50, 'This pads to 50 chars at location 1,10'); | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
String Handling Functions and Procedures | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
Function ADDSLASH(S: String) : String | |||
takes a directory and appends the appropriate ending backslash or | |||
forward slash depending on operating system. If the slash is already | |||
there, it does nothing. | |||
Function CHR (B: Byte) : Char | |||
This function will take a numerical byte value and return it's | |||
ASCII character. The byte value must be between 0 and 255 as | |||
there are only 255 characters in the ASCII character set. | |||
Example: | |||
WriteLn ('Hello', Chr(32), 'World') | |||
This will output the text "Hello World" to the screen. The ASCII | |||
number for the space character is 32 and by passing a 32 to CHR, | |||
a space is returned. | |||
Function COPY (S: String, Index: Byte, Count: Byte) : String; | |||
This function will copy a defined part of a string and return | |||
the copied portion as a string. | |||
Example: | |||
Var Str : String | |||
Str := 'Hello World' | |||
WriteLn (Copy(Str, 1, 5)) | |||
This will output "Hello" to the screen. The copy function takes | |||
the given Str and copies Count number of character from the Index. | |||
So the above copies 5 characters starting at the 1st character in | |||
Str and WriteLn outputs it to the screen. | |||
Procedure DELETE (S: String, Index: Byte, Count: Byte) | |||
This procedure will delete a defined portion of a string | |||
variable. | |||
Example: | |||
Var Str : String | |||
Str := 'Hello World' | |||
Delete (Str, 6, 6); | |||
WriteLn (Str) | |||
This example will delete 6 characters from the string Str starting | |||
at the 6th character. The resulting output from WriteLn will be | |||
"Hello" | |||
Function FillChar (V: Variable; S: LongInt; C Char ): String | |||
Fills variable V with Char C for S size. | |||
type | |||
myuserrecord = record | |||
<nowiki> username : string[30];</nowiki> | |||
<nowiki> somevalue : array[1..5] of byte;</nowiki> | |||
end; | |||
var | |||
u : myuserrecord; | |||
begin | |||
fillchar(u, sizeof(u), #0); | |||
end. | |||
Procedure INSERT (Source: String, Target: String, Index: Byte) | |||
This procedure will insert text into a string at a specified | |||
location. | |||
Example: | |||
Var Str : String | |||
Str := 'Mystic v1.00' | |||
Insert ('BBS ', Str, 8) | |||
WriteLn (Str) | |||
The above example will insert the text "BBS" into the Str variable | |||
starting at the 8th character in the string. The result WriteLn | |||
output would be "Mystic BBS v1.00" | |||
Function INT2STR (L: LongInt) : String | |||
This function converts a numerical type variable to a string | |||
type variable. | |||
Example: | |||
Var A : Byte | |||
Var S : String | |||
A := 255 | |||
S := Int2Str(A) | |||
WriteLn (S) | |||
The above example sets the numerical variable to the value of | |||
255, which is then converted to a string variable using Int2Str. | |||
The resulting value of S will be '255' as WriteLn will output to | |||
the screen. | |||
Function LENGTH (S: String) : Byte | |||
This function returns the length in characters of the passed | |||
string variable. | |||
Example: | |||
WriteLn (Length('Hello World')) | |||
The above example would output "11" to the screen, which is the | |||
number of characters in the text passed to Length. | |||
Function LOWER (S: String) : String | |||
This function converts a passed string variable to all lower | |||
case letters. | |||
Example: | |||
WriteLn (Lower('HELLO')) | |||
The above statement would output the text "hello" to the screen. | |||
The original text of HELLO is converted to all lower case letters | |||
and than displayed by WriteLn. | |||
Function ONEKEY (Keys : String; Echo : Boolean) : Char | |||
This function accepts a string of uppercase letters, and wait for | |||
input from the user. If the keystroke is among the characters in | |||
Keys, it will return that character. If the keystroke is not among | |||
the Keys string, it will do nothing. If Echo is set to TRUE, it | |||
will also echo the Key to the screen. | |||
Var Ch : Char | |||
Var Keys : String = 'ABCDQ' | |||
Ch := OneKey(Keys,True) | |||
WriteLn('You selected '+Ch+'.') | |||
Function ONEKEYRANGE (String, Int, Int ) : Char | |||
This function works similar to OneKey, except that it will also allow | |||
for a number input within a certain range. The number value is | |||
stored in a variable called RangeValue and the function returns a #0 | |||
if a number was entered. For example: | |||
Var | |||
Ch : Char; | |||
Begin | |||
Write ('Enter letters A-G or a number between 1-50: '); | |||
Ch := OneKeyRange('ABCDEFG', 1, 50); | |||
If Ch = #0 Then | |||
WriteLn ('You entered a number: ' + Int2Str(RangeValue)) | |||
Else | |||
WriteLn ('You entered character: ' + Ch); | |||
End. | |||
Function ORD (C: Char) : Byte | |||
This function returns the ASCII code of the passed Char variable. | |||
This function works the exact opposite of the CHR function. | |||
Example: | |||
WriteLn (Ord(' ')) | |||
The above example would output the text "32" to the screen because | |||
32 is the ASCII character code for space. | |||
Function PADCT (S: String, N: Byte, C: Char) : String | |||
This function pads a string to the center with the specified | |||
character. | |||
Example: | |||
Var Str : String | |||
Str := PadCT('Hello World', 80, ' ') | |||
WriteLn (Str) | |||
The above example would display the text "Hello World" centered on | |||
the screen. The PadCT function returns the text "Hello World" | |||
centered in 80 spaces with the character of " " used to fill the | |||
blank spaces. | |||
Function PADLT (S: String, N: Byte, C: Char) : String | |||
This function returns a text string padded with spaces to the | |||
left side. | |||
Example: | |||
Var Str : String | |||
Str := PadLT('Hello World', 79, ' ') | |||
The above example would return a string which is 79 characters in | |||
length with the text "Hello World" as the leftmost part of the | |||
string. The passed character is the character that is used to | |||
fill the blank spaces. | |||
Function PADRT (S: String, N: Byte, C: Char) : String | |||
This function returns a text string padded with spaces to the | |||
right side. | |||
Example: | |||
Var Str : String | |||
Str := PadRT('Hello World', 79, ' ') | |||
The above example would return a string which is 79 characters in | |||
length with the text "Hello World" being the rightmost part of the | |||
string. The empty spaces are filled with the passed charcter (in | |||
this case ' '). | |||
Function POS (Sub: String, S: String) : Byte | |||
This function returns the starting position of a substring in a | |||
string. | |||
Example: | |||
Var A : Byte | |||
A := POS('World', 'Hello World') | |||
WriteLn (A) | |||
The above example would output "7" to the screen becase POS | |||
returns the position of the text "World" in the string | |||
"Hello World". If POS does not find a match, a zero will be | |||
returned. IE: A := POS('Blah', 'Hello World') would return a zero | |||
because the text "Blah" was not found in the string "Hello World". | |||
Function REPLACE(Str1, Str2, Str3 : String) : String | |||
This function replaces all occurances of a supplied text and | |||
returns a string. Ex: | |||
Var Str : String = 'Hello Hello Hello'; | |||
Str := Replace(Str, 'Hello', 'World'); // Str is now World World World | |||
Function STRCOMMA(LI : LongInt) : String | |||
This function accepts a longint and returns it as a string, with | |||
commas added where applicable: | |||
Ex: | |||
WriteLn (strComma(1000000)); // will print 1,000,000 | |||
Function STR2INT (S: String) : LongInt | |||
This function converts a passed string variable to a numerical | |||
variable. The passed string variable must contain a valid number. | |||
Example: | |||
Var A : Byte | |||
Var S : String | |||
S := '100' | |||
A := Str2Int(S) | |||
WriteLn (S) | |||
WriteLn (A) | |||
The above example will output "100" twice the screen. The | |||
variable S is assigned to '100' and the function Str2Int converts | |||
the string into a numerical value which is assigned to variable | |||
A. | |||
Function STRIPB (S1, S2 : String) : String | |||
This function strips both sides of the string if a specific character. | |||
Var S : String = ' Hello '; | |||
S := StripB(S, ' '); | |||
Function STRIPL (S1, S2 : String) : String | |||
This function strips the left side of a string of any specified | |||
leading characters. | |||
Var S : String = ' Hello'; | |||
S := StripL(S, ' '); | |||
Function STRIPR (S1, S2 : String) : String | |||
This function strips the right side of a string of any specifcied | |||
trailing character: | |||
Var S : String = 'Hello '; | |||
S := StripR(S, ' '); | |||
Function STRIPLOW (String) : String | |||
This function strips all chracters from a string that are less than | |||
ascii code #32. | |||
Var S : String = #12#12#12#12 + 'Hello'; | |||
S := StripLow(S); | |||
Function STRIPMCI (S : String) : String | |||
This function will strip the passed string variable of all MCI | |||
codes and return the "cleaned" version. | |||
Example | |||
Var S : String | |||
S := '|10|H|02ello |10W|02orld|07' | |||
WriteLn ('Normal : ', S) | |||
WriteLn ('Stripped : ', StripMCI(S)) | |||
The above example assigns a string with MCI codes in it to the S | |||
variable. It then writes the original string and the stripped | |||
string to the screen, so the difference is shown. | |||
Function STRIPPIPE (String) : String | |||
This function takes a string and strips only pipe color codes | |||
from it. | |||
S := StripPipe('|15Hello there, |UH'); //returns "Hello There, |UH" | |||
Function STRMCI (String) : String | |||
This function takes an entire string and attempts to translate any | |||
MCI codes found in it, returning the entire result. | |||
S := StrMci('Hello |UH'); | |||
Function STRREP (Ch: Char, Num: Byte) : String | |||
This function returns a string filled with character <CH> to the | |||
length of <NUM>. | |||
Example: | |||
WriteLn (strRep('-', 60 )) | |||
The above example will use strRep to create a string 60 characters | |||
long of the character '-', then write it to the screen. So the | |||
outputted text would look like: | |||
"------------------------------------------------------------" | |||
Function STRWRAP(Str, Str2 : String; Len: Integer) : Byte | |||
This function takes two strings and wraps them after the word closest | |||
to the maximum supplied length. It optionally returns the actual | |||
position where it wrapped. | |||
Var Str : String = 'This will wrap'; | |||
Var Str2 : String = <nowiki>''</nowiki>; | |||
Var Where : Byte; | |||
Where := strWrap(Str, Str2, 10); | |||
WriteLn ('It wrapped at ' + Int2Str(Where)); | |||
WriteLn ('First string: ' + Str); | |||
WriteLn ('Second string: ' + Str2); | |||
Function UPPER (S: String) : String | |||
This function coverts the passed string variable to all upper | |||
case letters. | |||
Example: | |||
WriteLn (Upper('hello')) | |||
The above example would output the text "HELLO" to the screen. | |||
The UPPER function converts the passed text of "hello" to all | |||
upper cased letters, which is then printed to the screen by | |||
WriteLn. | |||
Function WORDCOUNT (S,C: String) : Integer | |||
Function WordCount returns the number of words in a string using | |||
the final parameter to define the character that determines what | |||
separates words. Ex: | |||
Str := 'Hello this is a test'; | |||
WriteLn ('Str has ' + Int2Str(WordCount(Str, ' ')) + ' words in it.'); | |||
Function WORDGET(I : Integer, S, C : String) : String | |||
returns the actual word at a specific word count. | |||
S is the inputted string value. | |||
I is the numerical value of the position where the word can be found. | |||
C is the string value used as the word separater. | |||
Ex: | |||
Str := 'Hello this is a test'; | |||
WriteLn('The second word was: ' + WordGet(2, Str, ' ')); | |||
Function WordPos (I : Integer; S, C : String ) : Integer | |||
Function WordPos returns the character position in the string where | |||
specific word is located. | |||
S = Inputted string value | |||
I = Index value of the the desired word within S | |||
C = String value of the word separater. | |||
Ex: | |||
Str := 'Hello this is a test'; | |||
WriteLn ('Second word is at: ' + Int2Str(WordPos(2, Str, ' '))); | |||
See Also : WordCount, WordGet | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
File Accessing Functions and Procedures | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
Function FEOF (Handle) : Boolean | |||
This function will return true if the file position of an opened | |||
file is at the End Of the File (EOF). The passed Handle value is | |||
the file number of the already opened file. | |||
Example: | |||
Var Str : String | |||
Var Fpt : File | |||
FOpen (1, Text, Reset, 'BLAH.TXT') | |||
While Not Eof(1) | |||
FReadLn (1, Str) | |||
WriteLn (Str) | |||
End | |||
FClose (1) | |||
The above example will open a text file under the filename of | |||
BLAH.TXT. The WHILE loop is used to repeat the code until the | |||
EOF (end of file) is reached. The FCLOSE statement will close | |||
the file after it is done being accessed. | |||
The result of the above example will be (in pseudocode): | |||
1. Open text file. | |||
2. If not at the end of file, run this code: | |||
3. Read line from text file into string variable | |||
4. Print line read from text file to the screen. | |||
5. Goto 2. | |||
6. Close the text file. | |||
So the above example will basically write the entire text file to | |||
the screen. | |||
Procedure FCLOSE (File) | |||
This procedure closes an already opened file. The passed Handle | |||
value is the file number of the opened file. All files which | |||
are opened MUST be closed after they are not being accessed any | |||
more. | |||
For example: | |||
Var Fptr : File | |||
fAssign (Fptr, 'BLAH.TXT', 66) | |||
fReWrite (Fptr) | |||
<nowiki><Code to access file goes here></nowiki> | |||
fClose (Fptr) | |||
The above example opens a file using the FOPEN procedure. When | |||
the file has been opened successfully, it can be accessed in | |||
various ways using the file I/O functions. Afterwards, it MUST | |||
be closed using the FCLOSE procedure as shown above. | |||
Function FILECOPY (Source: String, Dest: String) : Boolean | |||
This function will copy a file from the specified source location | |||
to the specified destination location. The function will return | |||
as TRUE if the file was copied successfully, or FALSE if an error | |||
The | occured. Note: The file which is being copied should not already | ||
be opened for File I/O by the program. | |||
Example: | |||
Write ('Copying C:\HELLO.TXT -> D:\HELLO.TXT: ') | |||
If fileCopy ('C:\HELLO.TXT', 'D:\HELLO.TXT') | |||
WriteLn ('OK') | |||
Else | |||
WriteLn ('ERROR') | |||
End | |||
The above example will attempt to copy the file "C:\HELLO.TXT" to | |||
the destination of "D:\HELLO.TXT". If the file is copied without | |||
any problems an "OK" will be printed to the screen. If an error | |||
occured while copying, "ERROR" will be printed to the screen. | |||
Procedure FILEERASE (FileName: String) | |||
This procedure is used to erase an existing file from the disk. | |||
The FileName variable is a string variable which contains the | |||
file name which is to be erased. The result of the FILEERASE | |||
procedure can be checked by checking the DOSERROR function. | |||
DOSERROR will return a 0 if successful or a 2 if an error occured. | |||
Example: | |||
FileErase ('C:\HELLO.TXT') | |||
The above example will erase the file "C:\HELLO.TXT" if it exists. | |||
Function FILEEXIST (FileName: String) : Boolean | |||
The above function will check to see if a file exists, and return | |||
TRUE if it does. The passed FileName string if the path and file | |||
name of the file to check. This file should not already be opened | |||
with the FOPEN procedure. | |||
Example: | |||
If FileExist('BLAH.TXT') Then | |||
WriteLn ('BLAH.TXT exists.') | |||
Else | |||
WriteLn ('BLAH.TXT does NOT exist.') | |||
The above example will check to see if the file "BLAH.TXT" exists | |||
and if it does, will output "BLAH.TXT exists" to the screen. If | |||
BLAH.TXT does NOT exist, the output will be "BLAH.TXT does NOT | |||
exist". | |||
Function FPOS (File) : LongInt | |||
This function returns the current file position of an opened | |||
file. The passed Handle is the file handle number used when the | |||
file was opened. The FilePos function only works for files that | |||
are opened as Binary, since Text files are read line by line. | |||
Example: | |||
Var Fptr : File | |||
fAssign (Fptr, 'TEST.DAT', 66) | |||
fReset(Fptr) | |||
If IORESULT = 0 Then Begin | |||
If fPos(Fptr) = FSize(Fptr) | |||
WriteLn ('END OF FILE.') | |||
End | |||
fClose (fPtr) | |||
End | |||
The above example opens the file "TEST.DAT" for binary and then | |||
writes to the screen if the file position is at the end of the | |||
file. The above statement "fPos(Fptr) = fSize(Fptr)" is the same | |||
as "fEof(Fptr)" since it's stating "if the file position is equal to | |||
the total file size, then we're at the end of the file." | |||
Function FSIZE (File) : LongInt | |||
This function returns the total file size of an opened file. The | |||
passed Handle is the file handle number used when the file was | |||
opened. This function only works with files that have been opened | |||
as Binary since Text files are read line by line. | |||
Example: | |||
Var Fptr : File | |||
fAssign (Fptr, 'TEST.DAT', 66) | |||
fReset(Fptr) | |||
If IoResult = 0 Then | |||
WriteLn ('This file is ', fSize(Fptr), ' bytes in size.') | |||
fClose (Fptr) | |||
The above example opens the file "TEST.DAT", writes the size of | |||
the file to the screen, and then closes the file. | |||
Procedure FASSIGN (Fptr : File, Mask : String, Attr : Int) | |||
This procedure opens a text or binary file for file operations. | |||
Fptr : The passed file pointer is the file reference, of type FILE | |||
Mask : The path and filename of the file to open, in string format. | |||
Attr : File attributes to open. See FINDFIRST for more info. | |||
EXAMPLE: | |||
Var Fptr : File | |||
fAssign (Fptr, 'BLAH.TXT', 66) | |||
fReWrite (Fptr) | |||
fWriteLn (Fptr, 'Hello World!') | |||
fClose (Fptr) | |||
The above example creates a text file under the name 'BLAH.TXT'. | |||
If BLAH.TXT already exists, it will be erased and replaced by a | |||
new BLAH.TXT file. The FWriteLn writes the text "Hello World" to | |||
the file, and then FClose closes the file. | |||
Procedure FRESET (File) | |||
This procedure moves the file pointer to the beginning of an already | |||
opened file. This is useful for moving the file pointer to specific | |||
spots in the file, without having to close and reopen the file. The | |||
file must have previously been opened by FASSIGN. | |||
Use IORESULT to determine if the freset command was successful. | |||
Var fPtr : File | |||
fAssign(Fptr,CfgDataPath+'somefile.dat',66) | |||
fReset(Fptr) | |||
If IORESULT = 0 Then Begin | |||
WriteLn('somefile.dat is opened for use!') | |||
WriteLn('closing somefile.dat!') | |||
fClose(Fptr) | |||
End Else | |||
WriteLn('Unable to open somefile.dat') | |||
Procedure FREWRITE(File) | |||
This procedure will this will erase an existing file and recreate it, | |||
leaving the file position at the beginning of the file. If the | |||
file does not already exist, MPL will create the file. The file must | |||
have previously been opened by FASSIGN. | |||
Procedure FSEEK (Fptr: File, Position: LongInt) | |||
This procedure seeks to a file position in a binary file. It | |||
will only work on binary files, not text file. | |||
Fptr : The passed file pointer value of type FILE | |||
Position : This is the position where FSEEK will seek to. | |||
EXAMPLE: | |||
Var Str : String | |||
Var Fptr: File | |||
Str := 'Hello World!' | |||
fAssign (Fptr, 'BLAH.DAT',66) | |||
fSeek (Fptr, FileSize(1)) | |||
fWriteRec (Fptr, Str, 12) | |||
fClose (Fptr) | |||
The above example opens an already existing file under the name | |||
'BLAH.DAT'. Using FSEEK, it will seek to the end of the file, | |||
so that "Hello World" can be added as the last record. | |||
Procedure FREAD (File, Str, Int) | |||
This procedure is used to read binary data from a file. | |||
Type FileInfo = record | |||
Index : Integer | |||
<nowiki> Name : String [50]</nowiki> | |||
Data : Integer | |||
End | |||
Var fptr : File | |||
Var info : FileInfo | |||
Var Recno: Integer = 3 | |||
fAssign(Fptr,'FILE.DAT',66) // Open the file | |||
fReset(Fptr) // Reset to the beginning of the file | |||
If IoResult = 0 Then Begin // If successful... | |||
fSeek(Fptr,(Recno-1)*SizeOf(Info)) // Go to 3rd record in the file | |||
If Not fEof(Fptr) Then // If the 3rd record is there... | |||
fRead(Fptr,Info,SizeOf(Info)) // Read the record | |||
// Optionally, use FreadRec(Fptr,Info) when reading record types. | |||
End | |||
fClose(Fptr) // close the file | |||
Procedure FREADLN(File,Str) | |||
This procedure will read string data from a text file. | |||
Var fptr : File | |||
Var Str : String | |||
fAssign(Fptr,'somefile.txt',66) | |||
fReset(Fptr) | |||
If IoResult = 0 Then Begin | |||
While Not fEof(Fptr) Do Begin | |||
FReadLn(Fptr,Str) | |||
WriteLn(Str) | |||
End | |||
fClose(Fptr) | |||
End | |||
Procedure FWRITE (File, Str, Int) | |||
This procedure is used to write binary data to a file. | |||
Type FileInfo = record | |||
Index : Integer | |||
<nowiki> Name : String [50]</nowiki> | |||
Data : Integer | |||
End | |||
Var fptr : File | |||
Var info : FileInfo | |||
info.Index:=1 | |||
info.Data:=33 | |||
info.Name:='newname' | |||
fAssign(Fptr,'FILE.DAT',66) | |||
fReWrite(Fptr) | |||
fWrite(Fptr,Info,SizeOf(Info)) | |||
fClose(Fptr) | |||
Procedure FWRITELN(File,Str) | |||
This procedure is used to save string data to a text file. | |||
Var Fptr : File | |||
Var Str : String = 'I am a string value!' | |||
fAssign(Fptr,'flatfile.txt',66) | |||
fReset(Fptr) | |||
If IoRESULT = 0 Then Begin | |||
// File already exists. | |||
// Seek to the end of the file. aka append to the file | |||
fSeek(Fptr,FSize(Fptr)) | |||
End Else Begin | |||
// File is not yet created. Create it now. | |||
fReWrite(Fptr) | |||
End | |||
fWriteLn(Fptr,Str) | |||
fClose(Fptr) | |||
Function SIZEOF (Type) : LongInt | |||
This function will take any named data type as input, and return | |||
the size of the data. | |||
Type TypeOfData = Record | |||
N : Integer | |||
L : Real | |||
V : LongInt | |||
<nowiki> Q : String [32] </nowiki> | |||
End | |||
Var I : Integer | |||
<nowiki> Var S : String [50]</nowiki> | |||
Var R : Real | |||
Var T : TypeofData | |||
WriteLn('Size Of I = '+Int2Str(SizeOf(I))) | |||
WriteLn('Size Of S = '+Int2Str(SizeOf(S))) | |||
WriteLn('Size Of R = '+Int2Str(SizeOf(R))) | |||
WriteLn('Size Of T = '+Int2Str(SizeOf(T))) | |||
<nowiki>-----------------------------------------------------------------------</nowiki> | |||
BBS Related Functions and Procedures | |||
<nowiki> | <nowiki>-----------------------------------------------------------------------</nowiki> | ||
Function ACS (S: String) : Boolean | |||
This function processes an ACS string and returns true if the user | |||
has passed. | |||
Example: | |||
If ACS('s10g1') Then | |||
WriteLn ('You have access to this.') | |||
Else | |||
WriteLn ('Sorry, you do not have access.') | |||
The above example checks to see if the user passes the ACS string | |||
of "s10g1" and prints the result to the screen. | |||
Function DATESTR (DT: LongInt, dType: Byte) : Integer | |||
This function will take a packed datetime number and convert it to | |||
a date string. The dType parameter is used to set the format of the | |||
date which is returned. Valid types are: | |||
UserDateType = Returns date in the users date format | |||
1 = Returns date in format: MM/DD/YY | |||
2 = Returns date in format: DD/MM/YY | |||
3 = Returns date in format: YY/DD/MM | |||
Example: | |||
GetThisUser | |||
WriteLn ('Welcome. You last called on ', DateStr(UserLast)) | |||
The above example loads the currently logged in user's information | |||
into the USER variables using GETTHISUSER, then displays the last | |||
time the user has called to the screen using the DATESTR procedure. | |||
Function DATETIME : LongInt | |||
This function returns the current Date and Time in the packed | |||
format. DATESTR and TIMESTR can be used to convert this value | |||
into strings. | |||
Example: | |||
WriteLn ('Current Date: ', DateStr(DateTime), 0) | |||
WriteLn ('Current Time: ', TimeStr(DateTime), 1) | |||
The above example outputs the current date and time to the screen | |||
using the DATESTR and TIMESTR functions. The DateTime function | |||
which is passed to DATESTR and TIMESTR, contains the current date | |||
and time in the packed format. | |||
Function DIREXIST (S : String) : Boolean | |||
This function returns TRUE or FALSE if a directory exists. | |||
If DirExist('C:/MYSTIC/TEMP46') Then | |||
WriteLn('Dir C:/MYSTIC/TEMP46 exists!') | |||
Else | |||
WriteLn('Dir C:/MYSTIC/TEMP46 does not exist!') | |||
Procedure DISPFILE (FN: String) | |||
This procedure displays a text or ANSI file to the screen. If a | |||
path not included in the passed filename, Mystic will look for | |||
the file in the language text file directory. If no file | |||
extension is provided in the passed file name, Mystic will display | |||
the correct file according to the user's graphics settings | |||
(ie .ANS for ANSI, .ASC for non-ansi). | |||
Example: | |||
DispFile ('WELCOME') | |||
The above example will display the text file "WELCOME" from the | |||
language text file directory. Since there is no file extension | |||
provided, Mystic will display "WELCOME.ANS" or "WELCOME.ASC" | |||
depending on what the user's terminal settings are. | |||
Procedure FILLCHAR (R : Record; S : Integer; V : Value ) | |||
Fillchar fills the memory starting at X with Count bytes or | |||
characters with value equal to Value. | |||
type | |||
myuserrecord = record | |||
<nowiki> username : string[30];</nowiki> | |||
<nowiki> somevalue : array[1..5] of byte;</nowiki> | |||
end; | |||
var | |||
u : myuserrecord; | |||
begin | |||
fillchar(u, sizeof(u), #0); | |||
end. | |||
Procedure GETCFG | |||
This procedure will load the current configuration data into the | |||
CFG variables. The "USES CFG" command must be used at the start | |||
of your program for GETCFG to work. The following variables will | |||
be loaded: | |||
CFGSYSPATH : System Path | |||
CFGDATAPATH : Data Path | |||
CFGMSGSPATH : Message Base Path | |||
CFGPROTPATH : Protocol Path | |||
CFGQWKPATH : Local QWK Path | |||
CFGMPEPATH : Script (MPE) Path | |||
CFGATTPATH : File Attach Path | |||
CFGLOGSPATH : System Logs Path | |||
CFGTEXTPATH : Text Files Path (for the current language) | |||
CFGTEMPPATH : Temp path for the current node | |||
CFGMENUPATH : Menu Files Path (for the current language) | |||
CFGTIMEOUT : | |||
CFGSEEINVIS : Gives the "See Invisible" ACS value | |||
CFGTNNODES : Number of max telnet nodes to allow | |||
CFGNETDESC[1..30] : Give the network descriptions. | |||
Example: | |||
Uses CFG | |||
GetCFG | |||
WriteLn ('Mystic BBS is installed in ', CfgSysPath) | |||
The above example will load the configuration into the CFG | |||
variables, and then print the directory where Mystic BBS is | |||
installed in to the screen. | |||
Function GETATTRXY (X, Y : Byte) : Byte | |||
This function returns the attribute of the character at position | |||
XY on the user's screen: | |||
Var Attr : Byte; | |||
Attr := GetAttrXY(1, 1); | |||
WriteLn ('The attribure of the character at 1,1 is: ' + strI2S(Attr)); | |||
Function GETCHARXY (X, Y : Byte) : Char | |||
This function returns the character located on the user's | |||
screen at the XY location. | |||
Var Ch : Char; | |||
Ch := GetCharXY(1, 1); | |||
WriteLn('The user has the following character at 1,1: ' + Ch); | |||
This kind of stuff could allow you to create MPL-based custom screen | |||
effects like TheDraw used to have, except for on-the-fly with whatever | |||
is on the user's screen. | |||
Function GETMBASE (N : Word) : Boolean | |||
This procedure will read message base data into the MBASE variables. | |||
The supplied N is the record number to read. The function will | |||
return TRUE if the record was read successfully, or FALSE if the | |||
record was not read. The "USES MBASE" command must be called at | |||
the start of your program for the MBASE functions to work | |||
correctly. | |||
The following MBASE variables will be set when a record is read: | |||
Variable Name Type Description | |||
------------------------------------------------------------------- | |||
MBASENAME String Name | |||
MBASEACS String ACS level | |||
MBASERACS String Read ACS level | |||
MBASEPACS String Post ACS level | |||
MBASESACS String SysOp ACS level | |||
MBASEINDEX Integer Index number (*NEVER* change this) | |||
Example: | |||
Var A Word | |||
A := 1 | |||
While GetMBase Do | |||
Begin | |||
WriteLn ('Base name: ', MBaseName) | |||
A := A + 1 | |||
End | |||
The above example will list all available message base systems on | |||
the BBS. | |||
Function GETMBASESTATS (Base : LongInt; B1, B2 : Boolean; Tot, New, Yours : LongInt) : Boolean | |||
This can be used as a function or a procedure (returning true if | |||
successful). It takes 6 parameters. | |||
#1: Message base number | |||
#2: Exclude messages FROM the current user in stats | |||
#3: Exclude messages TO the current user that have already been read | |||
#4: Total messages (this is a VAR parameter) | |||
#5: New messages (this is a VAR parameter) | |||
#6: New messages to you (this is a VAR parameter) | |||
Example: | |||
uses mbase; | |||
var | |||
count, total, new, yours : longint; | |||
begin | |||
count := 1; //start @1 to skip email base | |||
while getmbase(count) do begin | |||
getmbstats(count, true, true, total, new, yours); | |||
writeln('base : ' + mbasename); | |||
writeln('total msgs : ' + int2str(total)); | |||
writeln('new msgs : ' + int2str(new)); | |||
writeln('your msgs : ' + int2str(yours)); | |||
writeln(<nowiki>''</nowiki>); | |||
count := count + 1 | |||
end; | |||
Function GETMBASETOTAL (Compress : Boolean) : LongInt | |||
This function returns the total message bases on the system. If | |||
Compressed is true, then it will return the total number of message | |||
bases the user has access to (slower to calculate). If it is false, | |||
it returns the raw total number of bases on the system. | |||
Function GETPROMPT (N : Word) : String | |||
This function will return a prompt from the current user's language | |||
file. The passed N varliable is the prompt number to return. | |||
Example: | |||
WriteLn(GetPrompt(1)) | |||
The above example writes prompt #1 from the user's currently | |||
selected language file to the screen. | |||
Procedure GETSCREENINFO (I, X, Y, Attr : Integer) | |||
This allows you to read Mystic's internal ScreenInfo codes, | |||
used in Templates - so your MPLs can easily have templates | |||
just like Mystic! These are the |!X codes. | |||
Var | |||
X, Y, Attr : Byte; | |||
Begin | |||
GetScreenInfo(1, X, Y, Attr); | |||
WriteLn('The value of the !1 MCI code was:'); | |||
WriteLn(' X: ' + Int2Str(X)); | |||
WriteLn(' Y: ' + Int2Str(Y)); | |||
WriteLn('Attr: ' + Int2Str(Attr)); | |||
End; | |||
Function GETUSER (N: Integer) : Boolean | |||
This procedure will read user data into the USER variables. The | |||
supplied N is the record number to read. The function returns | |||
true if the record was read, or false if a record was not read. | |||
The following USER variables will be set when a record is read: | |||
Variable Name Type Description | |||
------------------------------------------------------------------- | |||
USERDELETED Boolean Is the user marked as deleted? | |||
USERNAME String User's real name. | |||
USERALIAS String User's BBS alias. | |||
USERPASSWORD String User's password. | |||
USERADDRESS String User's street address. | |||
USERCITY String User's City/State. | |||
USERBIRTHDAY String User's birth date. | |||
USERSEX Char User's gender (M = Male, F = FeMale). | |||
USERSEC Byte User's security level (0-255). | |||
USERFIRSTON LongInt User's date/time of first call to the BBS. | |||
This is stored in the packed date format | |||
so in order to display the date & time, | |||
the functions of DATESTR and TIMESTR need | |||
to be used. | |||
USERLASTON LongInt User's date/time of the last call to the | |||
BBS. This is also stored in a packed date | |||
format, so the same rules for USERFIRST | |||
apply to this. | |||
------------------------------------------------------------------- | |||
Example: | |||
Var A Integer | |||
A := 1 | |||
While GetUser(A) Do | |||
Begin | |||
WriteLn ('User Alias: ', UserAlias) | |||
A := A + 1 | |||
End | |||
The above example will list all user accounts on the BBS system. | |||
Procedure GETTHISUSER; | |||
This procedure loads the user information for the currently | |||
logged in user into the USER variables. See the GETUSER function | |||
for a reference of the USER variables. | |||
Example: | |||
GetThisUser | |||
WriteLn ('Welcome to this BBS, ', UserAlias) | |||
WriteLn ('You have called ', UserCalls, ' times!') | |||
The above example will load the currently logged in user | |||
information into the user variables, then display a line of | |||
text welcoming them to the BBS. | |||
Function GRAPHICS : Byte | |||
This function returns the user's current graphics mode in | |||
numerical format: | |||
0 = ASCII graphics mode | |||
1 = ANSI graphics mode | |||
Example: | |||
If Graphics = 1 Then | |||
WriteLn ('ANSI graphics') | |||
Else | |||
WriteLn ('ASCII graphics') | |||
The above example will print the user's current graphics mode | |||
to the screen. If the user has ANSI (graphics mode 1), "ANSI | |||
graphics" will be printed. If the user does not have ANSI | |||
(graphics mode 0), "ASCII graphics" will be printed to the screen. | |||
Procedure HANGUP | |||
This procedure will stop the program immediately, hangup up on the | |||
user, and return Mystic BBS to the waiting for caller screen. | |||
Example: | |||
If InputYN ('Do you want to hangup now? ') Then | |||
HangUp | |||
The above example will prompt the user with a Yes/No question | |||
asking "Do you want to hangup now?" and if the user responds | |||
"Yes", they will be logged off the BBS using the HangUp command. | |||
Function JustFile (S : String) : String | |||
This function takes a string arguement and returns only the | |||
filename: | |||
WriteLn ('This MPX filename is: ' + JustFile(ProgName)); | |||
Function JustFileName (S : String) : String | |||
This function takes a string arguement and returns only the base | |||
filename (ie, not the extension so it basically just removes a file | |||
extension). This does not remove a path, JustFile does that. | |||
WriteLn ('This MPX filename is: ' + JustFileName(ProgName)); | |||
Function JustPath (S : String) : String | |||
This function takes a string arguement and returns only the | |||
path (including the trailing backslash). | |||
Ex: | |||
WriteLn ('This MPX is located in ' + JustPath(ProgName)); | |||
Function LOCAL : Boolean | |||
This function returns TRUE if the user is logged into the BBS | |||
system locally. It will return FALSE if the user is connected | |||
via a remote location. | |||
Example: | |||
If Local Then | |||
WriteLn ('Local caller detected.') | |||
Else | |||
WriteLn ('Remote caller detected.') | |||
Function MSGEDITOR(0,Int,Int,Int,Bool,Str,Str) : Bool | |||
Procedure MSGEDITSET(Int,Str) | |||
Procedure MSGEDITGET(Int,Str) | |||
Added 3 new MPL functions: MsgEditor, MsgEditSet, MsgEditGet. These | |||
allow access to the internal Mystic msg editor (line and/or full) | |||
from within MPL. It even allows you to define wrap position and | |||
template to completely make it look like its not the Mystic editor! | |||
As a little hint the MsgEditSet and MsgEditGet stuff could be used to | |||
post process message text on posts. Like say for example you wanted | |||
to write a MPL that allows users to add Tag lines, you could do that | |||
by replacing the "Saving message..." prompt and using those two in | |||
order to modify the text before it is saved by Mystic! | |||
Rather than trying to explain it all, here is an example of all 3: | |||
Var | |||
Lines : Integer = 0; | |||
WrapPos : Integer = 79; | |||
MaxLines : Integer = 200; | |||
Forced : Boolean = False; | |||
Template : String = 'ansiedit'; | |||
Subject : String = 'My subject'; | |||
Count : Integer; | |||
Begin | |||
MsgEditSet (1, 'this is line 1'); | |||
MsgEditSet (2, 'this is line 2!'); | |||
Lines := 2; | |||
SetPromptInfo(1, 'MsgTo'); // if template uses &1 for "To:" display | |||
If MsgEditor(0, Lines, WrapPos, MaxLines, Forced, Template, Subject) Then Begin | |||
WriteLn('User selected to save.'); | |||
WriteLn('There are ' + Int2Str(Lines) + ' of text in buffer:'); | |||
For Count := 1 to Lines Do | |||
WriteLn(MsgEditGet(Count)); | |||
Pause; | |||
End Else Begin | |||
WriteLn('User aborted the edit.'); | |||
Pause; | |||
End | |||
End | |||
Procedure MENUCMD (CM: String, Data: String) | |||
This procedure will allow menu commands to be ran from within a | |||
program. <CM> is the menu command, and <nowiki><DATA> is the menu command</nowiki> | |||
data. | |||
Example: | |||
MenuCmd (<nowiki>'NW', ''</nowiki>) | |||
The above example will run the menu command "NW" with the optional | |||
data field set to nothing. This example will display the Who's | |||
Online list. See MYSTIC.DOC for a list of all available menu | |||
commands. | |||
Function NODENUM : Byte | |||
This function returns the current node number which the program | |||
is being ran on. | |||
Example: | |||
WriteLn ('Welcome to node number ', NodeNum) | |||
The above example will print the text "welcome to node number x" | |||
to the screen, where the x will be the current node number which | |||
the program is being ran on. | |||
Variable PROGNAME : String | |||
Returns the path and filename of the current MPL program | |||
Variable PROGPARAMS : String | |||
Returns any of th eparameters passed to the MPL program as a | |||
single string | |||
Procedure PUTMBASE | |||
This procedure will save the currently loaded MBASE variables into | |||
a message base record. See the GETMBASE function for a list of | |||
valid MBASE variables. | |||
Example: | |||
If GetMBase(1) Then Begin | |||
MBaseName := 'Message Base #1' | |||
PutMBase(1) | |||
End | |||
The above example will read the data for message base #1, set the | |||
name to "Message Base #1" and write the data back to the data file. | |||
Procedure PUTTHISUSER | |||
This procedure will save the USER variables into the currently | |||
logged in user's record. See the GETUSER function for a list of | |||
the USER variables which are saved by the PutThisUser function. | |||
Example: | |||
GetThisUser | |||
WriteLn ('Welcome ', UserAlias, '. Your account is being deleted.') | |||
UserDeleted := True | |||
PutThisUser | |||
HangUp | |||
The above example will load the USER variables with the currently | |||
logged in user's information, then mark them as deleted with the | |||
UserDeleted variable. Their account is then saved with the | |||
PutThisUser procedure and then they are hangup on using the HangUp | |||
command. | |||
Procedure PUTUSER (N: Integer) | |||
This procedure will save the USER variables into the user file. | |||
The passed N parameter is the record number to save under. See | |||
the GETUSER function for a list of the USER variables which are | |||
saved by the PutUser procedure. | |||
Example: | |||
If GetUser(1) Then | |||
Begin | |||
UserDeleted := True | |||
PutUser(1) | |||
End | |||
The above example will attempt to load the data from user record | |||
1 into the USER variables. If the data is loaded without any | |||
errors, it will mark the user as deleted using the USERDELETED | |||
variable, and then save the record back to the user file. | |||
Function READENV (S : String) : String | |||
This function returns the value of the given environment variable | |||
of the operating system. | |||
Function REAL2STR(Real,Int):String | |||
This takes a string and decimal place value. | |||
Ex: | |||
Var | |||
R : Real; | |||
Begin | |||
R := 1234.1234; | |||
WriteLn (Real2Str(R, 2)); // Will print 1234.12 | |||
End | |||
Procedure SYSOPLOG (S: String) | |||
This procedure will add a line into the sysop log file found in | |||
the logs directory. | |||
Example: | |||
SysopLog ('User ran this program.') | |||
The above example will write the text "User ran this program" in | |||
the system log file, using the same format as Mystic uses in the | |||
log files (ie, the date and time will automatically be added). | |||
Function TIMESTR (DT: LongInt, Mode: Byte) | |||
This function converts a packed datetime number into a time | |||
string. The passed mode variable defines the format of the time | |||
string returned. Valid options are: | |||
0 = 24 hour format: HH:MM:SS | |||
1 = 12 hour format: HH:MMa or HH:MMp | |||
Example: | |||
WriteLn ('The current time is: ', TimeStr(DateTime, 1)) | |||
The above example outputs the current time to the screen using the | |||
TIMESTR and DATETIME functions. | |||
Procedure UPUSER (Sec: Byte) | |||
This procedure will upgrade the currently logged in user's | |||
security level using the validation system. The passed value | |||
is the security level to upgrade to and must be between the | |||
range of 0 to 255. | |||
Example: | |||
WriteLn ('Upgrading your access to level 20') | |||
UpUser (20) | |||
The above example will do a validation upgrade to the security | |||
level of 20. | |||
<nowiki>-----------------------------------------</nowiki> | <nowiki>-----------------------------------------</nowiki> |
Latest revision as of 02:03, 26 February 2019
The Mystic BBS Programming Language Documentation
Copyright (C) 1998-2015 By James Coyle. All Rights Reserved
All mentioned programs are copyrighted by their respective authors
-----------------------------------------------------------------------
Introduction to Mystic Programming Language (MPL)
-----------------------------------------------------------------------
The Mystic Programming Language (refered to as MPL from here on out) is
not complete. In the state that it's in now, its still more powerful
than most BBS script languages, but its still not to the point where
it is as powerful as it should be.
The documentation for the MPL is also not complete. This documentation
as well as the Mystic BBS documentation will be worked on as time
permits and may not be completed for quite some time. There are some
example programs included with the distribution (found in the scripts
directory) which may help assist you in getting the hang of the MPL
structure and commands.
If you have written any useful MPL programs, please send them via e-mail
to [email protected] so they can be included for download on the
various Mystic BBS support sites.
-----------------------------------------------------------------------
General Notes About Using The MPL
-----------------------------------------------------------------------
The syntax of the Mystic BBS Programming Language follows closely to
that of the Turbo Pascal series of programming compilers. At one time,
the language was almost 100% Turbo Pascal compatible (except for the
BBS functions) but it has been slightly changed to make it a little
more friendly to the programmer.
Two versions of the programming compiler are available in the scripts
directory. The first one, MIDE.EXE, is a fully functional IDE for
creating and compiling MPE programs. This program looks similar to the
Turbo Pascal IDE, including syntax highlighting of all command keywords!
The second version of the compiler is MPLC.EXE. This is a command line
compiler supplied so you are not forced to use MIDE.EXE to write
programs. If you do not find the MIDE interface to be satisfactory, then
you can use your favorite text editor and MPLC.EXE to create programs!
The following are some quick notes about the syntax of the language as
well as some notes about things that aren't working as they probably
should be:
1. All text after a number sign (#) is considered a comment. It will
be ignored until the next line of code. For example:
WriteLn ('Hello There') # This is a comment and will be ignored.
2. Operation types:
The MPL does not follow the order of operations when doing
mathmatical equations (ie PEMDAS - parenthesis, exponents,
multiplication, division, addition, subtraction). So math functions are done in the order that they appear in the expression. This doesn't mean its not POSSIBLE to do PEMDAS-ordered expressions, it will just take a little more effort on the programmer's behalf. The following operation codes are supported for mathmatical equations:
- Subtract
+ Addition
* Multiplication
/ Division
% Modulus Operator
2a. Bitwise math:
MPL fully supports bitwise math and operators! The following are implemented:
AND - Bitwise AND
OR - Bitwise OR
XOR - Bitwise exclusive OR
SHL - Bitwise shift left
SHR - Bitwise shift right
Example:
Const
UserDeleted = $04; // established bit for userdeleted from records.pas
// note: this value has changed check records.pas!
Begin
GetThisUser
If UserFlags AND UserDeleted <> 0 Then
WriteLn('User is deleted');
End;
3. Defining variables: All variables are global to all of the program,
including procedures. The syntax for declaring a variable follows:
Var <VarName> : <VarType>
Examples:
var dummy : byte
var str : string
var
dummy : byte,
str : string
The following variable types are supported:
Type Format Range
--------------- -------------- -----------------------------------
Boolean FALSE/TRUE 0..1
Char Text 1 character
String Text Sequence of 1..255 characters
Byte Numerical 0..255
Integer Numerical -32767..32767
Word Numerical 0..65535
LongInt Numerical -2147483648..214748364
Real Numerical 9.99
All variables exept ARRAYs can be initialized when when defined.
Var TotalBases : LongInt = GetMBaseTotal(False)
Var Int : Integer = 33
Var Str : String = 'This is a string'
ARRAY multi-dimensional variables are supported. The syntax for
declaring an array variable is:
Var <VarName> : ARRAY[<Low>..<High>] of <VarType>
Var <VarName> : ARRAY[<L>..<H>, <L>..<H>] of <VarType>
Var <VarName> : ARRAY[<L>..<H>, <L>..<H>, <L>..<H>] of <VarType>
Examples:
Var Dummy : Array[1..10] of Byte
Var Str : Array[5..10] of String
Var Int : Array[1..10,1..10,1..10] of Integer
HEXIDECIMAL values are supported. They can be used in numeric
variable assignment numerical evaluation, and in numeric constant
variables. A hex value must begin with a $ character.
Some examples:
Const
MyHexValue = $1F;
Value := $10;
If Value = $10 Then WriteLn('Value is 16 <in decimal>');
3b. Record structures:
Groups data in to records. This command
allows you to create a datatype of multiple different variable
types.
Defining the record:
Type
testrec = record
x : byte;
y : byte;
d : array[1..10,1..5] of string[9]
end
Declaring the record:
Var struct : testrec
Using the record:
struct.x:=1
struct.y:=10
struct.d[1,1]:='abc123'
3c. CODE BLOCKS: When using multiple lines (more than one line) within a
IF/ELSE/WHILE/CASE blocks, the lines need to be grouped into
blocks between BEGIN and END statments. If there is only one line
following the IF/ELSE/WHILE/CASE blocks, then no blocking statements
are needed.
Examples:
If X = 1 Then
Begin
WriteLn('X = '+Int2Str(X))
X:=X+1
WriteLn('X = '+Int2Str(X))
End
The same is true for the ELSE block.
If X = 1 Then
Begin
WriteLn('X = '+Int2Str(X))
X:=X+1
WriteLn('X = '+Int2Str(X))
End
Else
Begin
WriteLn('X = '+Int2Str(X))
X:=X-1
WriteLn('X = '+Int2Str(X))
End
4. FOR LOOPS (FOR/FEND): The syntax for a for loop is as follows:
For <variable> := <start number> <TO> or <DOWNTO> <end number> Do.
For A := 1 to 10 Do
WriteLn (A)
For A := 10 DownTo 1 Do
Begin
WriteLn (A)
WriteLn (A)
End
5. REPEAT/UNTIL: The syntax for a repeat until loop is as follows:
Repeat
<Code here>
Until <Boolean Expression>
IE:
Repeat
WriteLn ('Blah blah')
Until A > 0 or A = 5
6. WHILE: The syntax for a while loop is as follows:
While <Boolean Expression> Do
<Code Here>
IE:
While A > 0 and A = 5 Do
WriteLn ('Blah')
OR:
While A > 0 and A = 5 Do
Begin
WriteLn ('Blah')
WriteLn ('More Blah')
End
7. PROCEDURES: The syntax for defining a procedure is as follows:
Procedure <Proc Name> (<varname vartype>, <varname vartype>)
<Code here>
IE:
Procedure Hello_World
WriteLn ('Hello World')
OR:
Procedure SomeProc (Str String, A Byte)
WriteLn ('Str = ' + Str)
WriteLn ('A = ' + A)
End
OR:
Procedure SomeProc (Str String)
Var
Str2 : String,
Str3 : String
Begin <--- The keyword "BEGIN" is ignored by the compiler
WriteLn (Str) just to maintain a "Pascal-like" feel.
End
8. IF THEN/ELSE/END: The syntax of an if/else/end statement:
If <boolean statement> Then
<True code here>
Else If <boolean statement> Then (optional)
<True code here>
Else (optional)
<False code here>
If Not fEof(fptr) Then
WriteLn ('We''re not at the end of the file.')
The above example is the same as the following example, except we've
added an else statement:
If fEof(fptr) = False Then
WriteLn ('We''re not at the end of the file.')
Else
WriteLn ('This is the end of the file.')
If A = 1 Then
WriteLn ('A is 1')
Else If A = 2 Then
WriteLn ('A is 2')
Else If A = 5 Then
WriteLn ('A is 5')
Else
WriteLn ('A is not 1, 2, or 5...')
8a. CASE statements
This has actually been expanded on
from the Pascal standard but still follows the same syntax. It has been
expanded to allow CASE of more variable types, such as strings. See
the included MPLTEST.MPS for examples.
Var I : Integer = 10
Case I Of
1 : WriteLn('I = 1')
2 : Begin
I:=I+1
WriteLn('I = 3')
End
2,3,4,5,6,7,8,9: WriteLn('Not 1, 2, or 10')
End
Var S : String = 'ABCDEFG'
Case S[3] Of
'A': WriteLn('S[3] = '+S[3])
'B','C','D': WriteLn('S[3] = '+S[3])
Else
WriteLn('This is the default choice')
End
9. The USES command must be declared before ANY other variables
or your program may not function properly. See documentation for
the USES command for further information.
10. FUNCTIONS: The syntax for defining a function is as follows:
Function <Function Name> (<varname vartype>) : <result type>
IE:
Function AddTen (Num Byte) : Byte
Begin
AddTen := Num + 10
End
11. CONST VARIABLES: The syntax for a constant variable is as follows:
String constants:
Const
SomeStr = 'Hello World!'
Numerical constants:
Const
SomeNum = 69
Constant variables, like regular variables, can be separated with a
comma:
Const
SomeNum = 69,
SomeStr = 'Hello World!'
At the moment, constant variables cannot be used in certain places
within the MPE engine. If you are assigning a value to a variable,
constant values will not be recongnized.
-----------------------------------------------------------------------
General Functions and Procedures
-----------------------------------------------------------------------
Function ABS (Num: LongInt) : LongInt
This function takes a signed integer and returns the absolute value.
Example:
Var Int : LongInt = -1234
WriteLn('The absolute value of '+Int2str(Int) +' is '+Abs(Int)+'.')
Function ALLOWARROW (Boolean)
Used to turn on arrow key processing in the READKEY function. It is
also used outside of MPL so use with caution.
Example:
AllowArrow := True
ReadKey
Variable ALLOWMCI (boolean)
This function toggles on/off MCI code parsing. This is used outside of
MPL so adjust this with caution.
Procedure APPENDTEXT (FileName, Text: String).
This procedure will append a single line of text onto a text file. If
the file does not exist, it will be created. Example:
Function BITCHECK (B : Byte; I : Integer) : Boolean
This function accepts a bit position and checks it against an integer,
returning true or false if the bit is on. So for example in the
Records, the third bit in UserFlags is UserDeleted:
GetThisUser
If BitCheck(3, UserFlags) Then WriteLn('User is marked deleted');
Procedure BITSET (B : Byte; I : Integer)
This procedure accepts a bit position and an integer and sets the
bit ON/OFF based on a boolean:
GetThisUser
BitSet(3, UserFlags, True); // user is marked as deleted
Procedure BITTOGGLE (B : Byte; I : Integer)
This procedure accepts a bit position and an integer and toggles the
bit.
GetThisUser
BitToggle(3, UserFlags); // undeletes if they are deleted or deletes if
// they are not deleted.
Variables CFGCHATSTART CFGCHATEND.
These return the byte of the chat hour start and end variables from the
System Configuration
Procedure CLRSCR
This function will clear the screen.
Example:
CLRSCR
Writeln ('The screen was just cleared.')
The above function will clear the screen and write the text "The
screen was just cleared." to the screen.
Function DATE2DOS (Str : String) : LongInt
This function takes a MM/DD/YY format date and converts it to
DOS packed datetime format.
Var DStr : String = '01/01/14'
Var PDt : LongInt
PDt := Date2Dos(DStr)
Function DATE2JULIAN (Str : String) : LongInt
This function takes a MM/DD/YY format date and converts it to a
Julian date format.
Function DATEG2J (Str : String) : LongInt
This function takes a gregorian date format (MMDDYY) and converts
it to a Julian format
Function DATEJ2G (LI : LongInt) : String
This function takes a julian date format and converts it to a
gregorian format (MMDDYY).
Function DATEJULIAN : LongInt
This function returns the Julian value of the current date.
Function DATESTRJULIAN (JD : LongInt) : String
This function returns the MM/DD/YY string value of the julian date.
Function DATEVALID (Str : String) : Boolean
This function takes a MM/DD/YY date and returns true or false
depending on if the date is valid (ie, month is 01-12, etc).
Function DAYOFTHEWEEK
Returns a number between 0-6 depending on the day of the week:
0 = Sun, 1 = Mon, 2 = Tue, 3 = Wed, 4 = Thu, 5 = Fri, 6 = Sat
Function DAYSAGO (JD : LongInt) : Integer
This function takes the Julian date value and returns the number
of days between the current date and the passed date.
Function DAYOFWEEK : Integer
This function will return a number between 0-6 depending on the
day of the week:
0 = Sun, 1 = Mon, 2 = Tue, 3 = Wed, 4 = Thu, 5 = Fri, 6 = Sat
Procedure DELAY (MS: Word)
This procedure will delay for a specified number of milliseconds.
Example:
DELAY (1000)
The above example will delay the program for one second.
Function DOSERROR : Byte
This function returns the current DosError and is used with the
FindFirst and FindNext functions. The possible values which may
be returned by DosError are as follows:
Value Meaning
----- ---------------------
0 No error
2 File not found
3 Path not found
5 Access denied
6 Invalid handle
8 Not enough memory
10 Invalid environment
11 Invalid format
18 No more files
----- ---------------------
Example:
FindFirst ('*.*', AnyFile)
While DosError = 0 Do Begin
WriteLn ('File Name: ', DirName)
FindNext
End
FindClose
The above example will list all files in the current directory.
The DosError function is used to return when there are no more
files to be listed. For more information on this see the reference
for the FindFirst and FindNext functions.
Procedure FINDCLOSE
This function is used along with the FindFirst and FindNext
functions. It is called only after all "Find" procedures have
completed. See the "FindFirst" and "FindNext" command references
for more information.
Procedure FINDFIRST (Mask : String, Attributes)
This function is used to search a drive for files using a supplied
file mask and attribute list. The results of the search are held
in the DIR variables as listed below.
Mask : The mask variable must contain at least a file mask
(ie "*.*") but can also contain a drive and directory name
as well (ie "C:\MYSTIC\TEXT\*.*").
Attributes : The file attributes are used to specify what type of
files to return in the DIR variables. The following
is a list of supported file attributes:
Dec Description Returns
--- ----------- -----------------
001 ReadOnly files marked as "read only".
002 Hidden files marked as "hidden".
004 SysFile files marked as "system files".
008 VolumeID files marked as "volume ID".
016 Directory files marked as "directory".
032 Archive files marked as "archive".
066 AnyFile any and all files.
These attributes can be combined when passed to
FindFirst. For example: 1 + 2 will return
any files which have been marked as "readonly" OR
"hidden". Example: 16 (DIRECTORY) will only return names
of directories.
DIR Variables : The DIR variables are what contain the information
returned by the FindFirst command. If your program
is going to use these variables, it must be declared
with the USES statement at the beginning of your
program source code. The following DIR variables
are supported:
DirName : Holds the file name.
DirSize : Holds the file size.
DirAttr : Holds the file attributes
DirTime : Holds the file date and time in packed
date format. The DateSTR and TimeSTR
functions will need to be used in order
to display these.
Example:
USES DIR
WriteLn ('The following files are in the C:\ directory:')
WriteLn ('')
FindFirst ('C:\*.*', 66)
While DosError = 0 Do
Begin
WriteLn ('File Name: ', DirName)
WriteLn (' Size: ', DirSize)
WriteLn (' Date: ', DateSTR(DirTime), 0)
WriteLn (' Time: ', TimeSTR(DirTime), 1)
Write ('Press a key to search for more.~PN')
FindNext
End
FindClose
WriteLn ('No more files have been found.')
The above example will list all files which fit the file mask of
"C:\*.*" and fit the attributes of either ReadOnly or Archive.
The DOSERROR function is used to determine when there are no more
files found (See the DOSERROR reference). If a file has been
found, it will then be printed to the screen using the DIR
variables. The FindNext functon is used to find the next file
that matches the name and attributes specified in the earlier call
to FindFirst. FindClose is used when all "Find" functions have been
completed.
Procedure FINDNEXT
This procedure is used to find the next file which matches the file
mask and attibutes specified in the last call to FindFirst.
Example:
Uses DIR
FindFirst ('*.*', 32)
While DosError = 0 Do
Begin
WriteLn ('File Name: ', DirName)
FindNext
End
FindClose
The above example uses the FindFirst/FindNext functions to do a
listing of all files in the current directory. The DosError
function is used to determine when no more files have been found.
Procedure GOTOXY (X: Byte, Y: Byte)
This procedure will move the cursor to a specified X and Y
position on the screen. This only works for users who have ANSI
graphics.
Example:
CLRSCR
GotoXY (1, 10)
WriteLn ('Hello')
The above example will clear the screen then goto the first column
of the tenth line and output the text "Hello" to the screen.
Procedure HALT
This procedure will exit the program and return the user back to
the BBS immediately.
Example:
If Graphics = 0 Do
Begin
WriteLn ('Sorry, you do not have ANSI graphics.')
Halt
End
The above example will check to see if the user has ANSI graphics
and if not, display "Sorry, you do not have ANSI" and exit the
program immediately by using the HALT command.
Function INITIALS (String) : String
This function takes a user name and attempts to return one or two
character initials.
S := Initials('Jack Phlash'); // should return "JP"
Function INPUT (Field: Byte, Max: Byte, Mode: Byte, Default: String) : String
This function gives input to the user, and returns the result of
the input as a string variable.
The Field parameter is the size of the input field (in characters)
that the user will be able to see. If the field size is smaller
than the maximum number of characters allowed in the input, the
input line will scroll when the user reaches the end. This field
is usually set to the same as the Max parameter.
The Max parameter is the maximum number of characters that
Input will allow to be entered. Note that the Field parameter, in
most cases, should be set to the same value as this.
The Mode parameter is the type of input that will be accepted, and
can be any one of the following input types:
1 : Standard input. All characters allowed.
2 : Upper case input. Allows all characters, but will convert
any lower case letters into upper case.
3 : Proper input. Allows all characters, but will convert
the first letter in each word to an upper case letter.
4 : Phone input. Allows only numbers and will pre-format them
using the USA-style phone numbers. IE: XXX-XXX-XXXX.
Note that the length of this input should always be 12,
as that is the length of the USA phone number format.
5 : Date input. Allows only numbers and will pre-format them
using the date format (ie XX/XX/XX) that is currently
selected by the user. NOTE: The date input will always
return the date in the MM/DD/YY format, regardless of what
format the user has selected. For example, if the user
has selected the DD/MM/YY format, Input will expect the
user to enter the date in that format, but will then
convert it to MM/DD/YY when it returns the date back to
the MPE program.
6 : Password input. Allows all characters, but will convert
any lower case letters into upper case. The character
that is typed is NOT echoed to the screen. Instead, it
is replaced by the * character so that what they have
entered will not be shown on the screen.
7: Lowercase Allows characters but will be lowercase.
8: User Defined Input (from system config)
9: Standard Input with no CR
10: Number Input numbers only and +-
NOTE: If any of the above input values are increased by 10, Input
will create an input field using the foreground/background color
that has been defined for that language. For example, input type
11 will function the same as input type 1, but will fill an input
field to the maximum field length.
The Default parameter can be used to force a default text into
the input field. If you do not wish to have any default text in
the buffer, supply a blank string parameter (ie '').
EXAMPLE:
Var Str : String
Write ('Enter something: ')
Str := Input (30, 30, 1, '')
The above example will print the text "Enter something: " to the
screen and the allow input of up to 30 characters in length, using
input type 1 (allows all characters). No default text has been
supplied so the input field will be empty by default.
Var Str : String
Write ('Enter something: ')
Str := Input (30, 30, 11, 'Default')
The above example will function just like the first example, except
it will create an input field background and stuff the text of
"Default" into the input field.
Function INPUTNY (Text: String) : Boolean
This function prompts the user with a Yes/No question, defaulting
to No. TRUE will be returned if the user answered Yes, or FALSE if
the user answered No. The passed Text variable is the text that is
displayed to the user asking the question.
Example:
If Not InputNY('Do you want to run this program? ') Then
Halt
The above example will prompt the user with the Yes/No question
passed as <Text>. This question will default to No. If the user
answers No, the program will halt from being executed.
Function INPUTYN (Text: String) : Boolean
This function prompts the user with a Yes/No question, defaulting
to Yes. TRUE will be returned if the user answered Yes, or FALSE
if the user answered No. The passed Text variable is the text
that is displayed to the user asking the question.
Example:
If Not InputYN('Do you want to run this program? ') Then
Halt
The above example will prompt the user with a Yes/No question,
asking "Do you want to run this program?". If the user responds
No, the program will not run, using the Halt command.
Function ISARROW : Boolean
This function is used along with the READKEY function. After
READKEY is called, this function can be checked to process various
extended keys, such as arrow keys. When ISARROW is true, READKEY
will return the following:
ASCII # Char Key Pressed
------- ---- -----------
71 G Home
72 H Up Arrow
73 I Page Up
75 K Left Arrow
77 M Right Arrow
79 O End
80 P Down Arrow
81 Q Page Down
83 S Delete
The character returned by READKEY can be checked by either the
ASCII # or the actual character. Below is an example:
Example:
Var Ch : Char
Ch := ReadKey # Input one key
If IsArrow Then # Is key returned an arrow key?
If Ch = 'H' Then
WriteLn ('Up arrow')
Else If Ch = Chr(80) Then
WriteLn ('Down arrow')
Else # No arrow key. A normal character
WriteLn ('You entered character: ', Ch)
The above example reads a key with READKEY and then uses the
ISARROW function to process the Up Arrow and Down Arrow keys.
Function ISUSER (String) : Boolean
This function takes a string value which can contain either a user
realname, handle, or user perm index number. If the user exists,
it will return a TRUE result or FALSE if the user does not exist.
Function KEYPRESSED : Boolean
This function returns TRUE if a key has been pressed either
remotely or locally. Keep in mind two things about this
function:
(1) It doesn't check for inactivity timeout. If you are
using this function to wait for a key to be pressed then
you may want to use the TIMER function and check for
inactivity.
(2) This function only returns whether a key was PRESSED.
It does not actually read the key out of the buffer.
See the READKEY function for reading keys from the
buffer.
Example:
Repeat
Until KeyPressed
WriteLn ('You pressed a key!')
The above example will wait for a key to be pressed and then
write to the screen "You pressed a key!".
Function MCI2STR (String) : String
This function will take the value of the supplied 2-character MCI
code (without pipe) and returns the string value of that code.
Ex:
Var BBSName : String
BBSName:=MCI2Str('BN')
WriteLn('The name of this BBS is "'+BBSName+'"')
Function MCILENGTH (String) : Integer
This function works just like LENGTH except it tries to ignore MCI
codes. It doesn't check for actual validity of MCI codes.
Var B : Byte;
B := MCILength('|15Hello|UH');
WriteLn ('Length should be 5: ' + Int2Str(B));
Function MOREPROMPT : Char
This function displays the system more prompt and returns a Char
value of either Y N or C depending on what the user selected.
Var C : Char
C:=MorePrompt
Procedure MOVEX (Pos : Byte)
This procedure is used to move the cursor to the passed X coordinate
on the screen. It only works if the user has ANSI graphics enabled.
Example:
MoveX (20)
WriteLn ('This text starts on the 20th space')
Procedure MOVEY (Pos : Byte)
This procedure is used to move the cursor to the passed Y coordinate
on the screen. It only works if the user has ANSI graphics enabled.
Example:
MoveY (10)
WriteLn ('This is on the 10th line of the screen')
Function PARAMCOUNT : Byte
This function is used to determine the number of command line
options which have been passed to the MPE program. For more
information, see the PARAMSTR function.
Example:
If ParamCount < 2 Then Begin
WriteLn ('Invalid command line.')
Halt
End
The above example will check to see if less than 2 command line
options have been passed to the MPE program. If there are less
than two, the program will terminal with a "invalid command line"
message.
Function PARAMSTR (Number : Byte) : String
This function returns the command line option specified by the
NUMBER parameter. A command line is the optional data which
is passed on the "Data" field of a menu command. For example,
when defining a menu command which executes an MPE program in
the menu editor, the text after the program name becomes command
line options.
Menu Command: GX
Data : BULLETIN p1 p2 p3 p4
If the above was defined in the menu editor, the following would
be true:
ParamCount would return 4
ParanStr(0) would return "BULLETIN"
ParamStr(1) would return "p1"
ParamStr(2) would return "p2"
ParamStr(3) would return "p3"
ParamStr(4) would return "p4"
Note that ParamStr(0) will ALWAYS return the file name of the
MPE program being executed. Even when there are no other
parameters defined.
Procedure PAUSE
Envokes the Mystic pause prompt as defined in the current
language file.
Function PAUSEPOS : Byte
This function gives access to Mystic's internal line
counter used for screen pauses.
Function RANDOM (Max: Word) : Word
This function will return a random number within the range
specified.
Example:
Var A : Byte
A := Random(255)
WriteLn (A)
The above example will generate a random number within the range
of 0 to 255 in the variable A and then print it to the screen.
Function READKEY : Char
This function will read a key from the buffer and return it as
a char variable. If there are no keys in the buffer, readkey will
wait for a key to be pressed.
Example:
Var Ch : Char
Repeat Until KeyPressed
Ch := ReadKey
WriteLn ('You entered: ', Ch)
The above example will wait for a key to be pressed by using the
KEYPRESSED function. Afterwards, the key will be read into the
CH variable using readkey, and then print it to the screen.
Procedure SETPROMPTINFO (N : Integer; S : String)
This allows you to set Mystic's internal "changing" PromptInfo MCI
codes (the |&X codes). For example:
SetPromptInfo(1, 'Hello!');
WriteLn ('This MCI code would like to say: |&1');
As a side note, there is NOT a GetPromptInfo because you can simply use
MCI2STR:
WriteLn('This MCI code would like to say: ' + Mci2Str('&1'));
Procedure STUFFKEY (S : String)
This function will stuff a string of text into the keyboard
buffer. This can be used to force your program into thinking
the user had actually typed <S>.
Example:
Var Ch : Char
StuffKey ('A')
Ch := ReadKey
WriteLn ('You entered: ', Ch)
The above example will stuff the character "A" into the input
buffer, where it will be read into Ch using the ReadKey function.
It is possible to stuff entire strings of text into the buffer
too.
Example:
Var Str : String
StuffKey 'Hello World'
Str := Input (20, 20, 1, '')
The above example will stuff "Hello World" into the input buffer.
This will cause the input function to think the user has actually
typed in "Hello World". In this case, the above is the same as
supplying "Hello World" in the <DEFAULT> field of the Input
function.
Function TIMER : LongInt
This function will return the current number of seconds which have
passed since midnight. This function can be used to time how long
a user is doing something.
Example:
Var StartTime : LongInt
Var EndTime : LongInt
Var Total : LongInt
Var Str : String
StartTime := Timer
Write ('Enter something: ')
Str := Input (40, 11, 'Nothing')
EndTime := Timer
Total := EndTime - StartTime
WriteLn ('You took ', Total, ' seconds to type something!')
The above example will prompt the user to type something and time
how long in seconds they took. WriteLn will then display the
number of seconds the user took to the screen.
Function TIMERMIN : LongInt
This function works just like TIMER except returns minues
instead of seconds.
Function WHEREX : Byte
This function returns the current X coordinate of the cursor.
Example:
Var X : Byte
Var Y : Byte
X := WhereX
Y := WhereY
WriteLn (' World')
GotoXY (X, Y)
WriteLn ('Hello')
The above example will save the current X and Y cursor positions
and then write the text "World" to the screen. After which, it
will return to the saved X and Y position and write the text
"Hello" to the screen. The end result will be the text of
"Hello World" written to the screen. Note: GotoXY can only be
used if the user has ANSI graphics mode.
Function WHEREY : Byte
This function returns the current Y coordinate of the cursor.
For more information on this function, please see the definition
of the WHEREX function.
Procedure WRITE (Text)
This procedure is used to write text to the screen without
going to the next line (ie, without sending a carriage return).
All text to be printed to the screen should be enclosed inside of
' characters. If you wish to print the value of a variable to
the screen, just include the variable name without the '
characters. If you wish to combine multiple text and variables,
they must be separated by commas.
Examples:
Write ('Hello ')
Write ('World')
This example will write the text "Hello World" to the screen.
Write ('Hello World')
This example does the exact same thing as the function above, but
makes a little more sense.
Var Str : String
Str := 'Hello World'
Write (Str)
This example will write the value held in the variable Str to the
screen. The resulting output will be "Hello World"
Var Str : String
Str := 'Hello '
Write (Str, 'World')
This example will write the value of the variable Str to the
screen, followed by the text "World". The resulting output will
be "Hello World". An unlimited number of variables and text can
be outputted with the Write statement, but they must all be
separated by a comma, as shown above.
If a ' character needs to be printed to the screen, it can be done
by doubling the ' character. For example:
Write ('This is how it''s done.')
The resulting screen output will be "This is how it's done", with
only one ' character.
All MCI display codes can be used within the Write statement. If
you wish to change the display colors, use the MCI color system to
do so. For example:
Write ('~14Hello World')
This example will write the text Hello World in yellow to the
screen. All MCI display codes are available to the write
statement.
Procedure WRITELN (Text)
This procedure outputs text to the screen. It functioning is
identical to the WRITE statement except that it goes to the next
line after the text is printed (ie, it sends a carriage return).
For example:
WriteLn ('Hello')
WriteLn ('World')
The above example will write the text "Hello" on one line, and
then the text of "World" on the next line.
Procedure WRITEPIPE (Text)
This function works just like WRITE but only parses pipe color
codes instead of all MCI codes.
Procedure WRITEPIPELN (Text)
This procedure works just like WRITEPIPE but with a CRLF at the end.
Procedure WRITERAW (Text)
This procedure works just like WRITE except it does not parse
any pipe color codes OR MCI codes.
Procedure WRITERAWLN (Text)
This procedure is the same as WRITERAW, but with a CRLF at the end.
Procedure WRITEXY (X,Y,Z: Byte; Str : String)
This procedure writes a string of text at the defined X/Y location with a
specific text color attribute 'Z'. This of course requires the user has
ANSI to function properly. This function will NOT parse MCI pipe codes.
Example:
WriteXY (1, 10, 8, 'Prints at X:1 Y:10 with dark grey text');
Procedure WRITEXYPIPE (X,Y,Z: Byte; Len: Integer; Str : String)
This procedure writes a string of text at the defined X/Y location with a
specific text color attribute 'Z'. This of course requires the user has
ANSI to function properly. This function will NOT parse MCI pipe codes.
Example:
WriteXYPipe (1, 10, 8, 50, 'This pads to 50 chars at location 1,10');
-----------------------------------------------------------------------
String Handling Functions and Procedures
-----------------------------------------------------------------------
Function ADDSLASH(S: String) : String
takes a directory and appends the appropriate ending backslash or
forward slash depending on operating system. If the slash is already
there, it does nothing.
Function CHR (B: Byte) : Char
This function will take a numerical byte value and return it's
ASCII character. The byte value must be between 0 and 255 as
there are only 255 characters in the ASCII character set.
Example:
WriteLn ('Hello', Chr(32), 'World')
This will output the text "Hello World" to the screen. The ASCII
number for the space character is 32 and by passing a 32 to CHR,
a space is returned.
Function COPY (S: String, Index: Byte, Count: Byte) : String;
This function will copy a defined part of a string and return
the copied portion as a string.
Example:
Var Str : String
Str := 'Hello World'
WriteLn (Copy(Str, 1, 5))
This will output "Hello" to the screen. The copy function takes
the given Str and copies Count number of character from the Index.
So the above copies 5 characters starting at the 1st character in
Str and WriteLn outputs it to the screen.
Procedure DELETE (S: String, Index: Byte, Count: Byte)
This procedure will delete a defined portion of a string
variable.
Example:
Var Str : String
Str := 'Hello World'
Delete (Str, 6, 6);
WriteLn (Str)
This example will delete 6 characters from the string Str starting
at the 6th character. The resulting output from WriteLn will be
"Hello"
Function FillChar (V: Variable; S: LongInt; C Char ): String
Fills variable V with Char C for S size.
type
myuserrecord = record
username : string[30];
somevalue : array[1..5] of byte;
end;
var
u : myuserrecord;
begin
fillchar(u, sizeof(u), #0);
end.
Procedure INSERT (Source: String, Target: String, Index: Byte)
This procedure will insert text into a string at a specified
location.
Example:
Var Str : String
Str := 'Mystic v1.00'
Insert ('BBS ', Str, 8)
WriteLn (Str)
The above example will insert the text "BBS" into the Str variable
starting at the 8th character in the string. The result WriteLn
output would be "Mystic BBS v1.00"
Function INT2STR (L: LongInt) : String
This function converts a numerical type variable to a string
type variable.
Example:
Var A : Byte
Var S : String
A := 255
S := Int2Str(A)
WriteLn (S)
The above example sets the numerical variable to the value of
255, which is then converted to a string variable using Int2Str.
The resulting value of S will be '255' as WriteLn will output to
the screen.
Function LENGTH (S: String) : Byte
This function returns the length in characters of the passed
string variable.
Example:
WriteLn (Length('Hello World'))
The above example would output "11" to the screen, which is the
number of characters in the text passed to Length.
Function LOWER (S: String) : String
This function converts a passed string variable to all lower
case letters.
Example:
WriteLn (Lower('HELLO'))
The above statement would output the text "hello" to the screen.
The original text of HELLO is converted to all lower case letters
and than displayed by WriteLn.
Function ONEKEY (Keys : String; Echo : Boolean) : Char
This function accepts a string of uppercase letters, and wait for
input from the user. If the keystroke is among the characters in
Keys, it will return that character. If the keystroke is not among
the Keys string, it will do nothing. If Echo is set to TRUE, it
will also echo the Key to the screen.
Var Ch : Char
Var Keys : String = 'ABCDQ'
Ch := OneKey(Keys,True)
WriteLn('You selected '+Ch+'.')
Function ONEKEYRANGE (String, Int, Int ) : Char
This function works similar to OneKey, except that it will also allow
for a number input within a certain range. The number value is
stored in a variable called RangeValue and the function returns a #0
if a number was entered. For example:
Var
Ch : Char;
Begin
Write ('Enter letters A-G or a number between 1-50: ');
Ch := OneKeyRange('ABCDEFG', 1, 50);
If Ch = #0 Then
WriteLn ('You entered a number: ' + Int2Str(RangeValue))
Else
WriteLn ('You entered character: ' + Ch);
End.
Function ORD (C: Char) : Byte
This function returns the ASCII code of the passed Char variable.
This function works the exact opposite of the CHR function.
Example:
WriteLn (Ord(' '))
The above example would output the text "32" to the screen because
32 is the ASCII character code for space.
Function PADCT (S: String, N: Byte, C: Char) : String
This function pads a string to the center with the specified
character.
Example:
Var Str : String
Str := PadCT('Hello World', 80, ' ')
WriteLn (Str)
The above example would display the text "Hello World" centered on
the screen. The PadCT function returns the text "Hello World"
centered in 80 spaces with the character of " " used to fill the
blank spaces.
Function PADLT (S: String, N: Byte, C: Char) : String
This function returns a text string padded with spaces to the
left side.
Example:
Var Str : String
Str := PadLT('Hello World', 79, ' ')
The above example would return a string which is 79 characters in
length with the text "Hello World" as the leftmost part of the
string. The passed character is the character that is used to
fill the blank spaces.
Function PADRT (S: String, N: Byte, C: Char) : String
This function returns a text string padded with spaces to the
right side.
Example:
Var Str : String
Str := PadRT('Hello World', 79, ' ')
The above example would return a string which is 79 characters in
length with the text "Hello World" being the rightmost part of the
string. The empty spaces are filled with the passed charcter (in
this case ' ').
Function POS (Sub: String, S: String) : Byte
This function returns the starting position of a substring in a
string.
Example:
Var A : Byte
A := POS('World', 'Hello World')
WriteLn (A)
The above example would output "7" to the screen becase POS
returns the position of the text "World" in the string
"Hello World". If POS does not find a match, a zero will be
returned. IE: A := POS('Blah', 'Hello World') would return a zero
because the text "Blah" was not found in the string "Hello World".
Function REPLACE(Str1, Str2, Str3 : String) : String
This function replaces all occurances of a supplied text and
returns a string. Ex:
Var Str : String = 'Hello Hello Hello';
Str := Replace(Str, 'Hello', 'World'); // Str is now World World World
Function STRCOMMA(LI : LongInt) : String
This function accepts a longint and returns it as a string, with
commas added where applicable:
Ex:
WriteLn (strComma(1000000)); // will print 1,000,000
Function STR2INT (S: String) : LongInt
This function converts a passed string variable to a numerical
variable. The passed string variable must contain a valid number.
Example:
Var A : Byte
Var S : String
S := '100'
A := Str2Int(S)
WriteLn (S)
WriteLn (A)
The above example will output "100" twice the screen. The
variable S is assigned to '100' and the function Str2Int converts
the string into a numerical value which is assigned to variable
A.
Function STRIPB (S1, S2 : String) : String
This function strips both sides of the string if a specific character.
Var S : String = ' Hello ';
S := StripB(S, ' ');
Function STRIPL (S1, S2 : String) : String
This function strips the left side of a string of any specified
leading characters.
Var S : String = ' Hello';
S := StripL(S, ' ');
Function STRIPR (S1, S2 : String) : String
This function strips the right side of a string of any specifcied
trailing character:
Var S : String = 'Hello ';
S := StripR(S, ' ');
Function STRIPLOW (String) : String
This function strips all chracters from a string that are less than
ascii code #32.
Var S : String = #12#12#12#12 + 'Hello';
S := StripLow(S);
Function STRIPMCI (S : String) : String
This function will strip the passed string variable of all MCI
codes and return the "cleaned" version.
Example
Var S : String
S := '|10|H|02ello |10W|02orld|07'
WriteLn ('Normal : ', S)
WriteLn ('Stripped : ', StripMCI(S))
The above example assigns a string with MCI codes in it to the S
variable. It then writes the original string and the stripped
string to the screen, so the difference is shown.
Function STRIPPIPE (String) : String
This function takes a string and strips only pipe color codes
from it.
S := StripPipe('|15Hello there, |UH'); //returns "Hello There, |UH"
Function STRMCI (String) : String
This function takes an entire string and attempts to translate any
MCI codes found in it, returning the entire result.
S := StrMci('Hello |UH');
Function STRREP (Ch: Char, Num: Byte) : String
This function returns a string filled with character <CH> to the
length of <NUM>.
Example:
WriteLn (strRep('-', 60 ))
The above example will use strRep to create a string 60 characters
long of the character '-', then write it to the screen. So the
outputted text would look like:
"------------------------------------------------------------"
Function STRWRAP(Str, Str2 : String; Len: Integer) : Byte
This function takes two strings and wraps them after the word closest
to the maximum supplied length. It optionally returns the actual
position where it wrapped.
Var Str : String = 'This will wrap';
Var Str2 : String = '';
Var Where : Byte;
Where := strWrap(Str, Str2, 10);
WriteLn ('It wrapped at ' + Int2Str(Where));
WriteLn ('First string: ' + Str);
WriteLn ('Second string: ' + Str2);
Function UPPER (S: String) : String
This function coverts the passed string variable to all upper
case letters.
Example:
WriteLn (Upper('hello'))
The above example would output the text "HELLO" to the screen.
The UPPER function converts the passed text of "hello" to all
upper cased letters, which is then printed to the screen by
WriteLn.
Function WORDCOUNT (S,C: String) : Integer
Function WordCount returns the number of words in a string using
the final parameter to define the character that determines what
separates words. Ex:
Str := 'Hello this is a test';
WriteLn ('Str has ' + Int2Str(WordCount(Str, ' ')) + ' words in it.');
Function WORDGET(I : Integer, S, C : String) : String
returns the actual word at a specific word count.
S is the inputted string value.
I is the numerical value of the position where the word can be found.
C is the string value used as the word separater.
Ex:
Str := 'Hello this is a test';
WriteLn('The second word was: ' + WordGet(2, Str, ' '));
Function WordPos (I : Integer; S, C : String ) : Integer
Function WordPos returns the character position in the string where
specific word is located.
S = Inputted string value
I = Index value of the the desired word within S
C = String value of the word separater.
Ex:
Str := 'Hello this is a test';
WriteLn ('Second word is at: ' + Int2Str(WordPos(2, Str, ' ')));
See Also : WordCount, WordGet
-----------------------------------------------------------------------
File Accessing Functions and Procedures
-----------------------------------------------------------------------
Function FEOF (Handle) : Boolean
This function will return true if the file position of an opened
file is at the End Of the File (EOF). The passed Handle value is
the file number of the already opened file.
Example:
Var Str : String
Var Fpt : File
FOpen (1, Text, Reset, 'BLAH.TXT')
While Not Eof(1)
FReadLn (1, Str)
WriteLn (Str)
End
FClose (1)
The above example will open a text file under the filename of
BLAH.TXT. The WHILE loop is used to repeat the code until the
EOF (end of file) is reached. The FCLOSE statement will close
the file after it is done being accessed.
The result of the above example will be (in pseudocode):
1. Open text file.
2. If not at the end of file, run this code:
3. Read line from text file into string variable
4. Print line read from text file to the screen.
5. Goto 2.
6. Close the text file.
So the above example will basically write the entire text file to
the screen.
Procedure FCLOSE (File)
This procedure closes an already opened file. The passed Handle
value is the file number of the opened file. All files which
are opened MUST be closed after they are not being accessed any
more.
For example:
Var Fptr : File
fAssign (Fptr, 'BLAH.TXT', 66)
fReWrite (Fptr)
<Code to access file goes here>
fClose (Fptr)
The above example opens a file using the FOPEN procedure. When
the file has been opened successfully, it can be accessed in
various ways using the file I/O functions. Afterwards, it MUST
be closed using the FCLOSE procedure as shown above.
Function FILECOPY (Source: String, Dest: String) : Boolean
This function will copy a file from the specified source location
to the specified destination location. The function will return
as TRUE if the file was copied successfully, or FALSE if an error
occured. Note: The file which is being copied should not already
be opened for File I/O by the program.
Example:
Write ('Copying C:\HELLO.TXT -> D:\HELLO.TXT: ')
If fileCopy ('C:\HELLO.TXT', 'D:\HELLO.TXT')
WriteLn ('OK')
Else
WriteLn ('ERROR')
End
The above example will attempt to copy the file "C:\HELLO.TXT" to
the destination of "D:\HELLO.TXT". If the file is copied without
any problems an "OK" will be printed to the screen. If an error
occured while copying, "ERROR" will be printed to the screen.
Procedure FILEERASE (FileName: String)
This procedure is used to erase an existing file from the disk.
The FileName variable is a string variable which contains the
file name which is to be erased. The result of the FILEERASE
procedure can be checked by checking the DOSERROR function.
DOSERROR will return a 0 if successful or a 2 if an error occured.
Example:
FileErase ('C:\HELLO.TXT')
The above example will erase the file "C:\HELLO.TXT" if it exists.
Function FILEEXIST (FileName: String) : Boolean
The above function will check to see if a file exists, and return
TRUE if it does. The passed FileName string if the path and file
name of the file to check. This file should not already be opened
with the FOPEN procedure.
Example:
If FileExist('BLAH.TXT') Then
WriteLn ('BLAH.TXT exists.')
Else
WriteLn ('BLAH.TXT does NOT exist.')
The above example will check to see if the file "BLAH.TXT" exists
and if it does, will output "BLAH.TXT exists" to the screen. If
BLAH.TXT does NOT exist, the output will be "BLAH.TXT does NOT
exist".
Function FPOS (File) : LongInt
This function returns the current file position of an opened
file. The passed Handle is the file handle number used when the
file was opened. The FilePos function only works for files that
are opened as Binary, since Text files are read line by line.
Example:
Var Fptr : File
fAssign (Fptr, 'TEST.DAT', 66)
fReset(Fptr)
If IORESULT = 0 Then Begin
If fPos(Fptr) = FSize(Fptr)
WriteLn ('END OF FILE.')
End
fClose (fPtr)
End
The above example opens the file "TEST.DAT" for binary and then
writes to the screen if the file position is at the end of the
file. The above statement "fPos(Fptr) = fSize(Fptr)" is the same
as "fEof(Fptr)" since it's stating "if the file position is equal to
the total file size, then we're at the end of the file."
Function FSIZE (File) : LongInt
This function returns the total file size of an opened file. The
passed Handle is the file handle number used when the file was
opened. This function only works with files that have been opened
as Binary since Text files are read line by line.
Example:
Var Fptr : File
fAssign (Fptr, 'TEST.DAT', 66)
fReset(Fptr)
If IoResult = 0 Then
WriteLn ('This file is ', fSize(Fptr), ' bytes in size.')
fClose (Fptr)
The above example opens the file "TEST.DAT", writes the size of
the file to the screen, and then closes the file.
Procedure FASSIGN (Fptr : File, Mask : String, Attr : Int)
This procedure opens a text or binary file for file operations.
Fptr : The passed file pointer is the file reference, of type FILE
Mask : The path and filename of the file to open, in string format.
Attr : File attributes to open. See FINDFIRST for more info.
EXAMPLE:
Var Fptr : File
fAssign (Fptr, 'BLAH.TXT', 66)
fReWrite (Fptr)
fWriteLn (Fptr, 'Hello World!')
fClose (Fptr)
The above example creates a text file under the name 'BLAH.TXT'.
If BLAH.TXT already exists, it will be erased and replaced by a
new BLAH.TXT file. The FWriteLn writes the text "Hello World" to
the file, and then FClose closes the file.
Procedure FRESET (File)
This procedure moves the file pointer to the beginning of an already
opened file. This is useful for moving the file pointer to specific
spots in the file, without having to close and reopen the file. The
file must have previously been opened by FASSIGN.
Use IORESULT to determine if the freset command was successful.
Var fPtr : File
fAssign(Fptr,CfgDataPath+'somefile.dat',66)
fReset(Fptr)
If IORESULT = 0 Then Begin
WriteLn('somefile.dat is opened for use!')
WriteLn('closing somefile.dat!')
fClose(Fptr)
End Else
WriteLn('Unable to open somefile.dat')
Procedure FREWRITE(File)
This procedure will this will erase an existing file and recreate it,
leaving the file position at the beginning of the file. If the
file does not already exist, MPL will create the file. The file must
have previously been opened by FASSIGN.
Procedure FSEEK (Fptr: File, Position: LongInt)
This procedure seeks to a file position in a binary file. It
will only work on binary files, not text file.
Fptr : The passed file pointer value of type FILE
Position : This is the position where FSEEK will seek to.
EXAMPLE:
Var Str : String
Var Fptr: File
Str := 'Hello World!'
fAssign (Fptr, 'BLAH.DAT',66)
fSeek (Fptr, FileSize(1))
fWriteRec (Fptr, Str, 12)
fClose (Fptr)
The above example opens an already existing file under the name
'BLAH.DAT'. Using FSEEK, it will seek to the end of the file,
so that "Hello World" can be added as the last record.
Procedure FREAD (File, Str, Int)
This procedure is used to read binary data from a file.
Type FileInfo = record
Index : Integer
Name : String [50]
Data : Integer
End
Var fptr : File
Var info : FileInfo
Var Recno: Integer = 3
fAssign(Fptr,'FILE.DAT',66) // Open the file
fReset(Fptr) // Reset to the beginning of the file
If IoResult = 0 Then Begin // If successful...
fSeek(Fptr,(Recno-1)*SizeOf(Info)) // Go to 3rd record in the file
If Not fEof(Fptr) Then // If the 3rd record is there...
fRead(Fptr,Info,SizeOf(Info)) // Read the record
// Optionally, use FreadRec(Fptr,Info) when reading record types.
End
fClose(Fptr) // close the file
Procedure FREADLN(File,Str)
This procedure will read string data from a text file.
Var fptr : File
Var Str : String
fAssign(Fptr,'somefile.txt',66)
fReset(Fptr)
If IoResult = 0 Then Begin
While Not fEof(Fptr) Do Begin
FReadLn(Fptr,Str)
WriteLn(Str)
End
fClose(Fptr)
End
Procedure FWRITE (File, Str, Int)
This procedure is used to write binary data to a file.
Type FileInfo = record
Index : Integer
Name : String [50]
Data : Integer
End
Var fptr : File
Var info : FileInfo
info.Index:=1
info.Data:=33
info.Name:='newname'
fAssign(Fptr,'FILE.DAT',66)
fReWrite(Fptr)
fWrite(Fptr,Info,SizeOf(Info))
fClose(Fptr)
Procedure FWRITELN(File,Str)
This procedure is used to save string data to a text file.
Var Fptr : File
Var Str : String = 'I am a string value!'
fAssign(Fptr,'flatfile.txt',66)
fReset(Fptr)
If IoRESULT = 0 Then Begin
// File already exists.
// Seek to the end of the file. aka append to the file
fSeek(Fptr,FSize(Fptr))
End Else Begin
// File is not yet created. Create it now.
fReWrite(Fptr)
End
fWriteLn(Fptr,Str)
fClose(Fptr)
Function SIZEOF (Type) : LongInt
This function will take any named data type as input, and return
the size of the data.
Type TypeOfData = Record
N : Integer
L : Real
V : LongInt
Q : String [32]
End
Var I : Integer
Var S : String [50]
Var R : Real
Var T : TypeofData
WriteLn('Size Of I = '+Int2Str(SizeOf(I)))
WriteLn('Size Of S = '+Int2Str(SizeOf(S)))
WriteLn('Size Of R = '+Int2Str(SizeOf(R)))
WriteLn('Size Of T = '+Int2Str(SizeOf(T)))
-----------------------------------------------------------------------
BBS Related Functions and Procedures
-----------------------------------------------------------------------
Function ACS (S: String) : Boolean
This function processes an ACS string and returns true if the user
has passed.
Example:
If ACS('s10g1') Then
WriteLn ('You have access to this.')
Else
WriteLn ('Sorry, you do not have access.')
The above example checks to see if the user passes the ACS string
of "s10g1" and prints the result to the screen.
Function DATESTR (DT: LongInt, dType: Byte) : Integer
This function will take a packed datetime number and convert it to
a date string. The dType parameter is used to set the format of the
date which is returned. Valid types are:
UserDateType = Returns date in the users date format
1 = Returns date in format: MM/DD/YY
2 = Returns date in format: DD/MM/YY
3 = Returns date in format: YY/DD/MM
Example:
GetThisUser
WriteLn ('Welcome. You last called on ', DateStr(UserLast))
The above example loads the currently logged in user's information
into the USER variables using GETTHISUSER, then displays the last
time the user has called to the screen using the DATESTR procedure.
Function DATETIME : LongInt
This function returns the current Date and Time in the packed
format. DATESTR and TIMESTR can be used to convert this value
into strings.
Example:
WriteLn ('Current Date: ', DateStr(DateTime), 0)
WriteLn ('Current Time: ', TimeStr(DateTime), 1)
The above example outputs the current date and time to the screen
using the DATESTR and TIMESTR functions. The DateTime function
which is passed to DATESTR and TIMESTR, contains the current date
and time in the packed format.
Function DIREXIST (S : String) : Boolean
This function returns TRUE or FALSE if a directory exists.
If DirExist('C:/MYSTIC/TEMP46') Then
WriteLn('Dir C:/MYSTIC/TEMP46 exists!')
Else
WriteLn('Dir C:/MYSTIC/TEMP46 does not exist!')
Procedure DISPFILE (FN: String)
This procedure displays a text or ANSI file to the screen. If a
path not included in the passed filename, Mystic will look for
the file in the language text file directory. If no file
extension is provided in the passed file name, Mystic will display
the correct file according to the user's graphics settings
(ie .ANS for ANSI, .ASC for non-ansi).
Example:
DispFile ('WELCOME')
The above example will display the text file "WELCOME" from the
language text file directory. Since there is no file extension
provided, Mystic will display "WELCOME.ANS" or "WELCOME.ASC"
depending on what the user's terminal settings are.
Procedure FILLCHAR (R : Record; S : Integer; V : Value )
Fillchar fills the memory starting at X with Count bytes or
characters with value equal to Value.
type
myuserrecord = record
username : string[30];
somevalue : array[1..5] of byte;
end;
var
u : myuserrecord;
begin
fillchar(u, sizeof(u), #0);
end.
Procedure GETCFG
This procedure will load the current configuration data into the
CFG variables. The "USES CFG" command must be used at the start
of your program for GETCFG to work. The following variables will
be loaded:
CFGSYSPATH : System Path
CFGDATAPATH : Data Path
CFGMSGSPATH : Message Base Path
CFGPROTPATH : Protocol Path
CFGQWKPATH : Local QWK Path
CFGMPEPATH : Script (MPE) Path
CFGATTPATH : File Attach Path
CFGLOGSPATH : System Logs Path
CFGTEXTPATH : Text Files Path (for the current language)
CFGTEMPPATH : Temp path for the current node
CFGMENUPATH : Menu Files Path (for the current language)
CFGTIMEOUT :
CFGSEEINVIS : Gives the "See Invisible" ACS value
CFGTNNODES : Number of max telnet nodes to allow
CFGNETDESC[1..30] : Give the network descriptions.
Example:
Uses CFG
GetCFG
WriteLn ('Mystic BBS is installed in ', CfgSysPath)
The above example will load the configuration into the CFG
variables, and then print the directory where Mystic BBS is
installed in to the screen.
Function GETATTRXY (X, Y : Byte) : Byte
This function returns the attribute of the character at position
XY on the user's screen:
Var Attr : Byte;
Attr := GetAttrXY(1, 1);
WriteLn ('The attribure of the character at 1,1 is: ' + strI2S(Attr));
Function GETCHARXY (X, Y : Byte) : Char
This function returns the character located on the user's
screen at the XY location.
Var Ch : Char;
Ch := GetCharXY(1, 1);
WriteLn('The user has the following character at 1,1: ' + Ch);
This kind of stuff could allow you to create MPL-based custom screen
effects like TheDraw used to have, except for on-the-fly with whatever
is on the user's screen.
Function GETMBASE (N : Word) : Boolean
This procedure will read message base data into the MBASE variables.
The supplied N is the record number to read. The function will
return TRUE if the record was read successfully, or FALSE if the
record was not read. The "USES MBASE" command must be called at
the start of your program for the MBASE functions to work
correctly.
The following MBASE variables will be set when a record is read:
Variable Name Type Description
-------------------------------------------------------------------
MBASENAME String Name
MBASEACS String ACS level
MBASERACS String Read ACS level
MBASEPACS String Post ACS level
MBASESACS String SysOp ACS level
MBASEINDEX Integer Index number (*NEVER* change this)
Example:
Var A Word
A := 1
While GetMBase Do
Begin
WriteLn ('Base name: ', MBaseName)
A := A + 1
End
The above example will list all available message base systems on
the BBS.
Function GETMBASESTATS (Base : LongInt; B1, B2 : Boolean; Tot, New, Yours : LongInt) : Boolean
This can be used as a function or a procedure (returning true if
successful). It takes 6 parameters.
#1: Message base number
#2: Exclude messages FROM the current user in stats
#3: Exclude messages TO the current user that have already been read
#4: Total messages (this is a VAR parameter)
#5: New messages (this is a VAR parameter)
#6: New messages to you (this is a VAR parameter)
Example:
uses mbase;
var
count, total, new, yours : longint;
begin
count := 1; //start @1 to skip email base
while getmbase(count) do begin
getmbstats(count, true, true, total, new, yours);
writeln('base : ' + mbasename);
writeln('total msgs : ' + int2str(total));
writeln('new msgs : ' + int2str(new));
writeln('your msgs : ' + int2str(yours));
writeln('');
count := count + 1
end;
Function GETMBASETOTAL (Compress : Boolean) : LongInt
This function returns the total message bases on the system. If
Compressed is true, then it will return the total number of message
bases the user has access to (slower to calculate). If it is false,
it returns the raw total number of bases on the system.
Function GETPROMPT (N : Word) : String
This function will return a prompt from the current user's language
file. The passed N varliable is the prompt number to return.
Example:
WriteLn(GetPrompt(1))
The above example writes prompt #1 from the user's currently
selected language file to the screen.
Procedure GETSCREENINFO (I, X, Y, Attr : Integer)
This allows you to read Mystic's internal ScreenInfo codes,
used in Templates - so your MPLs can easily have templates
just like Mystic! These are the |!X codes.
Var
X, Y, Attr : Byte;
Begin
GetScreenInfo(1, X, Y, Attr);
WriteLn('The value of the !1 MCI code was:');
WriteLn(' X: ' + Int2Str(X));
WriteLn(' Y: ' + Int2Str(Y));
WriteLn('Attr: ' + Int2Str(Attr));
End;
Function GETUSER (N: Integer) : Boolean
This procedure will read user data into the USER variables. The
supplied N is the record number to read. The function returns
true if the record was read, or false if a record was not read.
The following USER variables will be set when a record is read:
Variable Name Type Description
-------------------------------------------------------------------
USERDELETED Boolean Is the user marked as deleted?
USERNAME String User's real name.
USERALIAS String User's BBS alias.
USERPASSWORD String User's password.
USERADDRESS String User's street address.
USERCITY String User's City/State.
USERBIRTHDAY String User's birth date.
USERSEX Char User's gender (M = Male, F = FeMale).
USERSEC Byte User's security level (0-255).
USERFIRSTON LongInt User's date/time of first call to the BBS.
This is stored in the packed date format
so in order to display the date & time,
the functions of DATESTR and TIMESTR need
to be used.
USERLASTON LongInt User's date/time of the last call to the
BBS. This is also stored in a packed date
format, so the same rules for USERFIRST
apply to this.
-------------------------------------------------------------------
Example:
Var A Integer
A := 1
While GetUser(A) Do
Begin
WriteLn ('User Alias: ', UserAlias)
A := A + 1
End
The above example will list all user accounts on the BBS system.
Procedure GETTHISUSER;
This procedure loads the user information for the currently
logged in user into the USER variables. See the GETUSER function
for a reference of the USER variables.
Example:
GetThisUser
WriteLn ('Welcome to this BBS, ', UserAlias)
WriteLn ('You have called ', UserCalls, ' times!')
The above example will load the currently logged in user
information into the user variables, then display a line of
text welcoming them to the BBS.
Function GRAPHICS : Byte
This function returns the user's current graphics mode in
numerical format:
0 = ASCII graphics mode
1 = ANSI graphics mode
Example:
If Graphics = 1 Then
WriteLn ('ANSI graphics')
Else
WriteLn ('ASCII graphics')
The above example will print the user's current graphics mode
to the screen. If the user has ANSI (graphics mode 1), "ANSI
graphics" will be printed. If the user does not have ANSI
(graphics mode 0), "ASCII graphics" will be printed to the screen.
Procedure HANGUP
This procedure will stop the program immediately, hangup up on the
user, and return Mystic BBS to the waiting for caller screen.
Example:
If InputYN ('Do you want to hangup now? ') Then
HangUp
The above example will prompt the user with a Yes/No question
asking "Do you want to hangup now?" and if the user responds
"Yes", they will be logged off the BBS using the HangUp command.
Function JustFile (S : String) : String
This function takes a string arguement and returns only the
filename:
WriteLn ('This MPX filename is: ' + JustFile(ProgName));
Function JustFileName (S : String) : String
This function takes a string arguement and returns only the base
filename (ie, not the extension so it basically just removes a file
extension). This does not remove a path, JustFile does that.
WriteLn ('This MPX filename is: ' + JustFileName(ProgName));
Function JustPath (S : String) : String
This function takes a string arguement and returns only the
path (including the trailing backslash).
Ex:
WriteLn ('This MPX is located in ' + JustPath(ProgName));
Function LOCAL : Boolean
This function returns TRUE if the user is logged into the BBS
system locally. It will return FALSE if the user is connected
via a remote location.
Example:
If Local Then
WriteLn ('Local caller detected.')
Else
WriteLn ('Remote caller detected.')
Function MSGEDITOR(0,Int,Int,Int,Bool,Str,Str) : Bool
Procedure MSGEDITSET(Int,Str)
Procedure MSGEDITGET(Int,Str)
Added 3 new MPL functions: MsgEditor, MsgEditSet, MsgEditGet. These
allow access to the internal Mystic msg editor (line and/or full)
from within MPL. It even allows you to define wrap position and
template to completely make it look like its not the Mystic editor!
As a little hint the MsgEditSet and MsgEditGet stuff could be used to
post process message text on posts. Like say for example you wanted
to write a MPL that allows users to add Tag lines, you could do that
by replacing the "Saving message..." prompt and using those two in
order to modify the text before it is saved by Mystic!
Rather than trying to explain it all, here is an example of all 3:
Var
Lines : Integer = 0;
WrapPos : Integer = 79;
MaxLines : Integer = 200;
Forced : Boolean = False;
Template : String = 'ansiedit';
Subject : String = 'My subject';
Count : Integer;
Begin
MsgEditSet (1, 'this is line 1');
MsgEditSet (2, 'this is line 2!');
Lines := 2;
SetPromptInfo(1, 'MsgTo'); // if template uses &1 for "To:" display
If MsgEditor(0, Lines, WrapPos, MaxLines, Forced, Template, Subject) Then Begin
WriteLn('User selected to save.');
WriteLn('There are ' + Int2Str(Lines) + ' of text in buffer:');
For Count := 1 to Lines Do
WriteLn(MsgEditGet(Count));
Pause;
End Else Begin
WriteLn('User aborted the edit.');
Pause;
End
End
Procedure MENUCMD (CM: String, Data: String)
This procedure will allow menu commands to be ran from within a
program. <CM> is the menu command, and <DATA> is the menu command
data.
Example:
MenuCmd ('NW', '')
The above example will run the menu command "NW" with the optional
data field set to nothing. This example will display the Who's
Online list. See MYSTIC.DOC for a list of all available menu
commands.
Function NODENUM : Byte
This function returns the current node number which the program
is being ran on.
Example:
WriteLn ('Welcome to node number ', NodeNum)
The above example will print the text "welcome to node number x"
to the screen, where the x will be the current node number which
the program is being ran on.
Variable PROGNAME : String
Returns the path and filename of the current MPL program
Variable PROGPARAMS : String
Returns any of th eparameters passed to the MPL program as a
single string
Procedure PUTMBASE
This procedure will save the currently loaded MBASE variables into
a message base record. See the GETMBASE function for a list of
valid MBASE variables.
Example:
If GetMBase(1) Then Begin
MBaseName := 'Message Base #1'
PutMBase(1)
End
The above example will read the data for message base #1, set the
name to "Message Base #1" and write the data back to the data file.
Procedure PUTTHISUSER
This procedure will save the USER variables into the currently
logged in user's record. See the GETUSER function for a list of
the USER variables which are saved by the PutThisUser function.
Example:
GetThisUser
WriteLn ('Welcome ', UserAlias, '. Your account is being deleted.')
UserDeleted := True
PutThisUser
HangUp
The above example will load the USER variables with the currently
logged in user's information, then mark them as deleted with the
UserDeleted variable. Their account is then saved with the
PutThisUser procedure and then they are hangup on using the HangUp
command.
Procedure PUTUSER (N: Integer)
This procedure will save the USER variables into the user file.
The passed N parameter is the record number to save under. See
the GETUSER function for a list of the USER variables which are
saved by the PutUser procedure.
Example:
If GetUser(1) Then
Begin
UserDeleted := True
PutUser(1)
End
The above example will attempt to load the data from user record
1 into the USER variables. If the data is loaded without any
errors, it will mark the user as deleted using the USERDELETED
variable, and then save the record back to the user file.
Function READENV (S : String) : String
This function returns the value of the given environment variable
of the operating system.
Function REAL2STR(Real,Int):String
This takes a string and decimal place value.
Ex:
Var
R : Real;
Begin
R := 1234.1234;
WriteLn (Real2Str(R, 2)); // Will print 1234.12
End
Procedure SYSOPLOG (S: String)
This procedure will add a line into the sysop log file found in
the logs directory.
Example:
SysopLog ('User ran this program.')
The above example will write the text "User ran this program" in
the system log file, using the same format as Mystic uses in the
log files (ie, the date and time will automatically be added).
Function TIMESTR (DT: LongInt, Mode: Byte)
This function converts a packed datetime number into a time
string. The passed mode variable defines the format of the time
string returned. Valid options are:
0 = 24 hour format: HH:MM:SS
1 = 12 hour format: HH:MMa or HH:MMp
Example:
WriteLn ('The current time is: ', TimeStr(DateTime, 1))
The above example outputs the current time to the screen using the
TIMESTR and DATETIME functions.
Procedure UPUSER (Sec: Byte)
This procedure will upgrade the currently logged in user's
security level using the validation system. The passed value
is the security level to upgrade to and must be between the
range of 0 to 255.
Example:
WriteLn ('Upgrading your access to level 20')
UpUser (20)
The above example will do a validation upgrade to the security
level of 20.
-----------------------------------------
Other Supported Functions and procedures:
-----------------------------------------
Commands WITHOUT the ** DONE after them have not yet been documented above.
Hopefully all the commands are listed below, but it's possible that I could
have forgot a couple... These docs will be up-to-date as time goes on! :)
ABS ** DONE
ACS ** DONE
ADDSLASH ** DONE
ALLOWARROW ** DONE
CHR ** DONE
CLRSCR ** DONE
CONST
COPY ** DONE
DATESTR ** DONE
DATETIME ** DONE
DELAY ** DONE
DELETE ** DONE
DISPFILE ** DONE
DOSERROR ** DONE
FEOF ** DONE
FCLOSE ** DONE
FCOPY ** DONE
FILEERASE ** DONE
FILEEXIST ** DONE
FOPEN ** DONE
FPOS ** DONE
FSIZE ** DONE
FINDCLOSE ** DONE
FINDFIRST ** DONE
FINDNEXT ** DONE
FREAD
FREADLN
FREADREC
FSEEK ** DONE
FUNCTION
FWRITE
FWRITELN
FWRITEREC
GETCFG ** DONE
GETFBASE
GETMBASE ** DONE
GETPROMPT ** DONE
GETUSER ** DONE
GETTHISUSER ** DONE
GOTOXY ** DONE
GRAPHICS ** DONE
HALT ** DONE
HANGUP ** DONE
INPUT ** DONE
INPUTNY ** DONE
INPUTYN ** DONE
INSERT ** DONE
INT2STR ** DONE
ISARROW ** DONE
ISNOFILE ** DONE
KEYPRESSED ** DONE
LENGTH ** DONE
LOCAL ** DONE
LOWER ** DONE
MENUCMD ** DONE
MOVEX ** DONE
MOVEY ** DONE
NODENUM ** DONE
ONEKEY
ONEKEYRANGE ** DONE
ORD ** DONE
PADCT ** DONE
PADLT ** DONE
PADRT ** DONE
PARAMCOUNT ** DONE
PARAMSTR ** DONE
POS ** DONE
PUTFBASE
PUTMBASE ** DONE
PUTTHISUSER ** DONE
PUTUSER ** DONE
RANDOM ** DONE
READKEY ** DONE
SETPROMPT
SETUSERTIME
STATUSMODE
STATUSUPDATE
STR2INT ** DONE
STRIPMCI ** DONE
STRREP ** DONE
STUFFKEY ** DONE
SYSOPLOG ** DONE
TIMER ** DONE
TIMESTR ** DONE
UPPER ** DONE
UPUSER ** DONE
USES
WHEREX ** DONE
WHEREY ** DONE
WORDCOUNT ** DONE
WORDGET ** DONE
WORPOS ** DONE
WRITE ** DONE
WRITELN ** DONE