代码之家  ›  专栏  ›  技术社区  ›  Brian Frost

使用pascal脚本和synedit生成IDE

  •  9
  • Brian Frost  · 技术社区  · 15 年前

    我正在使用remobjects(优秀)中的pascalscript和synedit编辑器创建内置脚本引擎。使用pascalscript附带的ide示例和synedit中的ide示例几乎已经完成了-但是-我不知道如何询问pascalscript一个编号的源代码行是否是“可执行的”。(然后我可以用这个标记synedit排水沟与“delphi蓝点”)。我想我可能需要对ROPS输出进行分解?

    这里有帕斯卡文字专家吗?谢谢。布莱恩。

    3 回复  |  直到 9 年前
        1
  •  9
  •   mghie    15 年前

    查看的源代码 Inno Setup . 它确实会在synedit gutter区域中为具有可执行代码的行显示一个小圆点,为可执行但尚未执行的行显示灰色圆点,为至少命中一次的行显示绿色圆点。

    此代码可在中找到 CompForm.pas 寻找 TLineState 类型。信息设置在 iscbNotifySuccess 编译器回调的状态,您可以在IDE中执行相同的操作。您可能需要调整代码来处理多个源文件,因为Inno安装编译器只处理单个源文件中的代码片段。

    在pascal脚本源代码中,您应该查看 TPSCustomDebugExec.TranslatePositionEx() 方法-它也返回源文件的名称。

        2
  •  1
  •   Mason Wheeler    15 年前

    我不知道它是如何做到的,但是Pascalscript包中的IDE项目(在\samples\debug下找到)能够提供跨步和跨步(f7和f8)功能,因此在逻辑上,它必须有某种方式将ps字节码与脚本代码行相关联。试着检查那个项目,看看它是怎么做的。作为一个额外的好处,它也使用synedit,所以这些想法很容易适应您自己的系统。

        3
  •  1
  •   Andy k    9 年前

    我知道这是一个古老的问题,但我自己也在做同样的事情,上面的建议没有真正的帮助。例如,Inno安装程序不使用synedit,它使用scintila编辑器。

    另外,tpscustomdebugexec.translatepositionex()的作用与需要的相反,它从运行时代码位置提供源代码行号。

    在苦恼了一段时间之后,我得出结论,最简单的方法是向pascalscript代码中添加一个函数。

    新方法被添加到upsdebugexec单元中的tpscustomdebugexec类中。

    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;
    

    主编辑器窗体中的油漆槽回调如下

    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如下图所示。

    enter image description here