3

インターフェイスを使用して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.

Piでは、ICompiledBinding インターフェイスを使用して定数を含む式を評価するにはどうすればよいでしょうか?

4

1 に答える 1

5

私が知る限り、2つのオプションが存在します

1)およびスコープを渡すクラスをIScope使用して、インターフェイスを初期化できます。TNestedScopeBasicOperatorsBasicConstants

(BasicConstants スコープは、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 値を追加できます。

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;
于 2012-07-04T22:45:39.480 に答える