Delphi 是否可以创建读取–;评估–;是否使用DWScript打印循环(REPL)?
我正在尝试使用DWScript创建一个读取-评估-打印循环(REPL),我不确定这是否可行 基于名称,我假设Delphi 是否可以创建读取–;评估–;是否使用DWScript打印循环(REPL)?,delphi,dwscript,Delphi,Dwscript,我正在尝试使用DWScript创建一个读取-评估-打印循环(REPL),我不确定这是否可行 基于名称,我假设RecompileInContext在该上下文中可以正常工作,但我遇到了一些限制: 程序中永远包含一个有缺陷的行:由于该行,未来的运行将始终失败 我没有找到一种简单地通过键入变量来输出变量值的方法。例如,键入var test=“content”然后应显示测试,内容。据我所知,使用print或println无法工作,因为它们将在每次运行时执行 所以我的问题是:是否可以使用DWScript
RecompileInContext
在该上下文中可以正常工作,但我遇到了一些限制:
- 程序中永远包含一个有缺陷的行:由于该行,未来的运行将始终失败
- 我没有找到一种简单地通过键入变量来输出变量值的方法。例如,键入
var test=“content”代码>然后应显示
,测试
。据我所知,使用内容
或print
无法工作,因为它们将在每次运行时执行println
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.
您可以使用TdwsCompiler.Evaluate将代码段编译为IdwsEvaluateExpr,然后可以使用您的EvaluateExpr.expression.EvalAsString将包含的表达式计算为字符串 以上是用于调试计算、表达式监视或条件断点的典型机制(虽然不总是作为字符串计算,但表达式可以返回对象、数组等,也可以包含不返回任何内容的语句) RecompileInContext将保留声明,但会丢弃“主”代码,因此主代码中的错误不会影响将来的运行,但如果您为变量声明错误类型或错误函数实现,它将保留在脚本上下文中
但是,消息列表不是自动清除的,您必须自己清除它(最初,RecompileInContext旨在处理较大源中的小脚本片段,因此在消息列表中保留尽可能多的错误是所需的行为,以便正确的最后一个脚本不会“擦除”错误的第一个脚本的错误)谢谢Eric。我尝试过TdwsCompiler.Evaluate,但它似乎仅限于琐碎的表达式和执行:我无法计算变量赋值,例如“var test=2”。其想法是与现有脚本交互,并将其用于实时编程。一个简单的示例是Laravel Tinker命令: