Macro expander integrated in binder
This commit is contained in:
@@ -10,12 +10,41 @@ uses
|
||||
|
||||
type
|
||||
// Contains the "pure" native implementations.
|
||||
// These functions work with Delphi-native types (like TScalar) instead of TDataValue,
|
||||
// making them type-safe and easier to test.
|
||||
// The registration mechanism below will automatically create the required high-performance
|
||||
// wrappers to make them available to the script interpreter.
|
||||
TRtlFunctions = record
|
||||
public
|
||||
[TRtlFunction('+')]
|
||||
class function Add(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('-')]
|
||||
class function Subtract(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('*')]
|
||||
class function Multiply(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('/')]
|
||||
class function Divide(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('=')]
|
||||
class function Equal(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('<>')]
|
||||
class function NotEqual(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('<')]
|
||||
class function LessThan(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('<=')]
|
||||
class function LessThanOrEqual(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('>')]
|
||||
class function GreaterThan(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('>=')]
|
||||
class function GreaterThanOrEqual(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('not')]
|
||||
class function LogicalNot(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlFunction('Abs')]
|
||||
class function Abs(const Arg: TScalar): TScalar; static;
|
||||
|
||||
@@ -31,8 +60,6 @@ type
|
||||
[TRtlFunction('Sign')]
|
||||
class function Sign(const Arg: TScalar): TScalar; static;
|
||||
|
||||
// NOTE: Higher-order and complex functions can keep the TDataValue signature for now.
|
||||
// The registry is smart enough to handle both native types and the TDataValue signature directly.
|
||||
[TRtlFunction('Memoize')]
|
||||
class function Memoize(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
@@ -57,6 +84,139 @@ uses
|
||||
System.Math,
|
||||
Myc.Data.Decimal;
|
||||
|
||||
{ TRtlFunctions - Operator Implementations }
|
||||
|
||||
class function TRtlFunctions.Add(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Operator + requires 2 arguments.');
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.Add, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for operator +.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.Subtract(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) = 1 then // Unary negation
|
||||
begin
|
||||
if not TScalar.TryUnaryOperation(TScalar.TUnaryOp.Negate, Args[0], res) then
|
||||
raise EArgumentException.Create('Invalid argument for unary operator -.');
|
||||
end
|
||||
else if Length(Args) = 2 then // Binary subtraction
|
||||
begin
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.Subtract, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for binary operator -.');
|
||||
end
|
||||
else
|
||||
raise EArgumentException.Create('Operator - requires 1 or 2 arguments.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.Multiply(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Operator * requires 2 arguments.');
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.Multiply, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for operator *.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.Divide(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Operator / requires 2 arguments.');
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.Divide, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for operator /.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.Equal(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Operator = requires 2 arguments.');
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.Equal, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for operator =.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.NotEqual(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Operator <> requires 2 arguments.');
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.NotEqual, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for operator <>.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.LessThan(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Operator < requires 2 arguments.');
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.Less, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for operator <.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.LessThanOrEqual(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Operator <= requires 2 arguments.');
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.LessOrEqual, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for operator <=.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.GreaterThan(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Operator > requires 2 arguments.');
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.Greater, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for operator >.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.GreaterThanOrEqual(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Operator >= requires 2 arguments.');
|
||||
if not TScalar.TryBinaryOperation(TScalar.TBinaryOp.GreaterOrEqual, Args[0], Args[1], res) then
|
||||
raise EArgumentException.Create('Invalid arguments for operator >=.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
class function TRtlFunctions.LogicalNot(const Args: TArray<TDataValue>): TDataValue;
|
||||
var
|
||||
res: TScalar;
|
||||
begin
|
||||
if Length(Args) <> 1 then
|
||||
raise EArgumentException.Create('Operator not requires 1 argument.');
|
||||
if not TScalar.TryUnaryOperation(TScalar.TUnaryOp.Not, Args[0], res) then
|
||||
raise EArgumentException.Create('Invalid argument for operator not.');
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
{ TRtlFunctions - Standard Functions }
|
||||
|
||||
class function TRtlFunctions.Abs(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
case Arg.Kind of
|
||||
|
||||
Reference in New Issue
Block a user