Pascal syntax
Overview
TatPascalScripter component executes scripts written in Pascal syntax. Current Pascal syntax supports:
begin .. end
constructorprocedure
andfunction
declarationsif .. then .. else
constructorfor .. to .. do .. step
constructorwhile .. do
constructorrepeat .. until
constructortry .. except
andtry .. finally
blockscase
statementsarray constructors (
x := [ 1, 2, 3 ];
)^
,*
,/
,and
,+
,-
,or
,<>
,>=
,<=
,=
,>
,<
,div
,mod
,xor
,shl
,shr
operatorsaccess to object properties and methods (
ObjectName.SubObject.Property
)
Script structure
Script structure is made of two major blocks: (a) procedure and function
declarations and (b) main block. Both are optional, but at least one
should be present in script. There is no need for main block to be
inside begin..end
. It could be a single statement. Some examples:
SCRIPT 1:
procedure DoSomething;
begin
CallSomething;
end;
begin
CallSomethingElse;
end;
SCRIPT 2:
begin
CallSomethingElse;
end;
SCRIPT 3:
function MyFunction;
begin
result := 'Ok!';
end;
SCRIPT 4:
CallSomethingElse;
Like in Pascal, statements should be terminated by ";" character.
begin..end
blocks are allowed to group statements.
Identifiers
Identifier names in script (variable names, function and procedure names, etc.) follow the most common rules in Pascal: should begin with a character (a..z or A..Z), or '_', and can be followed by alphanumeric chars or '_' char. Cannot contain any other character or spaces.
Valid identifiers:
VarName
_Some
V1A2
_____Some____
Invalid identifiers:
2Var
My Name
Some-more
This,is,not,valid
Assign statements
Just like in Pascal, assign statements (assign a value or expression result to a variable or object property) are built using ":=". Examples:
MyVar := 2;
Button.Caption := 'This ' + 'is ok.';
Character strings
Strings (sequence of characters) are declared in Pascal using single quote (') character. Double quotes (") are not used. You can also use #nn to declare a character inside a string. There is no need to use '+' operator to add a character to a string. Some examples:
A := 'This is a text';
Str := 'Text '+'concat';
B := 'String with CR and LF char at the end'#13#10;
C := 'String with '#33#34' characters in the middle';
Comments
Comments can be inserted inside script. You can use // chars or (* *) or { } blocks. Using // char the comment will finish at the end of line.
//This is a comment before ShowMessage
ShowMessage('Ok');
(* This is another comment *)
ShowMessage('More ok!');
{ And this is a comment
with two lines }
ShowMessage('End of okays');
Variables
There is no need to declare variable types in script, even though you
can put any type in it. Thus, you declare variable just using var
directive and its name. There is no need to declare variables if
scripter property OptionExplicit is set to false. In this case,
variables are implicit declared. If you want to have more control over
the script, set OptionExplicit property to true. This will raise a
compile error if variable is used but not declared in script. Examples:
SCRIPT 1:
procedure Msg;
var S;
begin
S := 'Hello world!';
ShowMessage(S);
end;
SCRIPT 2:
var A;
begin
A := 0;
A := A + 1;
end;
SCRIPT 3:
var S: string;
begin
S := 'Hello World!';
ShowMessage(S);
end;
Note that if script property OptionExplicit is set to false, then var
declarations are not necessary in any of scripts above.
Array type
Even though variable type is not required and in most cases it will be ignored, there are some special types that have meaning.
You can declare a variable as an array and the variable will be automatically initialized as a variant array of that type, instead of null. For example:
var Arr: array[0..10] of string;
begin
Arr[1] := 'first';
end;
Type of array items and the low index are optional. These are also valid declarations and result in same array type:
var
Arr1: array[0..10] of string;
Arr2: array[10] of string;
Arr3: array[0..10];
Arr4: array[10];
Script arrays are always 0-based and indicating a different number for low bound will cause a compilation error:
var
Arr: array[1..10] of string; // Invalid declaration
Indexes
Strings, arrays and array properties can be indexed using "[" and "]" chars. For example, if Str is a string variable, the expression Str[3] returns the third character in the string denoted by Str, while Str[I + 1] returns the character immediately after the one indexed by I. More examples:
MyChar := MyStr[2];
MyStr[1] := 'A';
MyArray[1,2] := 1530;
Lines.Strings[2] := 'Some text';
Arrays
Script support array constructors and support to variant arrays. To construct an array, use "[" and "]" chars. You can construct multi-index array nesting array constructors. You can then access arrays using indexes. If array is multi-index, separate indexes using ",".
If variable is a variant array, script automatically support indexing in that variable. A variable is a variant array is it was assigned using an array constructor, if it is a direct reference to a Delphi variable which is a variant array (see Delphi integration later) or if it was created using VarArrayCreate procedure.
Arrays in script are 0-based index. Some examples:
NewArray := [2, 4, 6, 8];
Num := NewArray[1]; // Num receives "4"
MultiArray := [ ['green','red','blue'] , ['apple','orange','lemon'] ];
Str := MultiArray[0,2]; // Str receives 'blue'
MultiArray[1,1] := 'new orange';
If statements
There are two forms of if statement: if...then
and the if...then...else
.
Like normal Pascal, if the if expression is true,
the statement (or block) is executed. If there is else part and
expression is false, statement (or block) after else is execute.
Examples:
if J <> 0 then Result := I/J;
if J = 0 then Exit else Result := I/J;
if J <> 0 then
begin
Result := I/J;
Count := Count + 1;
end
else
Done := True;
while statements
A while statement is used to repeat a statement or a block, while a control condition (expression) is evaluated as true. The control condition is evaluated before the statement. Hence, if the control condition is false at first iteration, the statement sequence is never executed. The while statement executes its constituent statement (or block) repeatedly, testing expression before each iteration. As long as expression returns True, execution continues. Examples:
while Data[I] <> X do I := I + 1;
while I > 0 do
begin
if Odd(I) then Z := Z * X;
I := I div 2;
X := Sqr(X);
end;
while not Eof(InputFile) do
begin
Readln(InputFile, Line);
Process(Line);
end;
repeat statements
The syntax of a repeat statement is
repeat statement1; ...; statementn; until expression
where expression returns a Boolean value. The repeat statement executes its
sequence of constituent statements continually, testing expression after
each iteration. When expression returns True, the repeat statement
terminates. The sequence is always executed at least once because
expression is not evaluated until after the first iteration. Examples:
repeat
K := I mod J;
I := J;
J := K;
until J = 0;
repeat
Write('Enter a value (0..9): ');
Readln(I);
until (I >= 0) and (I <= 9);
for statements
Scripter support for statements with the following syntax:for counter := initialValue to finalValue do statement
.
The for statement set counter to initialValue, repeats execution of statement (or block) and increment value of counter until counter reachs finalValue. Examples:
SCRIPT 1:
for c := 1 to 10 do
a := a + c;
SCRIPT 2:
for i := a to b do
begin
j := i^2;
sum := sum+j;
end;
case statements
Scripter support case statements with following syntax:
case selectorExpression of
caseexpr1: statement1;
...
caseexprn: statementn;
else
elsestatement;
end
If selectorExpression matches the result of one of caseexprn expressions, the respective statement (or block) will be execute. Otherwise, elsestatement will be execute. Else part of case statement is optional. Different from Delphi, case statement in script doesn't need to use only ordinal values. You can use expressions of any type in both selector expression and case expression. Example:
case UpperCase(Fruit) of
'lime': ShowMessage('green');
'orange': ShowMessage('orange');
'apple': ShowMessage('red');
else
ShowMessage('black');
end;
function and procedure declaration
Declaration of functions and procedures are similar to Object Pascal in Delphi, with the difference you don't specify variable types. Just like OP, to return function values, use implicited declared result variable. Parameters by reference can also be used, with the restriction mentioned: no need to specify variable types. Some examples:
procedure HelloWord;
begin
ShowMessage('Hello world!');
end;
procedure UpcaseMessage(Msg);
begin
ShowMessage(UpperCase(Msg));
end;
function TodayAsString;
begin
result := DateToStr(Date);
end;
function Max(A,B);
begin
if A > B then
result := A
else
result := B;
end;
procedure SwapValues(var A, B);
var Temp;
begin
Temp := A;
A := B;
B := Temp;
end;