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

时间:2012-07-04 22:34:21

标签: 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.

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

1 个答案:

答案 0 :(得分:5)

据我所知,存在两个选项

1)您可以使用传递TNestedScopeBasicOperators范围的BasicConstants类初始化IScope界面。

(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; 

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

TDictionaryScope(RootScope).Map.Add('Pi', TValueWrapper.Create(pi));

,代码看起来像这样

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;