[英]Is it possible to create a Read–eval–print loop (REPL) using DWScript?
I am trying to create a Read–eval–print loop (REPL) with DWScript and I'm not sure this is possible. 我正在尝试使用DWScript创建一个Read-eval-print循环(REPL),我不确定这是否可行。
Based on the name, I assumed that RecompileInContext
would work fine in that context but I am experiencing some limitations: 根据名称,我假设RecompileInContext
在该上下文中可以正常工作,但我遇到了一些限制:
var test = "content";
例如,当键入var test = "content";
then test
, content
should be displayed. 然后test
,应显示content
。 As far as I can tell, using print
or println
can't work as they will be executed at each run 据我所知,使用print
或println
无法工作,因为它们将在每次运行时执行 So my question is: Is it possible to create a REPL using DWScript ? 所以我的问题是:是否可以使用DWScript创建REPL?
Here is what I've got so far: 这是我到目前为止所得到的:
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.
You can use TdwsCompiler.Evaluate to compile a snippet to an IdwsEvaluateExpr, it is then possible to evaluate the contained expression to a string with yourEvaluateExpr.Expression.EvalAsString 您可以使用TdwsCompiler.Evaluate将代码段编译为IdwsEvaluateExpr,然后可以使用yourEvaluateExpr.Expression.EvalAsString将包含的表达式计算为字符串。
The above is the typical mechanism to use for debug evaluations, expression watches or conditional breakpoints (though not always evaluated as string, an expression can return an object, an array, etc. or can hold a statement that returns nothing). 以上是用于调试评估,表达式监视或条件断点的典型机制(虽然并不总是作为字符串求值,但表达式可以返回对象,数组等,或者可以保存不返回任何内容的语句)。
RecompileInContext will keep the declarations, but throw away the "main" code, so bugs in the main code will not affect future runs, but if you declare a faulty type for a variable, or a faulty function implementation, it will stay there in the script context. RecompileInContext将保留声明,但丢弃“主”代码,因此主代码中的错误不会影响将来的运行,但如果您为变量声明了错误类型,或者错误的函数实现,它将保留在脚本上下文。
However the message list is not cleared automatically, you have to clear it yourself (originally RecompileInContext was intended to handle small script snippets in a larger source, so keeping as many errors as possible in the message list was the desired behavior, so that a correct last script would not "erase" the errors of an incorrect first script) 但是,消息列表不会自动清除,您必须自己清除它(最初RecompileInContext旨在处理较大源中的小脚本片段,因此在消息列表中保留尽可能多的错误是所需的行为,因此正确最后一个脚本不会“擦除”错误的第一个脚本的错误)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.