Проблема с определением переменных
Здравствуйте!
Запускаю скрипт, перед этим определив некоторые переменные, передаваемые ему приложением через Variables.
При описании скрипта исхожу из того, что переменную можно было бы в теле скрипта описать:
var MYVAR :integer;
Это наглядно, а также удобно при тестировании скрипта и вообще компиляции в редакторе скриптов.
А можно было бы переменную в тексте скрипта и не описывать. Запретить не описывать нельзя, поскольку время от времени появляется необходимость добавлять в приложении передачу новых переменных (MYVAR1), то возможен вариант, когда exe сует в скрипт новую переменную ,а она в нем не прописана.
ТО есть скрипт в своем теле в секции var может иметь описание переменной, которую ему передает приложение (скрипт первого типа), а может и не описать (скрипт второго типа). Тут вариантов для изменения политики уже нет: скриптов уже сотни, они стоят у клиентов, менять политику поздно.
Идем дальше, последовательность запуска скрипта, инициализации этих внешних переменных, компиляции скрипта.
1) Tfscript.create
2) Variables :=
3) compile
Скрипт второго типа откомпилится и сработает. А вот скрипт первого типа, то есть если переменная была описана через VAR уже в скрипте, на этапе (3) даст еггог "переопределение переменной".
Меняем последовательность: 1-3-2. Тогда все в норме в скриптах первого типа, но проблема со скриптами второго типа - на компиляции ругнется на отсутствие переменной, ибо она создается позже.
Вот и задача: реализовать так, чтобы запуск скрипта, определение, компиляция проходили без проблем для обоих типов скриптов.
Нормальными способами решить задачу у меня не вышло. Сейчас присутствует хакеро-проктологическое решение: заткнул в исходниках проверку переопределения переменной. То есть ошибки не получаю, но стало возможно дважды создать переменную в секции VAR, и компиляция не хрюкнет. а это серьезный минус.
Нет ли идей каких у кого на этот счет? Буду премного благодарен.
Запускаю скрипт, перед этим определив некоторые переменные, передаваемые ему приложением через Variables.
При описании скрипта исхожу из того, что переменную можно было бы в теле скрипта описать:
var MYVAR :integer;
Это наглядно, а также удобно при тестировании скрипта и вообще компиляции в редакторе скриптов.
А можно было бы переменную в тексте скрипта и не описывать. Запретить не описывать нельзя, поскольку время от времени появляется необходимость добавлять в приложении передачу новых переменных (MYVAR1), то возможен вариант, когда exe сует в скрипт новую переменную ,а она в нем не прописана.
ТО есть скрипт в своем теле в секции var может иметь описание переменной, которую ему передает приложение (скрипт первого типа), а может и не описать (скрипт второго типа). Тут вариантов для изменения политики уже нет: скриптов уже сотни, они стоят у клиентов, менять политику поздно.
Идем дальше, последовательность запуска скрипта, инициализации этих внешних переменных, компиляции скрипта.
1) Tfscript.create
2) Variables :=
3) compile
Скрипт второго типа откомпилится и сработает. А вот скрипт первого типа, то есть если переменная была описана через VAR уже в скрипте, на этапе (3) даст еггог "переопределение переменной".
Меняем последовательность: 1-3-2. Тогда все в норме в скриптах первого типа, но проблема со скриптами второго типа - на компиляции ругнется на отсутствие переменной, ибо она создается позже.
Вот и задача: реализовать так, чтобы запуск скрипта, определение, компиляция проходили без проблем для обоих типов скриптов.
Нормальными способами решить задачу у меня не вышло. Сейчас присутствует хакеро-проктологическое решение: заткнул в исходниках проверку переопределения переменной. То есть ошибки не получаю, но стало возможно дважды создать переменную в секции VAR, и компиляция не хрюкнет. а это серьезный минус.
Нет ли идей каких у кого на этот счет? Буду премного благодарен.
Комментарии
Правда "напильком пришлось порабоать"
Заводите глобальную переменную FUndeclared и перед компиляцией отключаете. потом при выполнение включаете обратно.
function TfsILParser.FindClass(const TypeName: String): TfsClassVariable;
begin
Result := FProgram.FindClass(TypeName);
if Result = nil then
if FUndeclared then
exit
else
raise Exception.Create(SUnknownType + '''' + TypeName + '''');
end;
function TfsILParser.FindVar(Prog: TfsScript; const Name: String): TfsCustomVariable;
begin
Result := Prog.Find(Name);
if Result = nil then
if not FNeedDeclareVars then
begin
Result := TfsVariable.Create(Name, fvtVariant, '');
FProgram.Add(Name, Result);
end
else
begin
// вот здесь заглушка
if fs_iinterpreter.FUndeclared then
begin
//if FUndeclaredList.IndexOfName(Name) = -1 then
if FUndeclaredList.IndexOf(Name) = -1 then
FUndeclaredList.Add(Name);
Result := TfsVariable.Create(Name, fvtVariant, '');
FProgram.Add(Name, Result);
end else
raise Exception.Create(SIdUndeclared + '''' + Name + '''');
end;
end;
и в месте где определение параметров
begin
if FUndeclared then
continue;
raise Exception.Create(STooManyParams)
end
И добавить в секции в модуле
fs_iinterpreter.pas
initialization
FUndeclaredList := TStringList.Create;
FProfileList := TStringList.Create;
FProfileList.Sorted := True;
FUndeclared := False;
finalization
FUndeclaredList.Free;
FProfileList.Free;
end.