如何使用ICompiledBinding评估包含`Pi`常量的表达式?

Sal*_*dor 3 delphi delphi-xe2

我正在使用ICompiledBinding接口来评估简单的表达式,如果我使用文字(2*5)+10工作正常,但当我尝试编译类似2*Pi代码失败时出现错误:

EEvaluatorError:找不到Pi

这是我目前的代码

{$APPTYPE CONSOLE}

uses
  System.Rtti,
  System.Bindings.EvalProtocol,
  System.Bindings.EvalSys,
  System.Bindings.Evaluator,
  System.SysUtils;


procedure Test;
Var
  RootScope : IScope;
  CompiledExpr : ICompiledBinding;
  R : TValue;
begin
  RootScope:= BasicOperators;
  //Compile('(2*5)+10', RootScope); //works
  CompiledExpr:= Compile('2*Pi', RootScope);//fails
  R:=CompiledExpr.Evaluate(RootScope, nil, nil).GetValue;
  if not R.IsEmpty then
   Writeln(R.ToString);
end;

begin
 try
    Test;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.
Run Code Online (Sandbox Code Playgroud)

那么我如何Pi使用ICompiledBinding接口评估包含常量的表达式呢?

RRU*_*RUZ 5

据我所知,存在两种选择

1)您可以IScope使用TNestedScope传递BasicOperatorsBasicConstants范围的类初始化接口.

(BasicConstants Scope定义nil,true,False和Pi.)

Var
  RootScope : IScope;
  CompiledExpr : ICompiledBinding;
  R : TValue;
begin
  RootScope:= TNestedScope.Create(BasicOperators, BasicConstants);
  CompiledExpr:= Compile('2*Pi', RootScope);
  R:=CompiledExpr.Evaluate(RootScope, nil, nil).GetValue;
  if not R.IsEmpty then
  Writeln(R.ToString);
end; 
Run Code Online (Sandbox Code Playgroud)

2)您可以使用这样的句子手动将Pi值添加到Scope.

TDictionaryScope(RootScope).Map.Add('Pi', TValueWrapper.Create(pi));
Run Code Online (Sandbox Code Playgroud)

代码看起来像这样

Var
  RootScope : IScope;
  CompiledExpr : ICompiledBinding;
  R : TValue;
begin
  RootScope:= BasicOperators;
  TDictionaryScope(RootScope).Map.Add('Pi', TValueWrapper.Create(pi));
  CompiledExpr:= Compile('2*Pi', RootScope);
  R:=CompiledExpr.Evaluate(RootScope, nil, nil).GetValue;
  if not R.IsEmpty then
  Writeln(R.ToString);
end;
Run Code Online (Sandbox Code Playgroud)