RTL: Sqrt & Pow
This commit is contained in:
@@ -41,8 +41,8 @@
|
|||||||
(fn [len]
|
(fn [len]
|
||||||
(do
|
(do
|
||||||
;; Konstanten vorberechnen
|
;; Konstanten vorberechnen
|
||||||
(def half-len (Round (/ len 2)))
|
(def half-len (round (/ len 2)))
|
||||||
(def sqrt-len (Round (sqrt len)))
|
(def sqrt-len (round (sqrt len)))
|
||||||
|
|
||||||
;; !!! WICHTIG !!!
|
;; !!! WICHTIG !!!
|
||||||
;; HMA benötigt eine Glättung der Differenz.
|
;; HMA benötigt eine Glättung der Differenz.
|
||||||
|
|||||||
@@ -123,54 +123,54 @@ type
|
|||||||
|
|
||||||
// --- Math Functions ---
|
// --- Math Functions ---
|
||||||
|
|
||||||
[TRtlExport('Abs', Pure)]
|
[TRtlExport('abs', Pure)]
|
||||||
[AstDoc('Returns the absolute value of a number.')]
|
[AstDoc('Returns the absolute value of a number.')]
|
||||||
[AstSignature('(number) -> number')]
|
[AstSignature('(number) -> number')]
|
||||||
class function Abs(const Arg: TScalar): TScalar; static;
|
class function Abs(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Round', Pure)]
|
[TRtlExport('round', Pure)]
|
||||||
[AstDoc('Rounds a float to the nearest integer.')]
|
[AstDoc('Rounds a float to the nearest integer.')]
|
||||||
[AstSignature('(number) -> number')]
|
[AstSignature('(number) -> number')]
|
||||||
class function Round(const Arg: TScalar): TScalar; static;
|
class function Round(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Trunc', Pure)]
|
[TRtlExport('trunc', Pure)]
|
||||||
[AstDoc('Returns the integer part of a float.')]
|
[AstDoc('Returns the integer part of a float.')]
|
||||||
[AstSignature('(number) -> number')]
|
[AstSignature('(number) -> number')]
|
||||||
class function Trunc(const Arg: TScalar): TScalar; static;
|
class function Trunc(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Ceil', Pure)]
|
[TRtlExport('ceil', Pure)]
|
||||||
[AstDoc('Returns the smallest integer >= the argument.')]
|
[AstDoc('Returns the smallest integer >= the argument.')]
|
||||||
[AstSignature('(number) -> number')]
|
[AstSignature('(number) -> number')]
|
||||||
class function Ceil(const Arg: TScalar): TScalar; static;
|
class function Ceil(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Floor', Pure)]
|
[TRtlExport('floor', Pure)]
|
||||||
[AstDoc('Returns the largest integer <= the argument.')]
|
[AstDoc('Returns the largest integer <= the argument.')]
|
||||||
[AstSignature('(number) -> number')]
|
[AstSignature('(number) -> number')]
|
||||||
class function Floor(const Arg: TScalar): TScalar; static;
|
class function Floor(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Sign', Pure)]
|
[TRtlExport('sign', Pure)]
|
||||||
[AstDoc('Returns -1 for negative, 1 for positive, 0 for zero.')]
|
[AstDoc('Returns -1 for negative, 1 for positive, 0 for zero.')]
|
||||||
[AstSignature('(number) -> number')]
|
[AstSignature('(number) -> number')]
|
||||||
class function Sign(const Arg: TScalar): TScalar; static;
|
class function Sign(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Sqrt', Pure)]
|
[TRtlExport('sqrt', Pure)]
|
||||||
[AstDoc('Returns the square root of a number.')]
|
[AstDoc('Returns the square root of a number.')]
|
||||||
[AstSignature('(number) -> number')]
|
[AstSignature('(number) -> number')]
|
||||||
class function Sqrt(const Arg: TScalar): TScalar; static;
|
class function Sqrt(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Pow', Pure)]
|
[TRtlExport('pow', Pure)]
|
||||||
[AstDoc('Returns Base raised to the power of Exponent.')]
|
[AstDoc('Returns Base raised to the power of Exponent.')]
|
||||||
[AstSignature('(number, number) -> number')]
|
[AstSignature('(number, number) -> number')]
|
||||||
class function Pow(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Pow(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
// --- DateTime ---
|
// --- DateTime ---
|
||||||
|
|
||||||
[TRtlExport('Now', Impure)]
|
[TRtlExport('now', Impure)]
|
||||||
[AstDoc('Returns the current system timestamp.')]
|
[AstDoc('Returns the current system timestamp.')]
|
||||||
[AstSignature('() -> datetime')]
|
[AstSignature('() -> datetime')]
|
||||||
class function Now(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Now(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Date', Impure)]
|
[TRtlExport('date', Impure)]
|
||||||
[AstDoc('Returns the current date or constructs a date from Y, M, D.')]
|
[AstDoc('Returns the current date or constructs a date from Y, M, D.')]
|
||||||
[AstSignature('() -> datetime')]
|
[AstSignature('() -> datetime')]
|
||||||
[AstSignature('(number, number, number) -> datetime')]
|
[AstSignature('(number, number, number) -> datetime')]
|
||||||
@@ -178,27 +178,27 @@ type
|
|||||||
|
|
||||||
// --- Functional / Series ---
|
// --- Functional / Series ---
|
||||||
|
|
||||||
[TRtlExport('Memoize', Pure)]
|
[TRtlExport('memoize', Pure)]
|
||||||
[AstDoc('Creates a memoized version of a function for performance.')]
|
[AstDoc('Creates a memoized version of a function for performance.')]
|
||||||
[AstSignature('((any) -> any) -> ((any) -> any)')]
|
[AstSignature('((any) -> any) -> ((any) -> any)')]
|
||||||
class function Memoize(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Memoize(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Map', Pure)]
|
[TRtlExport('map', Pure)]
|
||||||
[AstDoc('Applies a function to every element of a series.')]
|
[AstDoc('Applies a function to every element of a series.')]
|
||||||
[AstSignature('(series, (any) -> any) -> series')]
|
[AstSignature('(series, (any) -> any) -> series')]
|
||||||
class function Map(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Map(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Reduce', Pure)]
|
[TRtlExport('reduce', Pure)]
|
||||||
[AstDoc('Collapses a series into a single value using a reducer function.')]
|
[AstDoc('Collapses a series into a single value using a reducer function.')]
|
||||||
[AstSignature('(series, any, (any, any) -> any) -> any')]
|
[AstSignature('(series, any, (any, any) -> any) -> any')]
|
||||||
class function Reduce(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Reduce(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Where', Pure)]
|
[TRtlExport('where', Pure)]
|
||||||
[AstDoc('Filters a series based on a predicate function.')]
|
[AstDoc('Filters a series based on a predicate function.')]
|
||||||
[AstSignature('(series, (any) -> boolean) -> series')]
|
[AstSignature('(series, (any) -> boolean) -> series')]
|
||||||
class function Where(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Where(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Any', Pure)]
|
[TRtlExport('any', Pure)]
|
||||||
[AstDoc('Returns true if at least one element satisfies the predicate.')]
|
[AstDoc('Returns true if at least one element satisfies the predicate.')]
|
||||||
[AstSignature('(series, (any) -> boolean) -> boolean')]
|
[AstSignature('(series, (any) -> boolean) -> boolean')]
|
||||||
class function Any(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Any(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
@@ -324,31 +324,31 @@ type
|
|||||||
[TRtlExport('not', Pure)]
|
[TRtlExport('not', Pure)]
|
||||||
class function Not_Ordinal_Ordinal(A: Int64): Int64; static;
|
class function Not_Ordinal_Ordinal(A: Int64): Int64; static;
|
||||||
|
|
||||||
[TRtlExport('Abs', Pure)]
|
[TRtlExport('abs', Pure)]
|
||||||
class function Abs_Ordinal_Ordinal(A: Int64): Int64; static;
|
class function Abs_Ordinal_Ordinal(A: Int64): Int64; static;
|
||||||
[TRtlExport('Abs', Pure)]
|
[TRtlExport('abs', Pure)]
|
||||||
class function Abs_Float_Float(A: Double): Double; static;
|
class function Abs_Float_Float(A: Double): Double; static;
|
||||||
[TRtlExport('Round', Pure)]
|
[TRtlExport('round', Pure)]
|
||||||
class function Round_Ordinal_Ordinal(A: Int64): Int64; static;
|
class function Round_Ordinal_Ordinal(A: Int64): Int64; static;
|
||||||
[TRtlExport('Round', Pure)]
|
[TRtlExport('round', Pure)]
|
||||||
class function Round_Float_Ordinal(A: Double): Int64; static;
|
class function Round_Float_Ordinal(A: Double): Int64; static;
|
||||||
[TRtlExport('Trunc', Pure)]
|
[TRtlExport('trunc', Pure)]
|
||||||
class function Trunc_Ordinal_Ordinal(A: Int64): Int64; static;
|
class function Trunc_Ordinal_Ordinal(A: Int64): Int64; static;
|
||||||
[TRtlExport('Trunc', Pure)]
|
[TRtlExport('trunc', Pure)]
|
||||||
class function Trunc_Float_Ordinal(A: Double): Int64; static;
|
class function Trunc_Float_Ordinal(A: Double): Int64; static;
|
||||||
|
|
||||||
[TRtlExport('Sqrt', Pure)]
|
[TRtlExport('sqrt', Pure)]
|
||||||
class function Sqrt_Ordinal_Float(A: Int64): Double; static;
|
class function Sqrt_Ordinal_Float(A: Int64): Double; static;
|
||||||
[TRtlExport('Sqrt', Pure)]
|
[TRtlExport('sqrt', Pure)]
|
||||||
class function Sqrt_Float_Float(A: Double): Double; static;
|
class function Sqrt_Float_Float(A: Double): Double; static;
|
||||||
|
|
||||||
[TRtlExport('Pow', Pure)]
|
[TRtlExport('pow', Pure)]
|
||||||
class function Pow_Ordinal_Ordinal_Float(A, B: Int64): Double; static;
|
class function Pow_Ordinal_Ordinal_Float(A, B: Int64): Double; static;
|
||||||
[TRtlExport('Pow', Pure)]
|
[TRtlExport('pow', Pure)]
|
||||||
class function Pow_Float_Float_Float(A, B: Double): Double; static;
|
class function Pow_Float_Float_Float(A, B: Double): Double; static;
|
||||||
[TRtlExport('Pow', Pure)]
|
[TRtlExport('pow', Pure)]
|
||||||
class function Pow_Ordinal_Float_Float(A: Int64; B: Double): Double; static;
|
class function Pow_Ordinal_Float_Float(A: Int64; B: Double): Double; static;
|
||||||
[TRtlExport('Pow', Pure)]
|
[TRtlExport('pow', Pure)]
|
||||||
class function Pow_Float_Ordinal_Float(A: Double; B: Int64): Double; static;
|
class function Pow_Float_Ordinal_Float(A: Double; B: Int64): Double; static;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ var
|
|||||||
Expected: TDateTime;
|
Expected: TDateTime;
|
||||||
begin
|
begin
|
||||||
// Act
|
// Act
|
||||||
Res := FEnv.Run(TAstScript.Parse('(Date 2025 11 24)'));
|
Res := FEnv.Run(TAstScript.Parse('(date 2025 11 24)'));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.AreEqual(TDataValueKind.vkScalar, Res.Kind, 'Result should be scalar');
|
Assert.AreEqual(TDataValueKind.vkScalar, Res.Kind, 'Result should be scalar');
|
||||||
@@ -85,7 +85,7 @@ begin
|
|||||||
Sleep(1);
|
Sleep(1);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
Res := FEnv.Run(TAstScript.Parse('(Now)'));
|
Res := FEnv.Run(TAstScript.Parse('(now)'));
|
||||||
|
|
||||||
After := System.SysUtils.Now;
|
After := System.SysUtils.Now;
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ var
|
|||||||
Res: TDataValue;
|
Res: TDataValue;
|
||||||
begin
|
begin
|
||||||
// (> (Date y1 m1 d1) (Date y2 m2 d2))
|
// (> (Date y1 m1 d1) (Date y2 m2 d2))
|
||||||
Script := Format('(> (Date %d %d %d) (Date %d %d %d))', [Y1, M1, D1, Y2, M2, D2]);
|
Script := Format('(> (date %d %d %d) (date %d %d %d))', [Y1, M1, D1, Y2, M2, D2]);
|
||||||
|
|
||||||
Res := FEnv.Run(TAstScript.Parse(Script));
|
Res := FEnv.Run(TAstScript.Parse(Script));
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ var
|
|||||||
Res: TDataValue;
|
Res: TDataValue;
|
||||||
begin
|
begin
|
||||||
// (= (Date 2023 10 10) (Date 2023 10 10))
|
// (= (Date 2023 10 10) (Date 2023 10 10))
|
||||||
Res := FEnv.Run(TAstScript.Parse('(= (Date 2023 10 10) (Date 2023 10 10))'));
|
Res := FEnv.Run(TAstScript.Parse('(= (date 2023 10 10) (date 2023 10 10))'));
|
||||||
|
|
||||||
Assert.AreEqual(TScalar.TKind.Boolean, Res.AsScalar.Kind);
|
Assert.AreEqual(TScalar.TKind.Boolean, Res.AsScalar.Kind);
|
||||||
Assert.AreEqual(Int64(1), Res.AsScalar.Value.AsInt64);
|
Assert.AreEqual(Int64(1), Res.AsScalar.Value.AsInt64);
|
||||||
@@ -132,7 +132,7 @@ var
|
|||||||
begin
|
begin
|
||||||
// (if (Date 2023 1 1) "yes" "no")
|
// (if (Date 2023 1 1) "yes" "no")
|
||||||
// Checks if IsTruthy correctly handles TKind.DateTime
|
// Checks if IsTruthy correctly handles TKind.DateTime
|
||||||
Res := FEnv.Run(TAstScript.Parse('(if (Date 2023 1 1) "yes" "no")'));
|
Res := FEnv.Run(TAstScript.Parse('(if (date 2023 1 1) "yes" "no")'));
|
||||||
|
|
||||||
Assert.AreEqual(TDataValueKind.vkText, Res.Kind);
|
Assert.AreEqual(TDataValueKind.vkText, Res.Kind);
|
||||||
Assert.AreEqual('yes', Res.AsText);
|
Assert.AreEqual('yes', Res.AsText);
|
||||||
@@ -151,7 +151,7 @@ begin
|
|||||||
InputDate := EncodeDate(2023, 11, 24);
|
InputDate := EncodeDate(2023, 11, 24);
|
||||||
Expected := System.Round(InputDate);
|
Expected := System.Round(InputDate);
|
||||||
|
|
||||||
Res := FEnv.Run(TAstScript.Parse('(Round (Date 2023 11 24))'));
|
Res := FEnv.Run(TAstScript.Parse('(round (date 2023 11 24))'));
|
||||||
|
|
||||||
Assert.AreEqual(TScalar.TKind.Ordinal, Res.AsScalar.Kind);
|
Assert.AreEqual(TScalar.TKind.Ordinal, Res.AsScalar.Kind);
|
||||||
Assert.AreEqual(Expected, Res.AsScalar.Value.AsInt64);
|
Assert.AreEqual(Expected, Res.AsScalar.Value.AsInt64);
|
||||||
|
|||||||
@@ -128,8 +128,8 @@ procedure TTestMycAstRTL.RTL_Registration_SymbolsArePresent;
|
|||||||
begin
|
begin
|
||||||
Assert.AreNotEqual(TAddressKind.akUnresolved, FScope.Resolve('div').Kind);
|
Assert.AreNotEqual(TAddressKind.akUnresolved, FScope.Resolve('div').Kind);
|
||||||
Assert.AreNotEqual(TAddressKind.akUnresolved, FScope.Resolve('mod').Kind);
|
Assert.AreNotEqual(TAddressKind.akUnresolved, FScope.Resolve('mod').Kind);
|
||||||
Assert.AreNotEqual(TAddressKind.akUnresolved, FScope.Resolve('Date').Kind);
|
Assert.AreNotEqual(TAddressKind.akUnresolved, FScope.Resolve('date').Kind);
|
||||||
Assert.AreNotEqual(TAddressKind.akUnresolved, FScope.Resolve('Round').Kind);
|
Assert.AreNotEqual(TAddressKind.akUnresolved, FScope.Resolve('round').Kind);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestMycAstRTL.RTL_Math_Float(const Op: string; A, B, Expected: Double);
|
procedure TTestMycAstRTL.RTL_Math_Float(const Op: string; A, B, Expected: Double);
|
||||||
@@ -164,7 +164,7 @@ procedure TTestMycAstRTL.RTL_Round_Works(A: Double; Expected: Int64);
|
|||||||
var
|
var
|
||||||
res: TDataValue;
|
res: TDataValue;
|
||||||
begin
|
begin
|
||||||
res := Call('Round', [ValF(A)]);
|
res := Call('round', [ValF(A)]);
|
||||||
Assert.AreEqual(TScalar.TKind.Ordinal, res.AsScalar.Kind);
|
Assert.AreEqual(TScalar.TKind.Ordinal, res.AsScalar.Kind);
|
||||||
Assert.AreEqual(Expected, res.AsScalar.Value.AsInt64);
|
Assert.AreEqual(Expected, res.AsScalar.Value.AsInt64);
|
||||||
end;
|
end;
|
||||||
@@ -192,7 +192,7 @@ var
|
|||||||
begin
|
begin
|
||||||
// 1. Test Date(Y, M, D)
|
// 1. Test Date(Y, M, D)
|
||||||
expectedDate := EncodeDate(2023, 10, 5);
|
expectedDate := EncodeDate(2023, 10, 5);
|
||||||
d := Call('Date', [ValI(2023), ValI(10), ValI(5)]);
|
d := Call('date', [ValI(2023), ValI(10), ValI(5)]);
|
||||||
|
|
||||||
Assert.AreEqual(TScalar.TKind.DateTime, d.AsScalar.Kind);
|
Assert.AreEqual(TScalar.TKind.DateTime, d.AsScalar.Kind);
|
||||||
Assert.AreEqual(expectedDate, d.AsScalar.Value.AsDouble, 0.001);
|
Assert.AreEqual(expectedDate, d.AsScalar.Value.AsDouble, 0.001);
|
||||||
|
|||||||
Reference in New Issue
Block a user