Как создать отображение «локальных переменных» с использованием DWScript и его отладчика - PullRequest
6 голосов
/ 09 сентября 2011

Я пишу IDE для DWScript и получил пошаговое выполнение кода с помощью отладчика.Теперь я хочу добавить отображение «локальных переменных» (то есть тех, которые находятся в области видимости).Может кто-нибудь дать мне указатель на способы сделать это?Я могу получить список всех символов, но не понимаю, как получить текущую область действия.Спасибо.

Ответы [ 2 ]

9 голосов
/ 09 сентября 2011

Применив IdwsProgramExecution к TdwsProgramExecution , вы получите доступ к свойству " CurrentProg ", TdwsProgram , которое либо TdwsMainProgram (если вы находитесь в основном), либо TdwsProcedure (если вы используете метод proc / func /). У них будет свойство Table , в котором перечислены локальные символы, это самая прямая область. Эта Таблица будет иметь одного или нескольких Родителей , которые ссылаются на родительские области (иерархически, в терминах области действия исходного кода).

Если в TdwsProcedure вы также можете посмотреть его свойство FuncSymbol , которое будет иметь таблицу параметров (полезно, если вы хотите напрямую изолировать параметры от остальная часть местного масштаба)

2 голосов
/ 09 сентября 2011

Для всех остальных, читающих этот вопрос, я покажу некоторую дополнительную информацию, касающуюся получения значения символа.Символ находится, как описано Эриком выше, но трудно понять, как получить действительное значение символа.Приведенный ниже код представляет собой процедуру, которая заполняет TMemo (memLocalVariables) локальными переменными при каждом вызове.Не хватает некоторых функций, таких как аккуратное форматирование значения переменной и доступ к параметрам вызова.Я вызываю это из состояния отладчика dsDebugSuspended.Менее интуитивный бит - это доступ к символьным данным в стеке и использование базового указателя стека.Отличный способ узнать, как работает компилятор!Но, может быть, где-то есть функция полезности, которую я не нашел ...?Эрик?

  procedure DrawLocalVariables;
  var
    ProgramExecution : TdwsProgramExecution;
    I   : integer;
    Sym : TSymbol;
    V   : variant;
    Adr : integer;
    SymbolTable : TSymbolTable;
  begin
    memLocalVariables.Lines.Clear;

    ProgramExecution := TdwsProgramExecution( dwsDebugger1.Execution );
    SymbolTable := ProgramExecution.CurrentProg.Table;
    For I := 0 to SymbolTable.Count-1 do
      begin
      Sym := SymbolTable[I];
      if Sym is TDataSymbol then
        begin
        Adr := TDataSymbol( Sym).StackAddr + ProgramExecution.Stack.BasePointer;
        ProgramExecution.Stack.ReadValue( Adr, V );
        memLocalVariables.Lines.Add( Format( '%s = %s', [ Sym.Name, VarToStr(V) ] ));
        end;
      end;
  end;
...