Mystic Utilities (MUTIL)
Scripting Custom Modules
Mystic Utilities (MUTIL)
Scripting Custom Modules
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:
All text after a two slashes (⁄⁄) 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.
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 mathematical equations:
− Subtract + Addition * Multiplication ⁄ Division % Modulus Operator
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
Const UserDeleted = $00000004; // Deleted bit from records.pas Begin GetThisUser; If UserFlags AND UserDeleted <> 0 Then WriteLn('User is deleted'); End;
All variables are global to all of the program, including procedures. The syntax for declaring a variable follows:
Var <Variable Name> : <Variable Type> Examples: Var Dummy : Byte; Var Str : String; Var Dummy1, Dummy2 : Byte;
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 Cardinal Numerical 0..4294967295 Real Numerical 9.99
All variables except 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>
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:
Const MyHexValue = $1F; Value := $10; If Value = $10 Then WriteLn('Value is 16 <in decimal>');
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 end
Declaring the record:
Var struct : testrec
Using the record:
struct.x:=1 struct.y:=10 struct.d[1,1]:='abc123' WriteLn(struct.d[1,1]); WriteLn('struct.x='+Int2Str(struct.x))
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.
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
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
The syntax for a repeat until loop is as follows:
Repeat <Code here> Until <Boolean Expression>
Repeat WriteLn ('Blah blah') Until A > 0 or A = 5
The syntax for a while loop is as follows:
While <Boolean Expression> Do <Code Here>
While A > 0 and A = 5 Do WriteLn ('Blah')
While A > 0 and A = 5 Do Begin WriteLn ('Blah') WriteLn ('More Blah') End
The syntax for defining a procedure is as follows:
Procedure <Proc Name> (<varname vartype>, <varname vartype>) <Code here>
Procedure Hello_World WriteLn ('Hello World')
Procedure SomeProc (Str String, A Byte) WriteLn ('Str = ' + Str) WriteLn ('A = ' + A) End
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
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...')
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 3,4,5,6,7,8,9: WriteLn('Not 1, 2, or 10') End
Var S : String = 'ABCDEFG' Case S Of 'A': WriteLn('S = '+S) 'B','C','D': WriteLn('S = '+S) Else WriteLn('This is the default choice') End
The syntax for defining a function is as follows:
Function <Function Name> (<varname vartype>) : <result type>
Function AddTen (Num Byte) : Byte Begin AddTen := Num + 10 End
The syntax for a constant variable is as follows:
Const SomeStr = 'Hello World!'
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 recognized.