unit fs01ef_main; interface uses //----------------------------- //FastScript fs_iinterpreter, fs_synmemo, fs_ipascal, fs_iclassesrtti, //----------------------------- Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Buttons, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.ComCtrls; type TForm1 = class(TForm) Panel1: TPanel; fsScript1: TfsScript; fsPascal1: TfsPascal; fsClassesRTTI1: TfsClassesRTTI; Panel2: TPanel; Panel3: TPanel; SpeedButton1: TSpeedButton; GroupBox1: TGroupBox; fsSyntaxMemo1: TfsSyntaxMemo; Panel_fsSyntMemo: TPanel; procedure FormCreate(Sender: TObject); procedure SpeedButton1Click(Sender: TObject); private { Private declarations } public { Public declarations } //функция (метод) формы, где реализована обработка вызова функции/процедуры function fsCallMethod(Instance: TObject; ClassType: TClass; const MethodName: String; var Params: Variant): Variant; end; var Form1: TForm1; function MyFunc_AddToFS(fsScr: TfsScript; //компонент fsScript sWhat:string; //вид: procedure или function sFuncRes:string; //тип возвр. значения для function или пустая строка для procedure sListFuncNames:string; //перечень (через точку с запятой) идентификаторов (наименований) фукции/процедуры sFuncScript:string; //текст "объявления" функции/процедуры (без окаймляющих скобок) fCallMethod:TfsCallMethodEvent //функция формы(TForm), где реализована обработка вызова функции/процедуры ):boolean; //Добавить в FastScript новую процедуру/функцию на "нескольких языках" implementation {$R *.dfm} function Get_Word_From_String( Sx : String; NumWord : integer; UnChar: String=' '; YesAllTrim_Before: boolean=true ) : String; //Получить слово из строки Sx по номеру NumWord. UnChar - множество разделителей //YesAllTrim_Before - если TRUE, то перед анализом удалить из строки левые и правые пробелы Var InWord : byte; NumWordCur, i : integer; begin Result:=''; if YesAllTrim_Before then Sx:=trim(Sx); if length(Sx)>0 then begin if NumWord>0 then begin InWord := 0; NumWordCur:=0; i:=0; while i<length(Sx) do begin i:=i+1; if POS(Sx[i],UnChar)<=0 then begin //этот символ - НЕ разделитель if InWord<=0 then NumWordCur:=NumWordCur+1; //мы - на начале слова InWord:=1; //Мы внутри слова if NumWordCur=NumWord then begin //Это - наше слово Result:=Result+Sx[i]; //и мы его выдираем из строки end; end else begin //этот символ - разделитель InWord:=0; //Мы снаружи слова if NumWordCur=NumWord then begin //Это было - наше слово i:=length(Sx)+1; //поэтому, выходим из цикла и функции end; end; end; end; end; end; function Get_CountWords_In_String( Sx : String; UnChar: String=' '; YesAllTrim_Before: boolean=true ) : integer; //Определить кол-во слов в строке Sx. UnChar - множество разделителей var InWord : byte; i : integer; begin Result:=0; if YesAllTrim_Before then Sx:=trim(Sx); if length(Sx)>0 then begin InWord := 0; i:=0; while i<length(Sx) do begin i:=i+1; if POS(Sx[i],UnChar)<=0 then begin //этот символ - НЕ разделитель if InWord<=0 then Result:=Result+1; //переход на начало слова InWord:=1; //Мы внутри слова end else begin //этот символ - разделитель InWord:=0; //Мы снаружи слова end; end; end; end; procedure Screen_Cursor_Set(sCurs:string='crDefault'); //"Назначить" курсор на экране Var Yes:boolean; begin sCurs:=trim(sCurs); Yes:=false; if sCurs='' then sCurs:='crDefault'; if AnsiUpperCase(sCurs)=AnsiUpperCase('crDefault') then begin Yes:=true; Screen.Cursor:=crDefault; end; if AnsiUpperCase(sCurs)=AnsiUpperCase('crHourGlass') then begin Yes:=true; Screen.Cursor:=crHourGlass; end; if AnsiUpperCase(sCurs)=AnsiUpperCase('crSQLWait') then begin Yes:=true; Screen.Cursor:=crSQLWait; end; if AnsiUpperCase(sCurs)=AnsiUpperCase('crAppStart') then begin Yes:=true; Screen.Cursor:=crAppStart; end; if AnsiUpperCase(sCurs)=AnsiUpperCase('crHandPoint') then begin Yes:=true; Screen.Cursor:=crHandPoint; end; if AnsiUpperCase(sCurs)=AnsiUpperCase('crArrow') then begin Yes:=true; Screen.Cursor:=crArrow; end; if AnsiUpperCase(sCurs)=AnsiUpperCase('crNo') then begin Yes:=true; Screen.Cursor:=crNo; end; if not Yes then begin Screen.Cursor:=crDefault; end; end; function Files_ToStrings(List: TStrings; FullNameMask:string = '*.*'; YesFileNamesOnly:boolean=true ):integer; // Прочитать список файлов по маске в TStrings Var sDir,sMask,NameF: string; DirInfo: TSearchRec; Err: integer; begin Result := 0; if Assigned(List) then begin List.Clear; FullNameMask := trim(FullNameMask); if FullNameMask<>'' then begin sDir:=trim(ExtractFilePath(FullNameMask)); if DirectoryExists(sDir) then begin sMask := trim(ExtractFileName(FullNameMask)); if sMask='' then sMask := '*.*'; Err := 0; Err := FindFirst(sDir + sMask, { faArchive } faAnyFile, DirInfo); while Err = 0 do begin NameF := DirInfo.Name; if FileExists(sDir + NameF) then begin if YesFileNamesOnly then begin List.Add(NameF); end else begin List.Add(sDir+NameF); end; end; Err := FindNext(DirInfo); Application.ProcessMessages; end; FindClose(DirInfo); Result := List.Count; end; end; end; end; function MyFunc_AddToFS(fsScr: TfsScript; //компонент fsScript sWhat:string; //вид: procedure или function sFuncRes:string; //тип возвр. значения для function или пустая строка для procedure sListFuncNames:string; //перечень (через точку с запятой) идентификаторов (наименований) фукции/процедуры sFuncScript:string; //текст "объявления" функции/процедуры (без окаймляющих скобок) fCallMethod:TfsCallMethodEvent //функция формы(TForm), где реализована обработка вызова функции/процедуры ):boolean; //Добавить в FastScript новую процедуру/функцию на "нескольких языках" Var sNameFunc:string; i,c:integer; Sx:string; s222:string; begin Result:=false; if Assigned(fsScr) then begin if Assigned(fCallMethod) then begin sWhat:=trim(sWhat); if length(sWhat)>0 then begin sListFuncNames:=trim(sListFuncNames); if length(sListFuncNames)>0 then begin s222:=''; sFuncRes:=trim(sFuncRes); if AnsiUpperCase(sWhat)='PROCEDURE' then sFuncRes:=''; if sFuncRes<>'' then begin s222:=':'; if sFuncRes[length(sFuncRes)]<>';' then begin sFuncRes:=sFuncRes+';'; end; end else begin sFuncRes:=';'; end; sFuncScript:=trim(sFuncScript); //s222:=''; if sFuncScript<>'' then begin if sFuncScript[length(sFuncScript)]=';' then begin sFuncScript[length(sFuncScript)]:=' '; end; end; sFuncScript:=trim(sFuncScript); c:=Get_CountWords_In_String( sListFuncNames, #32+#9+';' ); if c>0 then begin Result:=true; i:=0; while i<c do begin i:=i+1; sNameFunc:=trim( Get_Word_From_String( sListFuncNames, i, #32+#9+';' ) ); if length(sNameFunc)>0 then begin if length(sFuncScript)>0 then begin Sx:=sWhat+' '+sNameFunc+'('+sFuncScript+')'+s222+sFuncRes; end else begin Sx:=sWhat+' '+sNameFunc+s222+sFuncRes; end; fsScr.AddMethod(Sx, fCallMethod); end else begin Result:=false; i:=c+1; end; end; end; end; end; end; end; end; function MyConst_AddToFS(fsScr: TfsScript; sListConstNames:string; sConstType:string; sConstVal:string ):boolean; //Добавить в FastScript новую константу на "двух языках" Var sNameConst:string; i,c:integer; begin Result:=false; if Assigned(fsScr) then begin sListConstNames:=trim(sListConstNames); sConstType:=trim(sConstType); sConstVal:=trim(sConstVal); if (sListConstNames<>'') and (sConstType<>'') and (sConstVal<>'') then begin c:=Get_CountWords_In_String(sListConstNames, #32+#9+';'); if c>0 then begin Result:=true; i:=0; while i<c do begin i:=i+1; sNameConst:=trim(Get_Word_From_String(sListConstNames, i, #32+#9+';')); if sNameConst<>'' then begin fsScr.AddConst(sNameConst, sConstType, sConstVal); end else begin Result:=false; i:=c+1; end; end; end; end; end; end; function TForm1.fsCallMethod(Instance: TObject; ClassType: TClass; const MethodName: String; var Params: Variant): Variant; //функция (метод) формы, где реализована обработка вызова функции/процедуры Var B:boolean; begin Result:=0; //------------------------------- if POS(AnsiUpperCase(';'+MethodName+';'), AnsiUpperCase(';'+'Экран_Курсор;Screen_Cursor'+';') )>0 then begin Screen_Cursor_Set(trim(Params[0])); Application.ProcessMessages; end; //------------------------------- //------------------------------- if POS(AnsiUpperCase(';'+MethodName+';'), AnsiUpperCase(';'+'Файлы_Список_Получить;Files_List_Get'+';') )>0 then begin B:=Params[2]; Result:=Files_ToStrings( POINTER(Integer(Params[0])), //List:TStrings trim(Params[1]), //FullNameMask B //YesFileNamesOnly ); Application.ProcessMessages; end; //------------------------------- end; procedure TForm1.FormCreate(Sender: TObject); begin fsSyntaxMemo1.Parent := Panel_fsSyntMemo; fsSyntaxMemo1.Align := alClient; end; procedure TForm1.SpeedButton1Click(Sender: TObject); begin Application.ProcessMessages; //--------------------- fsScript1.Clear; fsScript1.Lines.Text := fsSyntaxMemo1.Lines.Text; fsScript1.Parent := fsGlobalUnit; fsScript1.SyntaxType := 'PascalScript'; //--------------------- //--------------------- MyFunc_AddToFS(fsScript1, 'procedure','', 'Экран_Курсор;Screen_Cursor', 'sCursor:string='+#39+'crDefault'+#39, fsCallMethod); MyFunc_AddToFS(fsScript1, 'function', 'integer', 'Файлы_Список_Получить;Files_List_Get', 'List: TStrings;' +' FullNameMask: string='+#39+'*.*'+#39+';' +' YesFileNamesOnly: boolean=true' , fsCallMethod); //--------------------- //--------------------- MyConst_AddToFS(fsScript1, 'Ускорение_свободного_падения', 'real', '9.8' ); MyConst_AddToFS(fsScript1, 'Скорость_света;Speed_of_light', 'extended', '299792458.0' ); //--------------------- //--------------------- if fsScript1.Compile then begin fsScript1.Execute; end else begin ShowMessage('Ошибка компиляции скрипта: '+fsScript1.ErrorMsg); end; //--------------------- end; end.