i’m using JCL’s expression evaluator TEvaluator (a marvelous creation donated by barry kelly). (THANK YOU barry!)
background
i’ve used the AddFunc method.
function MyFunc:double; begin // calculations here Result:=1; end;
you can use the AddFunc method to make the function available:
AddFunc('MyFunc', MyFunc);
here’s the problem…
i need to call a method on an object instead of a standalone routine.
the reason is that i have a list of objects that provide the values.
say we have a list of vehicle objects. each object has a Weight function. i want to be able to make available each object’s weight available for use in the formula.
a silly example but it’s easy to explain:
type TVehicle=class private public function Weight:double; end; function StrangeCalculation:double; var vehicle:TVehicle; begin for iVehicle = 0 to Count - 1 do begin vehicle:=GetVehicle(iVehicle); // E2250 There is no overloaded version of 'AddFunc' that can be called with these arguments eval.AddFunc(vehicle.Name, vehicle.Weight); end; Result:=eval.Evaluate('JeepTJWeight + FordF150Weight * 2'); end;
my options:
-
AddVar( ) or AddConst( ) — but that isn’t so great because i need to be able to raise an exception if the value is not available.
-
AddFunc( ) with standalone functions. can’t do that because the names of (and number of) variables is unknown until runtime.
-
modify the object to add a callback if the variable isn’t found. i have actually done this but needed to edit a copy of the source to call back to make it do this.
-
make an AddFunc( ) that’s able to use method functions.
option #3 is actually built but an additional AddFunc would be nicer. the trouble is i don’t know what method prototype to provide. i thought TMethod would be the way but my knowledge is too limited here… here was my unsuccessful attempt but i still get ‘E2250 There is no overloaded version of ‘AddFunc’ that can be called with these arguments’ at the eval.AddFunc() call like before.
TFloat64MethodFunc = function(c:pointer): TFloat64; procedure TEasyEvaluator.AddFunc(const AName: string; AFunc: TFloat64MethodFunc); begin FOwnContext.Add(TExprFloat64MethodFuncSym.Create(AName, AFunc)); end; TExprFloat64MethodFuncSym = class(TExprAbstractFuncSym) private FFunc: TFloat64MethodFunc; public constructor Create(const AIdent: string; AFunc: TFloat64MethodFunc); function Evaluate: TFloat; override; // not using function Compile: TExprNode; override; end;
thank you for your help!
mp
figured it out…
TFloat64MethodFunc = function: TFloat of object;