2009-06-26 14 views
9

Tworzę wbudowany silnik skryptowy za pomocą PascalScript z RemObjects (doskonały) i edytor SynEdit. Jest prawie ukończony przy użyciu przykładu IDE dostarczanego z PascalScript i przykładu IDE w SynEdit - ale - nie mogę zobaczyć, jak zapytać PascalScript, czy numerowana linia źródłowa jest "wykonywalna", czy nie. (Mogę użyć tego do oznaczenia rynny SynEdit za pomocą "niebieskiej kropki Delphi"). Sądzę, że mógłbym wykonać demontaż wyjścia ROPS?Tworzenie IDE przy użyciu Pascal Script i SynEdit

Dowolny ekspert PascalScript tutaj? Dzięki. Brian.

+0

To wygląda na interesujący projekt. Czy masz stronę dla niego? Czy udostępnisz źródło po uruchomieniu? –

Odpowiedz

9

Zobacz kod źródłowy: Inno Setup. Pokazuje małą kropkę w obszarze rynny SynEdit dla linii z kodem wykonawczym, szare dla linii, które są wykonywalne, ale nie zostały wykonane, zielone dla linii, które zostały uderzone co najmniej raz.

Kod ten można znaleźć w CompForm.pas, poszukaj typu TLineState. Informacje są konfigurowane w stanie oddzwaniającego kompilatora, można to zrobić w IDE. Może zajść potrzeba przystosowania kodu do obsługi wielu plików źródłowych, ponieważ kompilator Inno Setup zajmuje się fragmentami kodu tylko w jednym pliku źródłowym.

W źródłach skryptu Pascala powinieneś rzucić okiem na metodę TPSCustomDebugExec.TranslatePositionEx() - zwraca również nazwę pliku źródłowego.

+1

Świetny pomysł. Wiedziałem, że Innosetup używa PascalScript, ale nie zdawałem sobie sprawy, że ma on funkcje edycji. Off, aby wyglądać. Dzięki. –

+0

mghie, twoja sugestia była doskonała. Miałem wszystkie potrzebne informacje. Pozdrawiam, Brian. –

1

Nie wiem dokładnie jak to działa, ale projekt IDE w pakiecie PascalScript (znajdujący się w \ samples \ debug) jest w stanie zaoferować funkcje Step Into i Step Over (F7 i F8), więc logicznie musi mieć jakiś sposób powiązania kodu bajtowego PS z liniami kodu skryptu. Spróbuj przeanalizować ten projekt, aby zobaczyć, jak to działa. Jako bonus, używa również SynEdit, więc pomysły będą łatwe do dostosowania do własnego systemu.

+0

Dzięki za komentarz Mason. Używałem tego bardzo dużo. StepInto i StepOver są wbudowane w klasę TPSDebugScript i nic dziwnego, że dostają swoje "Ive zakończyli w tej nowej linii", wykonując kod. Zanim kod zostanie wykonany, muszę zapytać o kod skryptu pod kątem możliwych linii i to właśnie mnie flumoxuje. Bri –

+0

W jaki sposób mapuje kod na linie źródłowe? Nie ma związku 1: 1.Rozważ "x: = 5;" i "x: = 5 * performCalculation (y, z + x);" Obie są jedną linią, ale druga zawiera dużo więcej operacji do wykonania. Musi być jakiś rodzaj metadanych zmieszanych z kodem bajtowym, którego używa do wykonania mapowania. –

+0

@Mason: Zajrzyj do TPSCustomDebugExec.TranslatePositionEx(). Ma pozycję źródłową w rekordzie informacji debugowania i dla każdego op może wyszukać informacje o pozycji źródłowej. Dla twojego drugiego przykładu wszystkie te operacje zwrócą zapisaną pozycję źródłową pierwszej operacji w tym wierszu. – mghie

0

Wiem, że to stare pytanie, ale robię to samo, a powyższe sugestie tak naprawdę nie pomagają. Instalacja Inno na przykład nie używa Synedit, używa edytora scintilla.

Również TPSCustomDebugExec.TranslatePositionEx() działa odwrotnie do tego, co jest potrzebne, podaje numer linii źródłowej z pozycji kodu wykonawczego.

Po pewnym okresie rozmyślania doszedłem do wniosku, że najprościej było dodać funkcję do kodu Pascalscript.

Nowa metoda zostanie dodana do klasy TPSCustomDebugExec w jednostce uPSdebugger.

function TPSCustomDebugExec.HasCode(Filename:string; LineNo:integer):boolean; 
var i,j:integer; fi:PFunctionInfo; pt:TIfList; r:PPositionData; 
begin 
    result:=false; 
    for i := 0 to FDebugDataForProcs.Count -1 do 
    begin 
    fi := FDebugDataForProcs[i]; 
    pt := fi^.FPositionTable; 
    for j := 0 to pt.Count -1 do 
    begin 
     r:=pt[j]; 
     result:= SameText(r^.FileName,Filename) and (r^.Row=LineNo); 
     if result then exit 
    end; 
    end; 
end; 

i zwrotna farby rynny w formularzu głównym edytora jest jak poniżej

procedure Teditor.PaintGutterGlyphs(ACanvas:TCanvas; AClip:TRect; 
    FirstLine, LastLine: integer); 
var a,b:boolean; LH,LH2,X,Y,ImgIndex:integer; 
begin 
    begin 
    FirstLine := Ed.RowToLine(FirstLine); 
    LastLine := Ed.RowToLine(LastLine); 
    X := 14; 
    LH := Ed.LineHeight; 
    LH2:=(LH-imglGutterGlyphs.Height) div 2; 
    while FirstLine <= LastLine do 
    begin 
     Y := LH2+LH*(Ed.LineToRow(FirstLine)-Ed.TopLine); 
     a:= ce.HasBreakPoint(ce.MainFileName,FirstLine); 
     b:= ce.Exec.HasCode(ce.MainFileName,FirstLine); 
     if Factiveline=FirstLine then 
     begin 
     if a then 
      ImgIndex := 2 //Blue arrow+red dot (breakpoint and execution point) 
     else 
      ImgIndex := 1; //Blue arrow (current line execution point) 
     end 
     else 
     if b then 
     begin 
      if a then 
      ImgIndex := 3 //Valid Breakpoint marker 
      else 
      ImgIndex := 0; //blue dot (has code) 
     end 
     else 
     begin 
      if a then 
      ImgIndex := 4 //Invalid breakpoint (No code on this line) 
      else 
      ImgIndex := -1; //Empty (No code for line) 
     end; 
     if ImgIndex >= 0 then 
     imglGutterGlyphs.Draw(ACanvas, X,Y,ImgIndex); 
     Inc(FirstLine); 
    end; 
    end; 
end; 

Synedit z numerami linii, kod kropki, pułapki, zakładki i punkty wykonanie wygląd jak na obrazku poniżej

enter image description here

Powiązane problemy