【问题标题】:Is it possible to create a Read–eval–print loop (REPL) using DWScript?是否可以使用 DWScript 创建 Read-eval-print 循环 (REPL)?
【发布时间】:2016-02-12 13:37:52
【问题描述】:

我正在尝试使用 DWScript 创建一个读取-评估-打印循环 (REPL),但我不确定这是否可行。

根据名称,我认为RecompileInContext 在这种情况下可以正常工作,但我遇到了一些限制:

  • 程序中永远包含有错误的行:以后的运行总是会因为该行而失败
  • 我没有找到一种方法来简单地通过键入来输出变量的值。例如,当输入var test = "content"; 然后test 时,应显示content。据我所知,使用 printprintln 无法工作,因为它们将在每次运行时执行

所以我的问题是:是否可以使用 DWScript 创建 REPL?

这是我目前得到的:

program DwsRepl;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  dwsComp,
  dwsCompiler,
  dwsExprs;

var
  oCompiler: TDelphiWebScript;
  oProgram: IdwsProgram;
  oExecution: IdwsProgramExecution;
  sInput: string;
begin
  try
    oCompiler := TDelphiWebScript.Create(nil);
    try
      oProgram := oCompiler.Compile('', 'ReplScript');
      oExecution := oProgram.BeginNewExecution;
      try
        while True do
        begin
          Write('> ');
          // Read user input
          Readln(sInput);
          // Exit if needed
          if sInput = '' then Break;
          // Compile
          oCompiler.RecompileInContext(oProgram, sInput);
          if not oProgram.Msgs.HasErrors then
          begin
            oExecution.RunProgram(0);
            // Output
            if not oExecution.Msgs.HasErrors then
             Writeln(oExecution.Result.ToString)
            else
             Writeln('EXECUTION ERROR: ' + oExecution.Msgs.AsInfo);
          end
          else
           Writeln('COMPILE ERROR: ' + oProgram.Msgs.AsInfo);
        end;
      finally
        oExecution.EndProgram;
      end;
    finally
      oCompiler.Free();
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

【问题讨论】:

    标签: delphi dwscript


    【解决方案1】:

    您可以使用 TdwsCompiler.Evaluate 将 sn-p 编译为 IdwsEvaluateExpr,然后可以使用 yourEvaluateExpr.Expression.EvalAsString 将包含的表达式计算为字符串

    以上是用于调试评估、表达式监视或条件断点的典型机制(尽管并不总是作为字符串进行评估,但表达式可以返回对象、数组等,或者可以包含不返回任何内容的语句)。

    RecompileInContext 将保留声明,但丢弃“主”代码,因此主代码中的错误不会影响以后的运行,但如果您为变量声明错误的类型或错误的函数实现,它将保留在脚本上下文中。

    但是消息列表不会自动清除,您必须自己清除它(最初 RecompileInContext 旨在处理较大源中的小脚本 sn-ps,因此在消息列表中保留尽可能多的错误是期望的行为,因此正确的最后一个脚本不会“擦除”不正确的第一个脚本的错误)

    【讨论】:

    • 谢谢埃里克。我已经尝试过 TdwsCompiler.Evaluate,但它似乎仅限于琐碎的表达式和执行:我无法评估变量赋值,例如“var test = 2”。这个想法是与现有脚本交互并将其用于实时编程。一个简单的例子是 Laravel Tinker 命令:laravel-recipes.com/recipes/280/…
    猜你喜欢
    • 2012-08-28
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多