Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How I can evaluate an expression which contains the `Pi` constant using ICompiledBinding?

I'm using the ICompiledBinding interface to evaluate simple expressions, If I use literals like (2*5)+10 works fine , but when i try to compile something like 2*Pi the code fails with the error :

EEvaluatorError:Couldn't find Pi

This is my current code

{$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.

So how I can evaluate an expression which contains the Pi constant using the ICompiledBinding interface?

like image 853
Salvador Avatar asked Sep 18 '25 10:09

Salvador


1 Answers

As far i know exists two options

1) You can initializate the IScope interface using the TNestedScope class passing the BasicOperators and BasicConstants scopes.

(The BasicConstants Scope define nil, true, False, and 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) you can add the Pi Value manually to the Scope using a sentence like this.

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

and the code will look like this

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;
like image 200
RRUZ Avatar answered Sep 21 '25 01:09

RRUZ