Global data value refactoring + 1st scripting version

This commit is contained in:
Michael Schimmel
2025-09-20 18:30:32 +02:00
parent 09bd25b318
commit 00f5861148
17 changed files with 1430 additions and 2742 deletions
+22 -34
View File
@@ -60,13 +60,9 @@ uses
class function TRtlFunctions.Abs(const Arg: TScalar): TScalar;
begin
case Arg.Kind of
skInteger: Result := TScalar.FromInteger(System.Abs(Arg.Value.AsInteger));
skInt64: Result := TScalar.FromInt64(System.Abs(Arg.Value.AsInt64));
skSingle: Result := TScalar.FromSingle(System.Abs(Arg.Value.AsSingle));
skDouble: Result := TScalar.FromDouble(System.Abs(Arg.Value.AsDouble));
skDecimal: Result := TScalar.FromDecimal(Arg.Value.AsDecimal.Abs);
TScalar.TKind.Ordinal: Result := TScalar.FromInt64(System.Abs(Arg.Value.AsInt64));
TScalar.TKind.Float: Result := TScalar.FromDouble(System.Abs(Arg.Value.AsDouble));
else
// This case should not be reached if the wrapper validation is correct.
raise EArgumentException.Create('Abs requires a numeric argument.');
end;
end;
@@ -74,10 +70,8 @@ end;
class function TRtlFunctions.Trunc(const Arg: TScalar): TScalar;
begin
case Arg.Kind of
skInteger, skInt64: Result := Arg; // Trunc on an integer is a no-op
skSingle: Result := TScalar.FromInt64(System.Trunc(Arg.Value.AsSingle));
skDouble: Result := TScalar.FromInt64(System.Trunc(Arg.Value.AsDouble));
skDecimal: Result := TScalar.FromInt64(System.Trunc(Arg.Value.AsDecimal));
TScalar.TKind.Ordinal: Result := Arg; // Trunc on an integer is a no-op
TScalar.TKind.Float: Result := TScalar.FromInt64(System.Trunc(Arg.Value.AsDouble));
else
raise EArgumentException.Create('Trunc requires a numeric argument.');
end;
@@ -86,10 +80,8 @@ end;
class function TRtlFunctions.Ceil(const Arg: TScalar): TScalar;
begin
case Arg.Kind of
skInteger, skInt64: Result := Arg; // Ceil on an integer is a no-op
skSingle: Result := TScalar.FromInt64(System.Math.Ceil(Arg.Value.AsSingle));
skDouble: Result := TScalar.FromInt64(System.Math.Ceil(Arg.Value.AsDouble));
skDecimal: Result := TScalar.FromInt64(System.Math.Ceil(Double(Arg.Value.AsDecimal)));
TScalar.TKind.Ordinal: Result := Arg; // Ceil on an integer is a no-op
TScalar.TKind.Float: Result := TScalar.FromInt64(System.Math.Ceil(Arg.Value.AsDouble));
else
raise EArgumentException.Create('Ceil requires a numeric argument.');
end;
@@ -98,10 +90,8 @@ end;
class function TRtlFunctions.Floor(const Arg: TScalar): TScalar;
begin
case Arg.Kind of
skInteger, skInt64: Result := Arg; // Floor on an integer is a no-op
skSingle: Result := TScalar.FromInt64(System.Math.Floor(Arg.Value.AsSingle));
skDouble: Result := TScalar.FromInt64(System.Math.Floor(Arg.Value.AsDouble));
skDecimal: Result := TScalar.FromInt64(System.Math.Floor(Double(Arg.Value.AsDecimal)));
TScalar.TKind.Ordinal: Result := Arg; // Floor on an integer is a no-op
TScalar.TKind.Float: Result := TScalar.FromInt64(System.Math.Floor(Arg.Value.AsDouble));
else
raise EArgumentException.Create('Floor requires a numeric argument.');
end;
@@ -110,11 +100,8 @@ end;
class function TRtlFunctions.Sign(const Arg: TScalar): TScalar;
begin
case Arg.Kind of
skInteger: Result := TScalar.FromInteger(System.Math.Sign(Arg.Value.AsInteger));
skInt64: Result := TScalar.FromInteger(System.Math.Sign(Arg.Value.AsInt64));
skSingle: Result := TScalar.FromInteger(System.Math.Sign(Arg.Value.AsSingle));
skDouble: Result := TScalar.FromInteger(System.Math.Sign(Arg.Value.AsDouble));
skDecimal: Result := TScalar.FromInteger(Arg.Value.AsDecimal.Sign);
TScalar.TKind.Ordinal: Result := TScalar.FromInt64(System.Math.Sign(Arg.Value.AsInt64));
TScalar.TKind.Float: Result := TScalar.FromInt64(System.Math.Sign(Arg.Value.AsDouble));
else
raise EArgumentException.Create('Sign requires a numeric argument.');
end;
@@ -145,13 +132,10 @@ begin
raise EArgumentException.Create('This memoized function can only be called with a single scalar argument.');
argScalar := AArgs[0].AsScalar;
if not (argScalar.Kind in [skInteger, skInt64]) then
raise EArgumentException.Create('This memoized function expects an integer argument for caching.');
if argScalar.Kind <> TScalar.TKind.Ordinal then
raise EArgumentException.Create('This memoized function expects an ordinal argument for caching.');
if argScalar.Kind = skInteger then
key := argScalar.Value.AsInteger
else
key := argScalar.Value.AsInt64;
key := argScalar.Value.AsInt64;
var cache := cCache.AsObject as TDictionary<Int64, TDataValue>;
@@ -248,7 +232,9 @@ begin
begin
item := sourceSeries.Items[i];
predicateResult := predicateFunc([TDataValue(item)]);
if (predicateResult.Kind = vkScalar) and (predicateResult.AsScalar.Value.AsBoolean) then
if (predicateResult.Kind = vkScalar)
and (predicateResult.AsScalar.Kind = TScalar.TKind.Ordinal)
and (predicateResult.AsScalar.Value.AsInt64 <> 0) then
matchingIndices.Add(i);
end;
@@ -262,7 +248,7 @@ begin
var
idx: Integer;
begin
idx := AArgs[0].AsScalar.Value.AsInteger;
idx := AArgs[0].AsScalar.Value.AsInt64;
Result := TDataValue(sourceSeries.Items[idx]);
end;
@@ -297,14 +283,16 @@ begin
item := sourceSeries.Items[i];
predicateResult := predicateFunc([TDataValue(item)]);
if (predicateResult.Kind = vkScalar) and (predicateResult.AsScalar.Value.AsBoolean) then
if (predicateResult.Kind = vkScalar)
and (predicateResult.AsScalar.Kind = TScalar.TKind.Ordinal)
and (predicateResult.AsScalar.Value.AsInt64 <> 0) then
begin
Result := TScalar.FromBoolean(True);
Result := TScalar.FromInt64(1);
exit;
end;
end;
Result := TScalar.FromBoolean(False);
Result := TScalar.FromInt64(0);
end;
end.