FastScript 1.
7
Scripting library
Developer's manual
Copyright (c) 1998-2004 by Fast Reports Inc.
Author: Alexander Tzyganenko
e-mail: tz@[Link]
home page: [Link]
[Link]
Introduction
What is FastScript
Quick start
Features and missing features
Language reference
Script structure
Data types
Classes
Functions
Events
Enumerations and sets
Arrays
What is FastScript
FastScript is a scripting library. It is useful for the programmers who want to add
scripting ability to their projects. FastScript is written on 100% Object Pascal and can be
installed in Borland Delphi 4-7, C++Builder 4-6 and Kylix 1-3.
Unique feature of FastScript is ability to use several languages (PascalScript, C++Script,
JScript and BasicScript), so you can write scripts using your favourite language.
FastScript doesn't use Microsoft Scripting Host, so it can be used in Windows and Linux
environment. It is possible to add a new language - language definition is stored in the
XML format, so you can perform it without writing a Delphi code.
FastScript combines cross-platform scripting, fast code execution, small footprint, rich
set of features and a splendid scalability. Make your applications the most flexible and
powerful ones with FastScript!
Quick start
Here is a sample code which demonstrates the easiest way of using FastScript. For the
correct work of the example put the components fsScript1: TfsScript and fsPascal1:
TfsPascal on the form .
uses FS_iInterpreter;
procedure TForm1.Button1Click(Sender: TObject);
begin
[Link]; // do this if you running many scripts from one
component
[Link] := 'begin ShowMessage(''Hello!'') end.';
[Link] := fsGlobalUnit; // use standard classes and methods
[Link] := 'PascalScript';
if [Link] then
[Link] else
ShowMessage([Link]);
end;
As you can see, there is nothing difficult here. At first we fill in the [Link]
property with the script text. For using standard types and functions we set Parent
property to the fsGlobalUnit. Then we compile the script using PascalScript language
(you can use C++Script, BasicScript, JScript as well). If compilation is successful
Compile method returns True and we can Execute the script. Otherwise the error message
is shown.
Features and missing features
Features
- Multi-language architecture allows you to use a number of languages (at present
moment PascalScript, C++Script, BasicScript, JScript). You can add any procedural
language (language grammar is stored in XML format).
- Standard language set: variables, constants, procedures, functions (nested functions
allowed) with var/const/default parameters, all the standard operators and statements
(including case, try/finally/except, with), types (int, float, bool, char, string, multi-
dimensional array, enum, variant), classes (with methods, events, properties, indices and
default properties).
- Types compatibility checking.
- Access to any object inside your application. Standard libraries for the access to the
base classes, controls, forms and BD. Easily expandable library architecture.
- Small footprint - 90-150Kb depending on used modules.
Missing features
- No type declarations (records, classes) in the script; no records, no pointers, no sets (but
you can use 'IN' operator - "a in ['a'..'c','d']"), no shortstrings, no GOTO statement.
- C++Script: no octal constants; no 'break' in the SWITCH operator (SWITCH works like
Pascal CASE); '++' and '--' operators are possible only after the variables, that is '++i' is
not allowed; '--', '++' and '=' operators do not return a value, that is 'if(i++)' is not allowed;
all the identifiers are case-insensitive; NULL constant is the Pascal Null - use nil instead
of NULL.
- JScript and BasicScript: see syntax diagrams.
Language reference
PascalScript syntax:
Program -> [PROGRAM Ident ';']
[UsesClause]
Block '.'
UsesClause -> USES (String/,)... ';'
Block -> [DeclSection]...
CompoundStmt
DeclSection -> ConstSection
-> VarSection
-> ProcedureDeclSection
ConstSection -> CONST (ConstantDecl)...
ConstantDecl -> Ident '=' Expression ';'
VarSection -> VAR (VarList ';')...
VarList -> Ident/','... ':' TypeIdent [InitValue]
TypeIdent -> Ident
-> Array
Array -> ARRAY '[' ArrayDim/','... ']' OF Ident
ArrayDim -> Expression..Expression
-> Expression
InitValue -> '=' Expression
Expression -> SimpleExpression [RelOp SimpleExpression]...
SimpleExpression -> ['-'] Term [AddOp Term]...
Term -> Factor [MulOp Factor]...
Factor -> Designator
-> UnsignedNumber
-> String
-> '(' Expression ')'
-> NOT Factor
-> '[' SetConstructor ']'
SetConstructor -> SetNode/','...
SetNode -> Expression ['..' Expression]
RelOp -> '>'
-> '<'
-> '<='
-> '>='
-> '<>'
-> '='
-> IN
-> IS
AddOp -> '+'
-> '-'
-> OR
-> XOR
MulOp -> '*'
-> '/'
-> DIV
-> MOD
-> AND
-> SHL
-> SHR
Designator -> ['@'] Ident ['.' Ident | '[' ExprList ']' | '(' ExprList
')']...
ExprList -> Expression/','...
Statement -> [SimpleStatement | StructStmt]
StmtList -> Statement/';'...
SimpleStatement -> Designator
-> Designator ':=' Expression
-> BREAK | CONTINUE | EXIT
StructStmt -> CompoundStmt
-> ConditionalStmt
-> LoopStmt
-> TryStmt
-> WithStmt
CompoundStmt -> BEGIN StmtList END
ConditionalStmt -> IfStmt
-> CaseStmt
IfStmt -> IF Expression THEN Statement [ELSE Statement]
CaseStmt -> CASE Expression OF CaseSelector/';'... [ELSE Statement]
[';'] END
CaseSelector -> SetConstructor ':' Statement
LoopStmt -> RepeatStmt
-> WhileStmt
-> ForStmt
RepeatStmt -> REPEAT StmtList UNTIL Expression
WhileStmt -> WHILE Expression DO Statement
ForStmt -> FOR Ident ':=' Expression ToDownto Expression DO Statement
ToDownto -> (TO | DOWNTO)
TryStmt -> TRY StmtList (FINALLY | EXCEPT) StmtList END
WithStmt -> WITH (Designator/,..) DO Statement
ProcedureDeclSection -> ProcedureDecl
-> FunctionDecl
ProcedureDecl -> ProcedureHeading ';'
Block ';'
ProcedureHeading -> PROCEDURE Ident [FormalParameters]
FunctionDecl -> FunctionHeading ';'
Block ';'
FunctionHeading -> FUNCTION Ident [FormalParameters] ':' Ident
FormalParameters -> '(' FormalParam/';'... ')'
FormalParm -> [VAR | CONST] VarList
C++Script syntax:
Program -> [UsesClause]
[DeclSection]...
CompoundStmt
UsesClause -> '#' INCLUDE (String/,)...
DeclSection -> ConstSection
-> ProcedureDeclSection
-> VarStmt ';'
ConstSection -> '#' DEFINE ConstantDecl
ConstantDecl -> Ident Expression
VarStmt -> Ident Ident [Array] [InitValue] /','...
ArrayDef -> '[' ArrayDim/','... ']'
ArrayDim -> Expression
InitValue -> '=' Expression
Expression -> SimpleExpression [RelOp SimpleExpression]...
SimpleExpression -> ['-'] Term [AddOp Term]...
Term -> Factor [MulOp Factor]...
Factor -> Designator
-> UnsignedNumber
-> String
-> '(' Expression ')'
-> '!' Factor
-> '[' SetConstructor ']'
-> NewOperator
SetConstructor -> SetNode/','...
SetNode -> Expression ['..' Expression]
NewOperator -> NEW Designator
RelOp -> '>'
-> '<'
-> '<='
-> '>='
-> '!='
-> '=='
-> IN
-> IS
AddOp -> '+'
-> '-'
-> '||'
-> '^'
MulOp -> '*'
-> '/'
-> '%'
-> '&&'
-> '<<'
-> '>>'
Designator -> ['&'] Ident ['.' Ident | '[' ExprList ']' | '(' ExprList
')']...
ExprList -> Expression/','...
Statement -> [SimpleStatement ';' | StructStmt | EmptyStmt]
EmptyStmt -> ';'
StmtList -> (Statement...)
SimpleStatement -> DeleteStmt
-> AssignStmt
-> VarStmt
-> CallStmt
-> ReturnStmt
-> (BREAK | CONTINUE | EXIT)
DeleteStmt -> DELETE Designator
AssignStmt -> Designator ['+'|'-'|'*'|'/']'=' Expression
CallStmt -> Designator ['+''+'|'-''-']
ReturnStmt -> RETURN [Expression]
StructStmt -> CompoundStmt
-> ConditionalStmt
-> LoopStmt
-> TryStmt
CompoundStmt -> '{' [StmtList] '}'
ConditionalStmt -> IfStmt
-> CaseStmt
IfStmt -> IF '(' Expression ')' Statement [ELSE Statement]
CaseStmt -> SWITCH '(' Expression ')' '{' (CaseSelector)... [DEFAULT
':' Statement] '}'
CaseSelector -> CASE SetConstructor ':' Statement
LoopStmt -> RepeatStmt
-> WhileStmt
-> ForStmt
RepeatStmt -> DO Statement [';'] WHILE '(' Expression ')' ';'
WhileStmt -> WHILE '(' Expression ')' Statement
ForStmt -> FOR '(' ForStmtItem ';' Expression ';' ForStmtItem ')'
Statement
ForStmtItem -> AssignStmt
-> VarStmt
-> CallStmt
-> Empty
TryStmt -> TRY CompoundStmt (FINALLY | EXCEPT) CompoundStmt
FunctionDecl -> FunctionHeading CompoundStmt
FunctionHeading -> Ident Ident [FormalParameters]
FormalParameters -> '(' [FormalParam/';'...] ')'
FormalParam -> TypeIdent (['&'] Ident [InitValue]/',')...
JScript syntax:
Program -> Statements
Statements -> Statement...
Block -> '{' Statements '}'
ImportStmt -> IMPORT (String/,)...
VarStmt -> VAR (VarDecl/',')...
VarDecl -> Ident [Array] [InitValue]
Array -> '[' (ArrayDim/',')... ']'
ArrayDim -> Expression
InitValue -> '=' Expression
Expression -> SimpleExpression [RelOp SimpleExpression]...
SimpleExpression -> ['-'] Term [AddOp Term]...
Term -> Factor [MulOp Factor]...
Factor -> Designator
-> UnsignedNumber
-> String
-> '(' Expression ')'
-> '!' Factor
-> '[' SetConstructor ']'
-> NewOperator
-> '<' FRString '>'
SetConstructor -> SetNode/','...
SetNode -> Expression ['..' Expression]
NewOperator -> NEW Designator
RelOp -> '>'
-> '<'
-> '<='
-> '>='
-> '!='
-> '=='
-> IN
-> IS
AddOp -> '+'
-> '-'
-> '||'
-> '^'
MulOp -> '*'
-> '/'
-> '%'
-> '&&'
-> '<<'
-> '>>'
Designator -> ['&'] Ident ['.' Ident | '[' ExprList ']' |
'(' [ExprList] ')']...
ExprList -> Expression/','...
Statement -> (AssignStmt | CallStmt | BreakStmt | ContinueStmt |
DeleteStmt | DoWhileStmt | ForStmt | FunctionStmt |
IfStmt | ImportStmt | ReturnStmt | SwitchStmt |
VarStmt | WhileStmt | WithStmt | Block) [';']
BreakStmt -> BREAK
ContinueStmt -> CONTINUE
DeleteStmt -> DELETE Designator
AssignStmt -> Designator ['+'|'-'|'*'|'/']'=' Expression
CallStmt -> Designator ['+''+'|'-''-']
ReturnStmt -> RETURN [Expression]
IfStmt -> IF '(' Expression ')' Statement [ELSE Statement]
SwitchStmt -> SWITCH '(' Expression ')' '{' (CaseSelector)... [DEFAULT
':' Statement] '}'
CaseSelector -> CASE SetConstructor ':' Statement
DoWhileStmt -> DO Statement [';'] WHILE '(' Expression ')' ';'
WhileStmt -> WHILE '(' Expression ')' Statement
ForStmt -> FOR '(' ForStmtItem ';' Expression ';' ForStmtItem ')'
Statement
ForStmtItem -> AssignStmt
-> CallStmt
-> VarStmt
-> Empty
TryStmt -> TRY CompoundStmt (FINALLY | EXCEPT) CompoundStmt
FunctionStmt -> FunctionHeading Block
FunctionHeading -> FUNCTION Ident FormalParameters
FormalParameters -> '(' [FormalParam/','...] ')'
FormalParam -> ['&'] Ident
WithStmt -> WITH '(' Designator ')' Statement
BasicScript syntax:
Program -> Statements
Statements -> (EOL | StatementList EOL)...
StatementList -> Statement/':'...
ImportStmt -> IMPORTS (String/,)...
DimStmt -> DIM (VarDecl/',')...
VarDecl -> Ident [Array] [AsClause] [InitValue]
AsClause -> AS Ident
Array -> '[' ArrayDim/','... ']'
ArrayDim -> Expression
InitValue -> '=' Expression
Expression -> SimpleExpression [RelOp SimpleExpression]...
SimpleExpression -> ['-'] Term [AddOp Term]...
Term -> Factor [MulOp Factor]...
Factor -> Designator
-> UnsignedNumber
-> String
-> '(' Expression ')'
-> NOT Factor
-> NewOperator
-> '<' FRString '>'
SetConstructor -> SetNode/','...
SetNode -> Expression ['..' Expression]
NewOperator -> NEW Designator
RelOp -> '>'
-> '<'
-> '<='
-> '>='
-> '<>'
-> '='
-> IN
-> IS
AddOp -> '+'
-> '-'
-> '&'
-> OR
-> XOR
MulOp -> '*'
-> '/'
-> '\'
-> MOD
-> AND
Designator -> [ADDRESSOF] Ident ['.' Ident | '[' ExprList ']' |
'(' [ExprList] ')']...
ExprList -> Expression/','...
Statement -> BreakStmt
-> CaseStmt
-> ContinueStmt
-> DeleteStmt
-> DimStmt
-> DoStmt
-> ExitStmt
-> ForStmt
-> FuncStmt
-> IfStmt
-> ImportStmt
-> ProcStmt
-> ReturnStmt
-> SetStmt
-> TryStmt
-> WhileStmt
-> WithStmt
-> AssignStmt
-> CallStmt
BreakStmt -> BREAK
ContinueStmt -> CONTINUE
ExitStmt -> EXIT
DeleteStmt -> DELETE Designator
SetStmt -> SET AssignStmt
AssignStmt -> Designator ['+'|'-'|'*'|'/']'=' Expression
CallStmt -> Designator ['+''+'|'-''-']
ReturnStmt -> RETURN [Expression]
IfStmt -> IF Expression THEN ThenStmt
ThenStmt -> EOL [Statements] [ElseIfStmt | ElseStmt] END IF
-> StatementList
ElseIfStmt -> ELSEIF Expression THEN
(EOL [Statements] [ElseIfStmt | ElseStmt] | Statement)
ElseStmt -> ELSE (EOL [Statements] | Statement)
CaseStmt -> SELECT CASE Expression EOL
(CaseSelector...) [CASE ELSE ':' Statements] END SELECT
CaseSelector -> CASE SetConstructor ':' Statements
DoStmt -> DO [Statements] LOOP (UNTIL | WHILE) Expression
WhileStmt -> WHILE Expression [Statements] WEND
ForStmt -> FOR Ident '=' Expression TO Expression [STEP Expression] EOL
[Statements] NEXT
TryStmt -> TRY Statements (FINALLY | CATCH) [Statements] END TRY
WithStmt -> WITH Designator EOL Statements END WITH
ProcStmt -> SUB Ident [FormalParameters] EOL [Statements] END SUB
FuncStmt -> FUNCTION Ident [FormalParameters] [AsClause] EOL
[Statements] END FUNCTION
FormalParameters -> '(' (FormalParam/',')... ')'
FormalParm -> [BYREF | BYVAL] VarList
Script structure
The PascalScript structure is the same as in Object Pascal language:
#language PascalScript // this is optional
program MyProgram; // this is optional
uses '[Link]', '[Link]';
// uses section - must be before any other sections
// v1.2 changes: warning! the included units are not inserted into the
main unit text. So it can have
// 'program', 'uses' sections and must have the 'main procedure'
section.
var // var section
i, j: Integer;
const // const section
pi = 3.14159;
procedure p1; // procedures and function
var
i: Integer;
procedure p2; // nested procedure
begin
end;
begin
end;
begin // main procedure that will be executed.
end.
The C++Script structure is:
#language C++Script // this is optional
#include "[Link]", "[Link]"
// uses section - must be before any other sections
int i, j; // var section
#DEFINE pi = 3.14159 // const section
void p1() // procedures and function
{ // there is no nested procedures in C++Script
}
{ // main procedure that will be executed.
}
The JScript structure is:
#language JScript // this is optional
import "[Link]", "[Link]"
// import section - must be before any other sections
var i, j = 0; // var section
function p1() // procedures and function
{ //
}
// main procedure that will be executed.
p1();
for (i = 0; i < 10; i++) j++;
The BasicScript structure is:
#language BasicScript // this is optional
imports "[Link]", "[Link]"
// imports section - must be before any other sections
dim i, j = 0 // var section
function f1() // procedures and function
end function //
sub p1()
end sub
// main procedure that will be executed.
for i = 0 to 10
p1()
next
Data types
Internally FastScript operates with the Variant type and is based on it. Nevertheless, you
can use the following predetermined types in your scripts:
Byte | Same as Integer type
Word |
Integer |
Longint |
Cardinal |
TColor |
Boolean | Boolean type
Real | Same as Extended type
Single |
Double |
Extended |
TDate |
TTime |
TDateTime |
Char | Char type
String | String type
Variant | Same as Variant type
Pointer |
Array | Array type
C++Script maps some types to standard types:
int, long = Integer
void = Integer
bool = Boolean
float = Extended
JScript has no types, all types are variants. BasicScript may have types (for example,
dim i as Integer), or may have no types and even no variable declaration. In this case a
variable will have Variant type.
Not all of these types can be assign-compatible. Like in Object Pascal, you can't assign
Extended or String to an Integer. Only one type - the Variant - can be assigned to all the
types and can get value from any type.
Except the built-in types you can use the enumerated types defined in your application
or in add-in modules (for example after adding the TfsGraphicsRTTI component you can
use TPenMode, TFontStyles and other types).
Classes
You cannot define a class inside the script, but you can use the external classes defined
in add-in modules or your application. This is an example from the DEMOS\Main demo:
var
f: TForm;
b: TButton;
procedure ButtonClick(Sender: TButton);
begin
ShowMessage([Link]);
[Link] := mrOk;
end;
// there is no need to use all the parameters in event handlers
// because no type checking is performed
procedure ButtonMouseMove(Sender: TButton);
begin
[Link] := 'moved over';
end;
begin
f := [Link](nil);
[Link] := 'Test it!';
[Link] := bsDialog;
[Link] := poScreenCenter;
b := [Link](f);
[Link] := 'Button1';
[Link] := f;
[Link](10, 10, 75, 25);
[Link] := 'Test';
[Link] := @ButtonClick; { same as [Link] := 'ButtonClick' }
[Link] := @ButtonMouseMove;
[Link];
[Link];
end.
As you can see there is no difference between PascalScript and Delphi code. You can
access any property (simple, indexed or default) or method. All the object's published
properties are accessible from the script by default. Public properties and methods need
the implementation code - that's why you can access it partially (for example, you cannot
access the [Link] method or [Link] property because they are not
implemented).
You can add your own classes - see "Scripting" chapter for details.
Functions
There is a rich set of standard functions which can be used in a script. To get an access
to these functions, pass the fsGlobalUnit reference to the [Link] property.
function IntToStr(i: Integer): String
function FloatToStr(e: Extended): String
function DateToStr(e: Extended): String
function TimeToStr(e: Extended): String
function DateTimeToStr(e: Extended): String
function VarToStr(v: Variant): String
function StrToInt(s: String): Integer
function StrToFloat(s: String): Extended
function StrToDate(s: String): Extended
function StrToTime(s: String): Extended
function StrToDateTime(s: String): Extended
function Format(Fmt: String; Args: array): String
function FormatFloat(Fmt: String; Value: Extended): String
function FormatDateTime(Fmt: String; DateTime: TDateTime): String
function FormatMaskText(EditMask: string; Value: string): string
function EncodeDate(Year, Month, Day: Word): TDateTime
procedure DecodeDate(Date: TDateTime; var Year, Month, Day: Word)
function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime
procedure DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word)
function Date: TDateTime
function Time: TDateTime
function Now: TDateTime
function DayOfWeek(aDate: DateTime): Integer
function IsLeapYear(Year: Word): Boolean
function DaysInMonth(nYear, nMonth: Integer): Integer
function Length(s: String): Integer
function Copy(s: String; from, count: Integer): String
function Pos(substr, s: String): Integer
procedure Delete(var s: String; from, count: Integer): String
procedure Insert(s: String; var s2: String; pos: Integer): String
function Uppercase(s: String): String
function Lowercase(s: String): String
function Trim(s: String): String
function NameCase(s: String): String
function CompareText(s, s1: String): Integer
function Chr(i: Integer): Char
function Ord(ch: Char): Integer
procedure SetLength(var S: String; L: Integer)
function Round(e: Extended): Integer
function Trunc(e: Extended): Integer
function Int(e: Extended): Integer
function Frac(X: Extended): Extended
function Sqrt(e: Extended): Extended
function Abs(e: Extended): Extended
function Sin(e: Extended): Extended
function Cos(e: Extended): Extended
function ArcTan(X: Extended): Extended
function Tan(X: Extended): Extended
function Exp(X: Extended): Extended
function Ln(X: Extended): Extended
function Pi: Extended
procedure Inc(var i: Integer; incr: Integer = 1)
procedure Dec(var i: Integer; decr: Integer = 1)
procedure RaiseException(Param: String)
procedure ShowMessage(Msg: Variant)
procedure Randomize
function Random: Extended
function ValidInt(cInt: String): Boolean
function ValidFloat(cFlt: String): Boolean
function ValidDate(cDate: String): Boolean
function CreateOleObject(ClassName: String): Variant
function VarArrayCreate(Bounds: Array; Typ: Integer): Variant
As you can see, some functions/procedure have default parameters. You can call it just
like in Delphi:
Inc(a);
Inc(b, 2);
You can connect own function/procedure to a script - see "Scripting" chapter for details.
Events
You can use event handlers in the script. Unlike the Delphi event handler, script event
handlers are not the methods of the object. The following example shows how to
connect an event handler to the [Link] event:
var
b: TButton;
Form1: TForm;
procedure ButtonClick(Sender: TButton);
begin
ShowMessage([Link]);
end;
begin
b := [Link](Form1);
[Link] := Form1;
[Link] := @ButtonClick; // same as [Link] := 'ButtonClick'
[Link] := nil; // clear the event
end.
There are some predefined events available in FS_iEvents unit:
TfsNotifyEvent
TfsMouseEvent
TfsMouseMoveEvent
TfsKeyEvent
TfsKeyPressEvent
TfsCloseEvent
TfsCloseQueryEvent
TfsCanResizeEvent
See the "TfsFormsRTTTI component", "TfsExtCtrlsRTTI component" and
"TfsDBCtrlsRTTI component" chapters for a list of the available events.
Enumerations and Sets
FastScript supports enumerations. You can write in a script:
[Link] := bsDialog;
Sets are not supported. However, you can use set constants in the following way:
[Link] := fsBold; // [Link] := [fsBold] in Delphi
[Link] := fsBold + fsItalic; // [Link] := [fsBold, fsItalic]
[Link] := 0; // [Link] := []
Arrays
FastScript supports all kind of arrays: static (one- and multi-dimesional), dynamic,
variant arrays. There is an example of script that uses all array types:
var
ar1: array[0..2] of Integer;
ar2: array of Integer;
ar3: Variant;
SetLength(ar2, 3);
ar3 := VarArrayCreate([0, 2], varInteger);
ar1[0] := 1;
ar2[0] := 1;
ar3[0] := 1;
FastScript component
palette
Delphi component palette
TfsScript component
TfsClassesRTTI component
TfsGraphicsRTTI component
TfsFormsRTTI component
TfsExtCtrlsRTTI component
TfsDialogsRTTI component
TfsDBRTTI component
TfsDBCtrlsRTTI component
TfsBDERTTI component
TfsADORTTI component
TfsIBXRTTI component
TfsChartRTTI component
Delphi component palette
After the FastScript installing the "FastScript" tab will be created in the Delphi /
C++Builder. This tab contains the main FastScript components such as TfsScript,
TfsClassesRTTI, etc.
TfsScript component - the main scripting component
This is a main scripting component.
Properties:
SyntaxType: String;
The type of the script language. By default four types of scripts are supported:
"PascalScript", "C++Script", "BasicScript", "JScript". Warning! The property has the
string type and it is easy to make a mistake in the syntax type indication. The value by
default is “PascalScript”.
Lines: TStrings;
A script text. Contains strings of the script.
Methods:
function Compile: Boolean;
Compiles the source code. Source code must be placed in the [Link] property
before you call the Compile method.
procedure Execute;
Execute script after compiling.
function Run: boolean;
Compile and execute script. Returns true if compile was successful. This method is the
analogue to the Compile + Execute.
Examples of use:
Example1.
Delphi/Kylix IDE. Loads script file [Link] and execute it.
[Link](‘[Link]’);
if [Link] then
[Link]
else
ShowMessage(‘Script compilation error!’);
Example2.
Delphi/Kylix IDE. Pressing the Button1 gives the strings from fsSyntaxMemo1
component to [Link] and execute script.
procedure TForm1.Button1Click(Sender: TObject);
begin
[Link] := [Link];
if not [Link] then
ShowMessage(‘Script compilation error!’);
end;
Example3.
Delphi/Kylix IDE. Loads “C++Script” from [Link] file and execute it.
[Link](‘[Link]’);
[Link] := ‘C++Script’;
if [Link] then
[Link]
else
ShowMessage(‘Script compilation error!’);
Example4.
С++Builder IDE. Loads “C++Script” from [Link] file and execute it.
fsScript1->Lines->LoadFromFile(‘[Link]’);
fsScript1->SyntaxType = “C++Script”;
if (fsScript1->Compile())
fsScript1->Execute();
else
ShowMessage(“Script compilation error!”);
TfsSyntaxMemo - script editor with syntax highlighting
A special advanced TMemo is adapted for FastScript with support of C++ and Pascal
syntax highlighting.
Available in FastScript for VCL only.
Properties:
SyntaxType: TSyntaxType;
Type of syntax highlighting.
Possible values:
stPascal - for Pascal,
stCpp - for C++,
stSQL - for SQL,
stText - a simple text (without highlighting).
Default value stPascal.
Lines: TStrings;
The edit text.
ShowFooter: Boolean;
Shows the footer with a cursor position, etc.
ShowGutter: Boolean;
Shows the info in the left part of a text with bookmarks, current step position, etc.
BlockColor: TColor;
Background color of the selected text.
BlockFontColor: TColor;
Color of the selected text.
CommentAttr: TFont;
Attributes of the comment font.
KeywordAttr: TFont;
Attributes of keyword font.
StringAttr: TFont;
Attributes of the string values font.
TextAttr: TFont;
Attributes of a simple text font.
Modified: Boolean;
True if the text was modified.
SelText: String;
Contains a selected text.
Methods:
procedure CopyToClipboard;
Copies a selected text to the clipboard.
procedure CutToClipboard;
Moves a selected text to the clipboard.
procedure PasteFromClipboard;
Inserts a text from the clipboard to the cursor position.
procedure SetPos(x, y: Integer);
Sets the cursor position in the text. Line and positions numbering begins from 0. See the
GetPos method.
function GetPos: TPoint;
Returns the current cursor position. See SetPos.
procedure ShowMessage(s: String);
Shows a message in the footer.
procedure Undo;
Cancels the last change.
function Find(Text: String): boolean;
Searches a text from a current cursor position.
function IsBookmark(Line : integer): integer;
Return the bookmark number for the line with the Line number. Returns -1 if the
bookmark is not set. See AddBookmark method.
procedure AddBookmark(Line, Number : integer);
Adds the bookmark number for the line Line with the number Number. Supports 10
bookmarks with numbers from 0 to 9. See DeleteBookmark, GotoBookmark methods.
procedure DeleteBookmark(Number : integer);
Deletes the bookmark with the number Number. See AddBookmark method.
procedure GotoBookmark(Number : integer);
Sets the cursor position to the line with the bookmark with the number Number. See
AddBookmark method.
procedure SetActiveLine(Line : Integer);
Sets the active line highlighting (for use with the debugger). Line is the active line
number. The highlighting is disabled if Line is set to -1. See the GetActiveLine method.
function GetActiveLine: Integer;
Returns the active line number. If there is no active lines it returns -1. See SetActiveLine
method.
Hot keys.
Key Action
Cursor arrow Cursor moving
PgUp, PgDn, Page Up / Page Down
Ctrl+PgUp Move to the begin of text
Ctrl+PgDn Move to the end of text
Home Move to the begin of line
End Move to the end of line
Enter Move to the next line
Delete Delete symbol at right or selected text
Backspace Delete symbol at left
Ctrl+Y Delete current line
Ctrl+Z Undo last change
Shift+Стрелки курсора Select the text block
Ctrl+A Select all text
Ctrl+U Unindent selected block
Ctrl+I Indent selected block
Ctrl+C, Ctrl+Insert Copy to clipboard
Ctrl+V, Shift+Insert Paste from clipboard
Ctrl+X, Shift+Delete Cut to clipboard
Ctrl+Shift+<цифра> Set bookmark
Ctrl+<цифра> Goto bookmark
Ctrl+F Search text
F3 Continue search
TfsTree - classes and functions tree-view
Shows available classes and functions in a tree.
Properties:
property Script: TfsScript;
TfsScript reference.
property SyntaxMemo: TfsSyntaxMemo; for VCL
property SyntaxMemo: TMemo; for CLX
Memo reference.
property ShowClasses: Boolean;
The function tree is shown.
property ShowFunctions: Boolean;
All the tree nodes are shown .
property Expanded: Boolean;
Expand all tree nodes.
property ExpandLevel: integer;
The level of the unfolded tree nodes. 2 by default.
TfsClassesRTTI component
Use this component if you want to get access to [Link] stuff in your application.
This component allows you to access the following classes inside a script:
TObject
constructor [Link]
procedure [Link]
TPersistent
procedure [Link](Source: TPersistent)
TList
function [Link](Item: TObject): Integer
procedure [Link]
procedure [Link](Index: Integer)
function [Link](Item: TObject): Integer
procedure [Link](Index: Integer; Item: TObject)
function [Link](Item: TObject): Integer
property [Link]
property [Link]
TStrings
function [Link](const S: string): Integer
function [Link](const S: string; AObject: TObject): Integer
procedure [Link]
procedure [Link](Index: Integer)
function [Link](const S: string): Integer
function [Link](const Name: string): Integer
function [Link](AObject: TObject): Integer
procedure [Link](Index: Integer; const S: string)
procedure [Link](Index: Integer; const S: string;
AObject: TObject)
procedure [Link](const FileName: string)
procedure [Link](Stream: TStream)
procedure [Link](const FileName: string)
procedure [Link](Stream: TStream)
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
TStringList
function [Link](s: String; var Index: Integer): Boolean
procedure [Link]
property [Link]
property [Link]
TStream
function [Link](Buffer: string; Count: Longint): Longint
function [Link](Buffer: string; Count: Longint): Longint
function [Link](Offset: Longint; Origin: Word): Longint
function [Link](Source: TStream; Count: Longint): Longint
property [Link]
property [Link]
TFileStream
constructor [Link](Filename: String; Mode: Word)
TMemoryStream
procedure [Link]
procedure [Link](Stream: TStream)
procedure [Link](Filename: String)
procedure [Link](Stream: TStream)
procedure [Link](Filename: String)
TComponent
constructor [Link](AOwner: TComponent)
property [Link]
TfsXMLItem
constructor [Link]
procedure [Link](Item: TfsXMLItem)
procedure [Link]
procedure [Link](Index: Integer; Item: TfsXMLItem)
function [Link]: TfsXMLItem
function [Link](const Name: String): Integer
function [Link](const Name: String): TfsXMLItem
function [Link](const Name: String): String
function [Link]: TfsXMLItem
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
TfsXMLDocument
constructor [Link]
procedure [Link](Stream: TStream)
procedure [Link](Stream: TStream)
procedure [Link](const FileName: String)
procedure [Link](const FileName: String)
property [Link]
const fmCreate
const fmOpenRead
const fmOpenWrite
const fmOpenReadWrite
const fmShareExclusive
const fmShareDenyWrite
const fmShareDenyNone
const soFromBeginning
const soFromCurrent
const soFromEnd
type TDuplicates
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iClassesRTTI" unit to the "uses" clause.
TfsGraphicsRTTI component
Use this component if you want to get an access to [Link] stuff in your
application. This component allows you to access the following classes inside a script:
TFont
TPen
TBrush
TCanvas
procedure [Link](X, Y: Integer; Graphic: TGraphic)
procedure [Link](X1, Y1, X2, Y2: Integer)
procedure [Link](X, Y: Integer)
procedure [Link](X, Y: Integer)
procedure [Link](X1, Y1, X2, Y2: Integer)
procedure [Link](X1, Y1, X2, Y2, X3, Y3: Integer)
procedure [Link](X1, Y1, X2, Y2: Integer; Graphic:
TGraphic)
function [Link](const Text: string): Integer
procedure [Link](X, Y: Integer; const Text: string)
function [Link](const Text: string): Integer
property [Link]
TGraphic
procedure [Link](const Filename: string)
procedure [Link](const Filename: string)
property [Link]
property [Link]
TMetafile
TMetafileCanvas
TBitmap
property [Link]
type TFontStyles
type TFontPitch
type TPenStyle
type TPenMode
type TBrushStyle
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iGraphicsRTTI" unit to the "uses" clause.
TfsFormsRTTI component
Use this component if you want to get an access to [Link] and [Link] stuff in
your application. This component allows you to access the following classes inside a
script:
TControl
property [Link]
procedure [Link]
procedure [Link]
procedure [Link](ALeft, ATop, AWidth, AHeight: Integer)
event [Link]
event [Link]
event [Link]
event [Link]
event [Link]
event [Link]
event [Link]
TWinControl
procedure [Link]
event [Link]
event [Link]
event [Link]
event [Link]
event [Link]
TCustomControl
TGraphicControl
TGroupBox
TLabel
TEdit
TMemo
TCustomComboBox
property [Link]
property [Link]
TComboBox
TButton
TCheckBox
TRadioButton
TCustomListBox
property [Link]
property [Link]
property [Link]
TListBox
TControlScrollBar
TScrollingWinControl
TScrollBox
TCustomForm
procedure [Link]
procedure [Link]
procedure [Link]
function [Link]: Integer
event [Link]
event [Link]
event [Link]
event [Link]
event [Link]
event [Link]
event [Link]
event [Link]
event [Link]
property [Link]
TForm
type TModalResult
type TCursor
type TShiftState
type TAlignment
type TAlign
type TMouseButton
type TAnchors
type TBevelCut
type TTextLayout
type TEditCharCase
type TScrollStyle
type TComboBoxStyle
type TCheckBoxState
type TListBoxStyle
type TFormBorderStyle
type TWindowState
type TFormStyle
type TBorderIcons
type TPosition
type TCloseAction
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iFormsRTTI" unit to the "uses" clause.
TfsExtCtrlsRTTI component
Use this component if you want to get an access to [Link] stuff in your
application. This component allows you to access the following classes inside a script:
TShape
TPaintBox
event [Link]
TImage
TBevel
TTimer
event [Link]
TPanel
TSplitter
TBitBtn
TSpeedButton
TCheckListBox
property [Link]
TTabControl
TTabSheet
TPageControl
procedure [Link](GoForward: Boolean)
property [Link]
property [Link]
TStatusPanel
TStatusPanels
function [Link]: TStatusPanel
property [Link]
TStatusBar
TTreeNode
procedure [Link]
function [Link]: Boolean
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
TTreeNodes
function [Link](Node: TTreeNode; const S: string): TTreeNode
function [Link](Node: TTreeNode; const S: string):
TTreeNode
procedure [Link]
procedure [Link]
procedure [Link](Node: TTreeNode)
procedure [Link]
property [Link]
property [Link]
TTreeView
procedure [Link]
procedure [Link]
property [Link]
property [Link]
TTrackBar
TProgressBar
TListColumn
TListColumns
function [Link]: TListColumn
property [Link]
TListItem
procedure [Link]
function [Link]: Boolean
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
TListItems
function [Link]: TListItem
procedure [Link]
procedure [Link]
procedure [Link](Index: Integer)
procedure [Link]
property [Link]
property [Link]
TIconOptions
TListView
TToolButton
TToolBar
TMonthCalColors
TDateTimePicker
TMonthCalendar
type TShapeType
type TBevelStyle
type TBevelShape
type TResizeStyle
type TButtonLayout
type TButtonState
type TButtonStyle
type TBitBtnKind
type TNumGlyphs
type TTabPosition
type TTabStyle
type TStatusPanelStyle
type TStatusPanelBevel
type TSortType
type TTrackBarOrientation
type TTickMark
type TTickStyle
type TProgressBarOrientation
type TIconArrangement
type TListArrangement
type TViewStyle
type TToolButtonStyle
type TDateTimeKind
type TDTDateMode
type TDTDateFormat
type TDTCalAlignment
type TCalDayOfWeek
You get an access to all the published properties of these classes and the access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iExtCtrlsRTTI" unit to the "uses" clause.
TfsDialogsRTTI component
Use this component if you want to get an access to [Link] stuff in your
application. This component allows you to access the following classes inside a script:
TCommonDialog
function [Link]: Boolean
TOpenDialog
TSaveDialog
TColorDialog
TFontDialog
TPrintDialog
TPrinterSetupDialog
type TOpenOptions
type TFileEditStyle
type TColorDialogOptions
type TFontDialogOptions
type TFontDialogDevice
type TPrintRange
type TPrintDialogOptions
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iDialogsRTTI" unit to the "uses" clause.
TfsDBRTTI component
Use this component if you want to get an access to [Link] stuff in your application.
This component allows you to access the following classes inside a script:
TField
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
TFields
property [Link]
TStringField
TNumericField
TIntegerField
TSmallIntField
TWordField
TAutoIncField
TFloatField
TCurrencyField
TBooleanField
TDateTimeField
TDateField
TTimeField
TBinaryField
TBytesField
TVarBytesField
TBCDField
TBlobField
procedure [Link](const FileName: String)
procedure [Link](Stream: TStream)
procedure [Link](const FileName: String)
procedure [Link](Stream: TStream)
TMemoField
TGraphicField
TFieldDef
TFieldDefs
property [Link]
TDataSource
type TBookmark
TDataSet
procedure [Link]
procedure [Link]
procedure [Link]
procedure [Link]
procedure [Link]
procedure [Link]
procedure [Link]
procedure [Link]
procedure [Link]
procedure [Link]
procedure [Link]
procedure [Link]
function [Link](const FieldName: string): TField
procedure [Link](List: TStrings)
function [Link]: Boolean
function [Link]: Boolean
function [Link]: Boolean
function [Link]: Boolean
procedure [Link](Bookmark: TBookmark)
function [Link]: TBookmark
procedure [Link](Bookmark: TBookmark)
function [Link](const KeyFields: string; const KeyValues:
Variant; Options: TLocateOptions): Boolean
function [Link]: Boolean
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
TParam
procedure [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
property [Link]
TParams
function [Link](const Value: string): TParam
function [Link](const Value: string): TParam
property [Link]
type TFieldType
type TBlobStreamMode
type TLocateOptions
type TFilterOptions
type TParamType
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iDBRTTI" unit to the "uses" clause.
TfsDBCtrlsRTTI component
Use this component if you want to get an access to [Link] stuff in your
application. This component allows you to access the following classes inside a script:
TDBEdit
TDBText
TDBCheckBox
property [Link]
TDBComboBox
property [Link]
TDBListBox
TDBRadioGroup
property [Link]
property [Link]
TDBMemo
TDBImage
TDBNavigator
TDBLookupControl
property [Link]
TDBLookupListBox
property [Link]
TDBLookupComboBox
property [Link]
TColumnTitle
TColumn
TDBGridColumns
function [Link]: TColumn
property [Link]
TDBGrid
type TButtonSet
type TColumnButtonStyle
type TDBGridOptions
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iDBCtrlsRTTI" unit to the "uses" clause.
TfsBDERTTI component
Use this component if you want to get an access to BDE stuff in your application. This
component allows you to access the following classes inside a script:
TSession
TDatabase
TBDEDataSet
TDBDataSet
TTable
procedure [Link]
procedure [Link]
procedure [Link]
function [Link](const KeyValues: array): Boolean
procedure [Link](const KeyValues: array)
procedure [Link](const NewTableName: string)
TQuery
procedure [Link]
function [Link](const Value: string): TParam
procedure [Link]
property [Link]
TStoredProc
procedure [Link]
function [Link](const Value: string): TParam
procedure [Link]
property [Link]
type TTableType
type TParamBindMode
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iBDERTTI" unit to the "uses" clause.
TfsADORTTI component
Use this component if you want to get an access to ADO stuff in your application. This
component allows you to access the following classes inside a script:
TADOConnection
TParameter
TParameters
property [Link]
TCustomADODataSet
TADOTable
TADOQuery
procedure [Link]
TADOStoredProc
procedure [Link]
type TDataType
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iADORTTI" unit to the "uses" clause.
TfsIBXRTTI component
Use this component if you want to get an access to IBX stuff in your application. This
component allows you to access the following classes inside a script:
TIBDataBase
TIBTransaction
TIBCustomDataSet
TIBTable
TIBQuery
procedure [Link]
TIBStoredProc
procedure [Link]
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iIBXRTTI" unit to the "uses" clause.
TfsChartRTTI component
Use this component if you want to get an access to TeeChart stuff in your application.
This component allows you to access the following classes inside a script:
TChartValueList
TChartAxisTitle
TChartAxis
TCustomChartLegend
TChartLegend
TSeriesMarks
TChartGradient
TChartWall
TChartBrush
TChartTitle
TChartSeries
procedure [Link]
procedure [Link](const AValue: Double; const ALabel: String;
AColor: TColor)
TSeriesPointer
TCustomSeries
TLineSeries
TPointSeries
TAreaSeries
TCustomBarSeries
TBarSeries
THorizBarSeries
TCircledSeries
TPieSeries
TFastLineSeries
TCustomChart
TChart
type TChartValue
type TLegendStyle
type TLegendAlignment
type TLegendTextStyle
type TChartListOrder
type TGradientDirection
type TSeriesMarksStyle
type TAxisLabelStyle
type THorizAxis
type TVertAxis
type TTeeBackImageMode
type TPanningMode
type TSeriesPointerStyle
type TMultiArea
type TMultiBar
type TBarStyle
You have an access to all the published properties of these classes and an access to
some public properties and methods.
Note: This is a "fake" component. It is needed only for automatic inclusion of the
"FS_iChartRTTI" unit to the "uses" clause.
Scripting
The simplest example of scripting
Getting the list of the supported languages
Showing the detail info about the syntax error
Debugging the the script
Adding a procedure to the script
Adding a function to the script
Adding a function with var and default
parameters
Adding a function with class parameters
Adding a function which returns value of class
type
Adding a constant to the script
Adding a variable to the script
Adding an object variable to the script
Adding a type to the script
Adding an enumeration to the script
Adding a set type to the script
Adding a class to the script
Implementation of the public properties and
methods of the class
Implementation of the class event handler
Implementation of the non-standard event
handler
Accessing script variables from the Delphi code
Calling a script function from the Delphi code
Calling a script function with var parameters
Calculation of the expressions
Saving and loading of the precompiled code
Script tutorials
The simplest example of scripting
Here is a sample code which demonstrates the easiest way of using FastScript. Just put
the TfsScript, TfsPascal and TButton components onto your form and write the following
code in the [Link] event:
procedure TForm1.Button1Click(Sender: TObject);
begin
[Link];
[Link] := 'begin ShowMessage(''Hello!'') end.';
[Link] := fsGlobalUnit;
[Link] := 'PascalScript';
if not [Link] then
ShowMessage([Link]);
end;
- Clear the script. It is necessary if you use one component to run many scripts.
- Fill the Lines property by the script code;
- To use standard types and functions pass the fsGlobalUnit to the Parent property.
- Run the script using the PascalScript language. If compilation was successful, Run
method returns True. Otherwise an error message is shown.
Getting the list of the supported languages
To get the list of the supported languages call the fsGetLanguageList(list: TStrings)
procedure, defined in the FS_iTools unit.
uses FS_iTools;
fsGetLanguageList([Link]);
Showing the detail info about the syntax error
uses FS_iInterpreter, FS_iTools;
begin
if not [Link] then
begin
{ show the error message and position in the status bar }
[Link] := [Link] + ' at ' + [Link];
Exit;
end
else
[Link];
end;
Debugging the script
Use OnRunLine. For example:
procedure [Link](Sender: TfsScript; const UnitName,
SourcePos: String);
var
pt: TPoint;
begin
// locate the unit with UnitName name
...
// locate the line with pt.Y number
pt := fsPosToPoint(SourcePos);
FStopped := True;
while FStopped do
[Link];
end;
Examine the demo located in the DEMOS\Main folder.
Adding a procedure to the script
To add a procedure/function to a script, perform the following steps:
- Create a method handler - function of the TfsCallMethodEvent type.
- Call [Link] method. The first parameter is a function syntax, the second
is a link to the handler of TfsCallMethodEvent type.
{ the function itself }
procedure [Link](s: String; i: Integer);
begin
ShowMessage(s + ', ' + IntToStr(i));
end;
{ the method handler }
function [Link](Instance: TObject; ClassType: TClass; const
MethodName: String;
var Params: Variant): Variant;
begin
DelphiFunc(Params[0], Params[1]);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
{ clear all items }
[Link];
{ script text }
[Link] := [Link];
{ frGlobalUnit contains standard types and functions }
[Link] := fsGlobalUnit;
{ make DelphiFunc procedure visible to a script }
[Link]('procedure DelphiFunc(s: String; i: Integer)',
CallMethod);
{ compile the script }
if [Link] then
[Link] else { execute if compilation was succesfull }
ShowMessage([Link]); { show an error message }
end;
If you want to add several methods, you can do it using one method handler:
[Link]('procedure DelphiFunc(s: String; i: Integer)',
CallMethod);
[Link]('procedure DelphiFunc2(s: String)', CallMethod);
{ the method handler }
function [Link](Instance: TObject; ClassType: TClass; const
MethodName: String;
var Params: Variant): Variant;
begin
{ dispatch the method call }
if MethodName = 'DELPHIFUNC' then
DelphiFunc(Params[0], Params[1])
else if MethodName = 'DELPHIFUNC2' then
DelphiFunc2(Params[0]);
end;
Adding a function to the script
The same as adding a procedure.
[Link]('function DelphiFunc2(s: String): Boolean',
CallMethod);
{ the method handler }
function [Link](Instance: TObject; ClassType: TClass; const
MethodName: String;
var Params: Variant): Variant;
begin
Result := DelphiFunc(Params[0]);
end;
Adding a function with var and default parameters
You don't need to care about default parameters - they are substituted automatically by
FastScript. Var parameters must be handled by you.
[Link]('function DelphiFunc(var s: String; i: Integer =
0): Boolean', CallMethod);
{ the method handler }
function [Link](Instance: TObject; ClassType: TClass; const
MethodName: String;
var Params: Variant): Variant;
var
s: String;
begin
s := Params[0];
Result := DelphiFunc(s, Params[1]);
Params[0] := s;
end;
Adding a function with the class parameter
Since all the parameters are represented as the Variant array type, you need to convert
them to objects.
[Link]('procedure HideButton(Button: TButton)', CallMethod);
{ the method handler }
function [Link](Instance: TObject; ClassType: TClass; const
MethodName: String;
var Params: Variant): Variant;
begin
TButton(Integer(Params[0])).Hide;
end;
Adding a function which returns a value of the class type
Since the values returned by the method handler is the array of theVariant type, you
need to convert the results of theTObject type to the Variant.
[Link]('function MainForm: TForm', CallMethod);
{ the method handler }
function [Link](Instance: TObject; ClassType: TClass; const
MethodName: String;
var Params: Variant): Variant;
begin
Result := Integer(Form1);
end;
Adding a constant to the script
To add a constant to a script, call the [Link] method. The first parameter
is the name of the constant, the second one is the type (it must be one of the standard
types), the third one is a value.
[Link]('pi', 'Extended', 3.14159);
Adding a variable to the script
To add a variable to a script, call the [Link] method. It is similar to
AddConst method, except that fact that you can change the value of a variable in a script.
Note that the actual Delphi variable is not changed after the script execution.
[Link]('i', 'Integer', i);
Adding an object to the script
To add an object to a script, call the [Link] method. The first parameter
is the name of the object, the second one is the object itself.
[Link]('Button1', Button1);
If object has an unregistered type, you have to register it before calling AddObject:
[Link](TForm1, 'TForm');
[Link]('Form1', Form1);
You can also use [Link] method to add a form or datamodule with all
its child components:
[Link](Form1);
In this case you don't need to register the form class by AddClass method. Now you can
access a form element in the script:
[Link] := '...'
Adding a type to the script
To add the own type to a script, call the [Link] method. The first
parameter is the name of the type, the second one is the one of the supported types:
TfsVarType = (fvtInt, fvtBool, fvtFloat, fvtChar, fvtString, fvtClass,
fvtArray, fvtVariant, fvtEnum);
[Link]('TCursor', fvtInt);
Adding an enumeration to the script
To add an enumeration type to the script, call the [Link] method. The
first parameter is the name of the type, the second one is the type values separated by
commas.
[Link]('TPrinterOrientation', 'poPortrait, poLandscape');
Adding a set to the script
To add a set type to a script, call the [Link] method. The first
parameter is the name of the type, the second one is the type values separated by commas.
[Link]('TFontStyles', 'fsBold, fsItalic, fsUnderline,
fsStrikeOut');
Adding a class to the script
To add a class to a script, call the [Link] method. The first parameter is
the class type, the second one is the name of the parent class.
type
TMyClass = class(TObject)
...
end;
[Link](TMyClass, 'TObject');
This will make all the published properies of this class available. If you want to make
this class available for all the scripts, it is recommended to add this class to the
fsGlobalUnit which is a global ancestor of all the scripts.
Implementation of the public properties and methods of the
class
The AddClass method automatically adds all the published properties of the class.
Public properties and methods require an extra work. The following example shows how
to add a public method to a class. You need to create the method handler (function of type
TfsCallMethod).
begin
...
{ add new class inherited from TObject }
with [Link](TList, 'TObject') do
begin
{ add public methods }
AddMethod('function Add(Item: TObject): Integer', CallMethod);
AddMethod('procedure Clear', CallMethod);
end;
...
end;
{ method handler }
function [Link](Instance: TObject; ClassType: TClass;
const MethodName: String; var Params: Variant): Variant;
begin
Result := 0;
if MethodName = 'ADD' then
{ convert Variant parameter to Pointer type and pass it to Add method
}
TList(Instance).Add(Pointer(Integer(Params[0])))
else if MethodName = 'CLEAR' then
TList(Instance).Clear
end;
To implement a property you need to create a method handler and two types property
handlers TfsGetValueEvent and TfsSetValueEvent:
TfsGetValueEvent = function(Instance: TObject; ClassType: TClass;
const PropName: String): Variant of object;
TfsSetValueEvent = procedure(Instance: TObject; ClassType: TClass;
const PropName: String; Value: Variant) of object;
Indexed and default properties are described by the method handler, the ordinary
properties are handled by the Get/Set property handlers.
begin
...
with [Link](TStrings, 'TPersistent') do
begin
{ property CommaText: String }
AddProperty('CommaText', 'string', GetProp, SetProp);
{ property Count: Integer readonly, second handler is nil }
AddProperty('Count', 'Integer', GetProp, nil);
{ index property Objects[Index: Integer]: TObject }
AddIndexProperty('Objects', 'Integer', 'TObject', CallMethod);
{ default property Strings[Index: Integer]: String }
AddDefaultProperty('Strings', 'Integer', 'string', CallMethod);
end;
...
end;
{ method handler }
function [Link](Instance: TObject; ClassType: TClass;
const MethodName: String; var Params: Variant): Variant;
begin
Result := 0;
if MethodName = '[Link]' then
Result := Integer(TStrings(Instance).Objects[Params[0]])
else if MethodName = '[Link]' then
TStrings(Instance).Objects[Params[0]] := TObject(Integer(Params
[1]))
else if MethodName = '[Link]' then
Result := TStrings(Instance).Strings[Params[0]]
else if MethodName = '[Link]' then
TStrings(Instance).Strings[Params[0]] := Params[1]
end;
{ property handler }
function [Link](Instance: TObject; ClassType: TClass;
const PropName: String): Variant;
begin
Result := 0;
if PropName = 'COMMATEXT' then
Result := TStrings(Instance).CommaText
else if PropName = 'COUNT' then
Result := TStrings(Instance).Count
end;
{ property handler }
procedure [Link](Instance: TObject; ClassType: TClass;
const PropName: String; Value: Variant);
begin
if PropName = 'COMMATEXT' then
TStrings(Instance).CommaText := Value
end;
Implementing of the class event handler
To add an event to the class, use the [Link] method. The first
parameter is the event name, the second one is the event handler.
with [Link](TControl, 'TComponent') do
AddEvent('OnClick', TfsNotifyEvent);
There are some predefined event handlers available in the FS_iEvents unit:
TfsNotifyEvent
TfsMouseEvent
TfsMouseMoveEvent
TfsKeyEvent
TfsKeyPressEvent
TfsCloseEvent
TfsCloseQueryEvent
TfsCanResizeEvent
See the the "TfsFormsRTTTI component", "TfsExtCtrlsRTTI component" and
"TfsDBCtrlsRTTI component" chapters for the list of events available in script.
Implementation of the non-standard event handler
There are some predefined event handlers available in FS_iEvents unit:
TfsNotifyEvent
TfsMouseEvent
TfsMouseMoveEvent
TfsKeyEvent
TfsKeyPressEvent
TfsCloseEvent
TfsCloseQueryEvent
TfsCanResizeEvent
However, if you need to write your own event handler have a look at the following
example:
{ example of two event handlers }
type
{ analogue of TNotifyEvent }
TfsNotifyEvent = class(TfsCustomEvent)
public
procedure DoEvent(Sender: TObject);
function GetMethod: Pointer; override;
end;
{ analogue of TKeyPressEvent = procedure(Sender: TObject; var Key:
Char) }
TfsKeyPressEvent = class(TfsCustomEvent)
public
procedure DoEvent(Sender: TObject; var Key: Char);
function GetMethod: Pointer; override;
end;
{ TfsNotifyEvent }
procedure [Link](Sender: TObject);
begin
{ CallHandler is an internal method }
CallHandler([Sender]);
end;
function [Link]: Pointer;
begin
Result := @[Link];
end;
{ TfsKeyPressEvent }
procedure [Link](Sender: TObject; var Key: Char);
begin
CallHandler([Sender, Key]);
{ get var parameter }
Key := String([Link][1].Value)[1];
end;
function [Link]: Pointer;
begin
Result := @[Link];
end;
Accessing script variables from the Delphi code
To get/set the value of a script variables use [Link] property.
val := [Link]['i'];
[Link]['i'] := 10;
Calling a script function from the Delphi code
To call a script function, use [Link] method. The first parameter is the
name of the called function, the second one is the function parameters.
// call to 'function ScriptFunc(s: String; i: Integer)'
val := [Link]('ScriptFunc', VarArrayOf(['hello', 1]));
Calling a script function with var parameters
The same as described above. Use TfsScript.CallFunction1 method if your
procedure/function accepts var parameters:
var
Params: Variant;
Params := VarArrayOf(['hello', 1]);
// call to 'function ScriptFunc(var s: String; i: Integer)'
fsScript1.CallFunction1('ScriptFunc', Params);
ShowMessage(Params[0]);
Calculation of the expressions
If you want to calculate an expression (for example, 'i+1'), call the [Link]
method.
ShowMessage([Link]('i+1'));
It is useful for debugging purposes.
Saving and loading of the precompiled code
Sometimes it is necessary to save compilation results and perform it later. You can do
it with the help of the [Link] and SetILCode methods.
The below code compiles the source script and places the precompiled results to the
stream:
var
s: TStream;
[Link] := ...;
[Link](s);
After this, you can restore the precompiled code from the stream and perform it:
[Link](s);
[Link];
Using "uses" directive
You can split large script to modules, like in Object Pascal:
File [Link]:
uses '[Link]';
begin
Unit2Proc('Hello!');
end.
File [Link]:
procedure Unit2Proc(s: String);
begin
ShowMessage(s);
end;
begin
ShowMessage('initialization of unit2...');
end.
As you can see, you should write module name with file extension in quotes. The code
placed in begin..end of the included module will be executed when you run script (this is
analogue of initialization in the Pascal).
In this example you cannot use unit1 from within unit2. This will cause circular reference
and infinity loop when compiling such script. Such references are not allowed since
FastScript does not have interface/implementation sections.
Using #language directive, you can write multi-language scripts. For example, one
module may be written in PascalScript, another one - using C++Script:
File [Link]:
uses '[Link]';
begin
Unit2Proc('Hello from PascalScript!');
end.
File [Link]:
#language C++Script
void Unit2Proc(string s)
{
ShowMessage(s);
}
{
ShowMessage("unit2 initialization, C++Script");
}
The #language directive must be the first line of the file. If this directive exists it
overrides [Link] setting.
Script tutorials
Script tutorials are located in the DEMOS\Main\Samples folder. Compile the demo
located in the DEMOS\Main folder and open the script samples in it.