Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Скриптовый язык


Автор: miksayer 28.10.2005, 15:35
Хотелось бы реализовать скриптовый язык в моей программе. Может посоветуете какой-то компонент или еще что-то?

Автор: Akella 28.10.2005, 16:50
ставь пакет JEDDI (JCL, JVCL)

Автор: unknovvn 28.10.2005, 18:01
а что это за пакет?
и где мона скачать?

Автор: Droll 29.10.2005, 17:02
JEDI VCL - один из популярнейших бесплатных наборов компонент (визуальных и невизуальных).
Скачать можно тут: http://sourceforge.net/projects/jvcl

PS
скриптов я там не нашел, но, возможно, просто плохо искал smile

Автор: miksayer 29.10.2005, 19:52
мдя, я тоже там не нашел скриптов. Там вроде есть что-то, содержащее в названии слово Script, но ни примеров ни документации по этому компоненту нету

Автор: Rrader 30.10.2005, 14:59
http://www.fast-report.com/ru/products/products.php?BID=5

Автор: miksayer 30.10.2005, 23:05
Rrader, не очень хочется юзать платный компонент
И еще хочется узнать, как Vit реализовал скриптовый язык в своем GoldenPen'е

Автор: miksayer 1.11.2005, 22:42
а как компонент для этого из JVCL называется?

Автор: AriX 2.11.2005, 10:53
Держи %)

PAXScript - http://paxscript.com/
RaLib - входит в набор JEDI
Dream Scripter - http://dream-com.com/scripter.html
Pascal Script - http://www.remobjects.com/page.asp?id={9A30A672-62C8-4131-BA89-EEBBE7E302E6} - ИХМО один из лучших
Delphi Web Script - http://www.dwscript.com/
TMS Scripter Studio - http://www.tmssoftware.com/scriptstudio.htm

Думаю, что-то подходящее точно найдешь smile

Автор: Случайный посетитель 2.11.2005, 13:25
Можешь также воспользоваться встроенным средством Microsoft Windows - WSH(Windows Script Host)

Автор: Akella 2.11.2005, 17:21
Ищи компоненты в JVCL с названием Interpreter (закладка JvInterpreter)
как пользоваться? читай справку

Автор: miksayer 5.11.2005, 11:22
dsergey, AriX,спасибо, гляну

Автор: ne0n 5.11.2005, 12:28
Microsoft Windows - WSH(Windows Script Host) Лучший вариант. Помоему
у меня статья(вкаченная с делфи ворлд) была как раз чтобы реализовать скрипты в своей проге!!

Автор: klyaksa 7.10.2013, 15:46
Подскажите какой из вариантов может такое и как это сделать.
Есть список переменных (он может быть любой). Есть код скрипта (он может быть любой). Нужно выполнить этот скрипт и после его выполнения получить значения этих переменных, например в stringlist (имя = значение). 
Пробовал смотреть Pascal  remobjects и TMS, но не разобрался как это можно сделать. Тем более так, как я понял, можно связать уже имеющиеся переменные с переменными в скрипте. Но это не вариант, т.к. они могут быть любые.

Автор: kami 7.10.2013, 22:05
Смотри RemObjects Samples\Pascal Script for Delphi\Import\fMain.pas
Там как раз производится работа с уже созданными TMemo + регистрируется TStringList в ХХRegister_Controls(...).
Переделать большого труда не составит.

Я у себя делал так (на оригинальность и правильность не претендую, всё подсмотрено в примерах, но - работает успешно):
1. делал модуль, содержащий все нужные мне типы и функции, которые будут использоваться в скрипте (само собой - кроме уже наработанных, типа TStrings). Через PSUnitImporter.exe из папки bin генерировал врапперы для них (не всегда четко отрабатывает, бывает нужно подправить ручками. Кстати, больше всего намучился с record-ами, оказалось - нужно указывать packed).

2. Добавлял получившийся враппер плагином в PSScript:
Код

FPSMySuperWrapper := TPSImport_uSuperPascalScriptWrappers1.Create(nil);
TPSPluginItem(FPSScript.Plugins.Add).Plugin := FPSMySuperWrapper;


3. В OnScriptCompile добавлял переменные, которые будут использоваться в скрипте, например, так:
Код

  Sender.AddRegisteredVariable('Intervals', 'TRouteIntervals');
  Sender.AddRegisteredPTRVariable('StartRouteTime', 'TDateTime'); // для использования функций из DateUtils нужно подключить плагин TPSImport_DateUtils.
  Sender.AddRegisteredPTRVariable('Cost', 'Double');


4. В OnScriptExecute - привязывал объявленные переменные к реальным:
Код

  Sender.SetVarToInstance('Intervals', FIntervals);
  Sender.SetPointerToData('StartRouteTime', @FStartRouteTime, Sender.FindNamedType('TDateTime'));
  Sender.SetPointerToData('Cost', @FCost, Sender.FindBaseType(btDouble));



5. И уже в тексте самого скрипта делаешь с этими переменными что хочешь, например:
Код

  Cost:= Intervals.FullRouteLength * 1024.5+MyDelphiFunctionFromWrapper(StartRouteTime);


После отработки скрипта в переменных получается то, что наработал скрипт, но меня интересовала одна - Cost (это для скрипта, а для программы - FCost).

Ну, а если даже сам скрипт не знает, какие переменные ему нужны - тут курить примеры с Variant-ами и массивами...

Автор: kami 7.10.2013, 22:23
Цитата(klyaksa @  7.10.2013,  15:46 Найти цитируемый пост)
Тем более так, как я понял, можно связать уже имеющиеся переменные с переменными в скрипте. Но это не вариант, т.к. они могут быть любые.

мда... не дочитал.
А, собственно, как это - любые? То есть - программа говорит скрипту "на тебе что-то, сама не знаю что", а скрипт, совершенно не представляя, что же ему отдали, должен с этим что-то сделать нечто эдакое, да еще и вернуть другой набор чего-то, о чем в свою очередь программа не догадывается и -соответственно - не сможет использовать?

Автор: klyaksa 8.10.2013, 08:24
Цитата(kami @  7.10.2013,  22:23 Найти цитируемый пост)
А, собственно, как это - любые? То есть - программа говорит скрипту "на тебе что-то, сама не знаю что", а скрипт, совершенно не представляя, что же ему отдали, должен с этим что-то сделать нечто эдакое, да еще и вернуть другой набор чего-то, о чем в свою очередь программа не догадывается и -соответственно - не сможет использовать? 

Например, дан скрипт (любой). Мы его текст пропарсили и получили какие в нем есть переменные. Потом запустили и надо получить значения (конечные) этих переменных и, допустим, в мемо их вывели с = лялял, х = 10...

Добавлено через 4 минуты и 58 секунд
Вроде бы по описанию что нужно умеет FastScript, но пробник с оф. сайта работать не захотел.

---------------------------
Delphi XE: bds.exe - Системная ошибка
---------------------------
Запуск программы невозможен, так как на компьютере отсутствует Tee9150.bpl. Попробуйте переустановить программу. 
---------------------------
ОК   
---------------------------


[Window Title]
Error

[Content]
Can't load package C:\DelphiXE\Fast\LibD15\dclfstee15.bpl.
Не найден указанный модуль.
Do you want to attempt to load this package the next time a project is loaded?

[Yes] [No]

Автор: kami 8.10.2013, 09:01
Цитата(klyaksa @  8.10.2013,  08:24 Найти цитируемый пост)
Потом запустили и надо получить значения (конечные) этих переменных и, допустим, в мемо их вывели с = лялял, х = 10...

Ввиду того, что твое приложение не знает, какие переменные есть в скрипте и, соответственно, - не имеет ни малейшего представления, что с ними делать дальше - не лучше ли будет сразу из скрипта выводить необходимые значения в тот же мемо и не заморачиваться на получение имен переменных в приложении? Можно даже не просто значения, а прямо текстовые описания предпринятых скриптом действий.

Добавлено через 54 секунды
То есть, получается - при запуске скрипта передали ему экземпляр мемо, а он пишет туда что хочет.

Автор: klyaksa 8.10.2013, 11:42
Скрипт  пишет пользователь, ему не нужно заморачиваться с выводом переменных.
Только если самому добавлять строки в скрипт, но это как-то не очень. Хотя на крайний случай как вариант.

Автор: klyaksa 8.10.2013, 12:22
kami,  а как в RemObjects Samples\Pascal Script for Delphi\TestApp подключить memo...? Добавляю плагины импорта на компиляции скрипта Project TestApplication.exe raised exception class EPSCompilerException with message 'Unable to register type TDrawItemEvent'.
Т.е. как в Import\fMain.pas, только с PSScript.

Вроде разобрался, в проекте с нуля заработало.

Автор: klyaksa 8.10.2013, 12:56
Кстати, где можно глянуть что понимает RemObjects Pascal Script.
Можно ли как сразу инициализировать массивы?
SysUtils можно подцепить или каждую надо отдельно и импортировать?

Автор: CynicRus 8.10.2013, 16:59
Цитата(klyaksa @ 8.10.2013,  12:56)
Кстати, где можно глянуть что понимает RemObjects Pascal Script.
Можно ли как сразу инициализировать массивы?
SysUtils можно подцепить или каждую надо отдельно и импортировать?

Там очень много чего можно. К сожалению документация унылая, и потому приходится курить исходники.  Можно, например

TSA:=['string','anotherstring'] и т.д. В самом скрипте. Что понимает PascalScript - тебе нужен модуль uPSCompiler. Открываешь его и смотришь, чего он понимает. За счёт того, что приходится втыкать самому в код, реализация чего либо дополнительного в PS проблематична, но возможна. Вот например реализация метода перевода любой зарегистрированной PS переменной в строку:

Код


function MakeString(data : TPSVariantIFC) : string;
begin;
  if data.Dta = nil then
    result := 'Nil'
  else
  if data.aType.basetype in [btString,btChar] then
    result := PSGetAnsiString(Data.Dta,data.aType)
  else if data.aType.ExportName = 'BOOLEAN' then
    result := BoolToStr(PSGetInt(Data.Dta,data.aType) <> 0,true)
  else if data.aType.BaseType in [btExtended,btSingle,btDouble] then
    result := FloatToStr(PSGetReal(data.Dta,data.aType))
  else
    result := PSVariantToString(data,'');
end;

function ToStr_(Caller: TPSExec; p: TPSExternalProcRec; Global, Stack: TPSStack): Boolean;
begin
  result := true;
  Stack.SetAnsiString(-1, MakeString(NewTPSVariantIFC(Stack[Stack.Count-2],false)));
end;



А вот реалиация Swap для 2 переменных:

Код

function swap_(Caller: TPSExec; p: TPSExternalProcRec; Global, Stack: TPSStack): Boolean;
var
  Param1,Param2: TPSVariantIFC;
  tempCopy : pointer;
begin
  Result:=true;
  Param1 := NewTPSVariantIFC(Stack[Stack.count-1],true);
  Param2 := NewTPSVariantIFC(Stack[Stack.count-2],true);
  if Param1.aType.BaseType <> Param2.aType.BaseType then
    exit(false)
  else
  begin
    Param1.aType.CalcSize;
    param2.aType.CalcSize;
    if Param1.aType.RealSize <> Param2.aType.RealSize then
      exit(false);
    GetMem(tempcopy,Param1.aType.RealSize);
    Move(Param1.Dta^,tempCopy^,param1.atype.realsize);
    Move(Param2.Dta^,Param1.Dta^,param1.atype.realsize);
    Move(tempCopy^,Param2.Dta^,param1.atype.realsize);
    Freemem(tempcopy);
  end;
end;

Автор: kami 9.10.2013, 08:10
Цитата(klyaksa @  8.10.2013,  12:56 Найти цитируемый пост)
Можно ли как сразу инициализировать массивы?

Я пробовал - константой объявить в скрипте не смог :( . А так хотелось...

Цитата(klyaksa @  8.10.2013,  12:56 Найти цитируемый пост)
SysUtils можно подцепить или каждую надо отдельно и импортировать?

Емнип, SysUtils подцепляется автоматом. По крайней мере я не задумывался над тем, что из плагинов нужно для (к примеру) StrToInt.
А вообще - да, с документацией немножко плоховасто. Но для не слишком крутых задач имеющихся примеров хватает. Если что-то нужно - открываем uPSC_xxxxxxx.pas и смотрим, что PSScript узнает, подключив плагин.

Сейчас ради интереса попробовал - в TestApp в скрипте можно написать
Код

 Memo2.Lines.Add('asretq349501924uftesdfa');
. Зачем там добавили вывод через MyWriteln - разве что для примера импорта функции... 

Автор: CynicRus 9.10.2013, 08:32
О, вчера забыл - а добавляется приведённый мной код в PS примерно вот так:
Код

procedure TPSThread.OnCompImport(Sender: TObject; x: TPSPascalCompiler);

***


  with x.AddFunction('function ToStr:string').Decl.AddParam do
  begin
    OrgName := 'x';
    Mode := pmIn;
  end;

  with x.AddFunction('procedure swap;').Decl do
  begin
    with AddParam do
    begin
      OrgName := 'x';
      Mode := pmInOut;
    end;

    with AddParam do
    begin
      OrgName := 'y';
      Mode := pmInOut;
    end;
  end;




Автор: klyaksa 9.10.2013, 13:45
Из SysUtils не все работает. Например, не все функции преобразования флоат в строку.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)