2009-06-26 13 views
9

Ich erstelle eine integrierte Skript-Engine mit PascalScript von RemObjects (ausgezeichnet) und dem SynEdit-Editor. Es ist fast fertig mit dem IDE-Beispiel, das mit PascalScript geliefert wurde und dem IDE-Beispiel in SynEdit - aber - ich kann nicht sehen, wie man PascalScript fragt, ob eine nummerierte Quellzeile "ausführbar" ist oder nicht. (Ich kann das verwenden, um den SynEdit-Kanal mit dem blauen Delphi-Punkt zu markieren). Ich denke, ich muss vielleicht die ROPS-Ausgabe demontieren?Erstellen einer IDE mit Pascal Script und SynEdit

Alle PascalScript-Experten hier? Vielen Dank. Brian.

+0

Das sieht wie ein interessantes Projekt aus. Haben Sie eine Website dafür? Werden Sie die Quelle verfügbar machen, sobald Sie es funktioniert haben? –

Antwort

9

Werfen Sie einen Blick auf den Quellcode Inno Setup. Es zeigt einen kleinen Punkt im SynEdit-Rinnenbereich für Linien mit ausführbarem Code, graue für Linien, die ausführbar sind, aber nicht ausgeführt wurden, grüne für Linien, die mindestens einmal getroffen wurden.

Der Code dafür finden Sie in CompForm.pas, suchen Sie nach dem TLineState Typ. Die Information wird in dem iscbNotifySuccess-Status des Compiler-Rückrufs eingerichtet, Sie könnten dasselbe in Ihrer IDE vornehmen. Möglicherweise müssen Sie den Code an mehrere Quelldateien anpassen, da der Inno Setup-Compiler nur Code-Snippets in der einzelnen Quelldatei verarbeitet.

In den Pascal Script-Quellen sollten Sie sich die TPSCustomDebugExec.TranslatePositionEx()-Methode ansehen - sie gibt auch den Namen der Quelldatei zurück.

+1

Tolle Idee. Ich wusste, dass Innosetup PascalScript benutzte, aber ich hatte nicht bemerkt, dass es die Bearbeitungsfunktionen hatte. Auszuschauen. Vielen Dank. –

+0

mghie, war dein Vorschlag ausgezeichnet. Das hatte alle Informationen, die ich brauchte. Grüße, Brian. –

1

Ich weiß nicht genau, wie es das tut, aber das IDE-Projekt im PascalScript-Paket (gefunden unter \ samples \ debug) bietet Step-In und Step-Over (F7 und F8) Funktionalität, also logisch muss eine Möglichkeit haben, PS-Bytecode mit Zeilen des Skriptcodes zu verknüpfen. Versuchen Sie, dieses Projekt zu untersuchen, um zu sehen, wie es funktioniert. Als Bonus nutzt es auch SynEdit, so dass die Ideen einfach an Ihr eigenes System angepasst werden können.

+0

Danke für den Kommentar Mason. Ich habe dieses Beispiel sehr oft benutzt. StepInto und StepOver sind in die TPSDebugScript-Klasse integriert und es ist nicht überraschend, dass sie ihre "Ich bin bei dieser neuen Zeile gelandet" haben, indem sie den Code tatsächlich ausführen. Bevor der Code ausgeführt wird, muss ich den Skript-Code nach möglichen Zeilen abfragen, und das ist der Teil, der mich verwirrt. Bri –

+0

Wie wird Code auf Quellzeilen abgebildet? Es gibt keine 1: 1-Beziehung.Betrachte "x: = 5;" und "x: = 5 * performCalculation (y, z + x);" Beide sind eine einzelne Zeile, aber die zweite enthält viel mehr Operationen, die ausgeführt werden müssen. Es muss eine Art von Metadaten geben, die mit dem Bytecode gemischt wird, der für das Mapping verwendet wird. –

+0

@Mason: Sehen Sie in TPSCustomDebugExec.TranslatePositionEx(). Es hat die Quellposition in den Debug-Infosätzen und kann für jedes Op die Quellpositionsinformationen nachschlagen. Für Ihr zweites Beispiel würden alle diese Operationen die gespeicherte Quellposition der ersten Operation in dieser Zeile zurückgeben. – mghie

0

Ich weiß, das ist eine alte Frage, aber ich habe das selbe selbst gemacht und die obigen Vorschläge helfen nicht wirklich. Das Inno-Setup verwendet zum Beispiel keine Synedit, sondern einen Scintilla-Editor.

Auch das TPSCustomDebugExec.TranslatePositionEx() führt das Gegenteil von dem, was gewünscht wird, es gibt eine Quellzeilennummer aus einer Laufzeitcodeposition an.

Nach einiger Zeit kam ich zu dem Schluss, dass es am einfachsten ist, dem PascalScript-Code eine Funktion hinzuzufügen.

Die neue Methode wird der TPSCustomDebugExec-Klasse in der Einheit uPSdebugger hinzugefügt.

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; 

und die Farbe Gosse Rückruf in der Hauptform Editor ist als unten

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; 

Die SynEdit mit Zeilennummern, Codepunkten, Haltepunkten, Lesezeichen und Ausführungspunkt Blick, wie im Bild unten

enter image description here