More actions
StackFault (talk | contribs) No edit summary |
StackFault (talk | contribs) No edit summary |
||
(One intermediate revision by the same user not shown) | |||
Line 7: | Line 7: | ||
<nowiki>-----------------------------------------------------------------------</nowiki> | <nowiki>-----------------------------------------------------------------------</nowiki> | ||
Introduction to Mystic Programming Language (MPL) | ''' Introduction to Mystic Programming Language (MPL) ''' | ||
<nowiki>-----------------------------------------------------------------------</nowiki> | <nowiki>-----------------------------------------------------------------------</nowiki> | ||
Line 18: | Line 18: | ||
it is as powerful as it should be. | it is as powerful as it should be. | ||
The documentation for the MPL is also not complete. This documentation | The documentation for the MPL is also not complete. This documentation | ||
Line 30: | Line 31: | ||
structure and commands. | structure and commands. | ||
If you have written any useful MPL programs, please send them via e-mail | If you have written any useful MPL programs, please send them via e-mail | ||
Line 39: | Line 41: | ||
<nowiki>-----------------------------------------------------------------------</nowiki> | <nowiki>-----------------------------------------------------------------------</nowiki> | ||
General Notes About Using The MPL | ''' General Notes About Using The MPL ''' | ||
<nowiki>-----------------------------------------------------------------------</nowiki> | <nowiki>-----------------------------------------------------------------------</nowiki> | ||
Line 52: | Line 54: | ||
more friendly to the programmer. | more friendly to the programmer. | ||
Two versions of the programming compiler are available in the scripts | Two versions of the programming compiler are available in the scripts | ||
Line 75: | Line 78: | ||
should be: | should be: | ||
be ignored until the next line of code. For example: | '''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. | WriteLn ('Hello There') # This is a comment and will be ignored. | ||
2. Operation types: | ''' 2. Operation types: ''' | ||
The MPL does not follow the order of operations when doing | The MPL does not follow the order of operations when doing | ||
Line 88: | Line 91: | ||
multiplication, division, addition, subtraction). So math | multiplication, division, addition, subtraction). So math | ||
functions are done in the order that they appear in the expression. | functions are done in the order that they appear in the expression. | ||
This doesn't mean its not POSSIBLE to do PEMDAS-ordered expressions, | 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. | it will just take a little more effort on the programmer's behalf. | ||
The following operation codes are supported for mathmatical | The following operation codes are supported for mathmatical | ||
equations: | equations: | ||
Line 109: | Line 107: | ||
% Modulus Operator | % Modulus Operator | ||
2a. Bitwise math: | ''' 2a. Bitwise math: ''' | ||
MPL fully supports bitwise math and operators! The following are | MPL fully supports bitwise math and operators! The following are | ||
implemented: | implemented: | ||
Line 125: | Line 122: | ||
SHR - Bitwise shift right | SHR - Bitwise shift right | ||
Example: | ''' Example: ''' | ||
Const | Const | ||
Line 201: | Line 198: | ||
<nowiki> Var <VarName> : ARRAY[<L>..<H>, <L>..<H>, <L>..<H>] of <VarType></nowiki> | <nowiki> Var <VarName> : ARRAY[<L>..<H>, <L>..<H>, <L>..<H>] of <VarType></nowiki> | ||
Examples: | ''' Examples: ''' | ||
<nowiki> Var Dummy : Array[1..10] of Byte</nowiki> | <nowiki> Var Dummy : Array[1..10] of Byte</nowiki> | ||
Line 225: | Line 222: | ||
If Value = $10 Then WriteLn('Value is 16 <in decimal>'); | If Value = $10 Then WriteLn('Value is 16 <in decimal>'); | ||
3b. Record structures: Groups data in to records. This command | ''' 3b. Record structures: ''' | ||
Groups data in to records. This command | |||
allows you to create a datatype of multiple different variable | allows you to create a datatype of multiple different variable |
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