RTL refactoring
This commit is contained in:
@@ -0,0 +1,270 @@
|
||||
unit Myc.Ast.RTL.Math;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Math,
|
||||
Myc.Data.Scalar,
|
||||
Myc.Data.Value,
|
||||
Myc.Ast.Attributes;
|
||||
|
||||
type
|
||||
TRtlMathFunctions = record
|
||||
public
|
||||
// --- Math Functions ---
|
||||
|
||||
[TRtlExport('abs', Pure)]
|
||||
[AstDoc('Returns the absolute value of a number.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Abs(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('round', Pure)]
|
||||
[AstDoc('Rounds a float to the nearest integer.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Round(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('trunc', Pure)]
|
||||
[AstDoc('Returns the integer part of a float.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Trunc(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('ceil', Pure)]
|
||||
[AstDoc('Returns the smallest integer >= the argument.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Ceil(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('floor', Pure)]
|
||||
[AstDoc('Returns the largest integer <= the argument.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Floor(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('sign', Pure)]
|
||||
[AstDoc('Returns -1 for negative, 1 for positive, 0 for zero.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Sign(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('sqrt', Pure)]
|
||||
[AstDoc('Returns the square root of a number.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Sqrt(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('pow', Pure)]
|
||||
[AstDoc('Returns Base raised to the power of Exponent.')]
|
||||
[AstSignature('(number, number) -> number')]
|
||||
class function Pow(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlExport('random', Impure)]
|
||||
[AstDoc('Returns a random number. No args: [0..1). Arg N: Integer [0..N).')]
|
||||
[AstSignature('() -> float')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Random(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
// --- Static Specializations ---
|
||||
|
||||
[TRtlExport('abs', Pure)]
|
||||
class function Abs_Ordinal_Ordinal(A: Int64): Int64; static;
|
||||
[TRtlExport('abs', Pure)]
|
||||
class function Abs_Float_Float(A: Double): Double; static;
|
||||
|
||||
[TRtlExport('round', Pure)]
|
||||
class function Round_Ordinal_Ordinal(A: Int64): Int64; static;
|
||||
[TRtlExport('round', Pure)]
|
||||
class function Round_Float_Ordinal(A: Double): Int64; static;
|
||||
|
||||
[TRtlExport('trunc', Pure)]
|
||||
class function Trunc_Ordinal_Ordinal(A: Int64): Int64; static;
|
||||
[TRtlExport('trunc', Pure)]
|
||||
class function Trunc_Float_Ordinal(A: Double): Int64; static;
|
||||
|
||||
[TRtlExport('sqrt', Pure)]
|
||||
class function Sqrt_Ordinal_Float(A: Int64): Double; static;
|
||||
[TRtlExport('sqrt', Pure)]
|
||||
class function Sqrt_Float_Float(A: Double): Double; static;
|
||||
|
||||
[TRtlExport('pow', Pure)]
|
||||
class function Pow_Ordinal_Ordinal_Float(A, B: Int64): Double; static;
|
||||
[TRtlExport('pow', Pure)]
|
||||
class function Pow_Float_Float_Float(A, B: Double): Double; static;
|
||||
[TRtlExport('pow', Pure)]
|
||||
class function Pow_Ordinal_Float_Float(A: Int64; B: Double): Double; static;
|
||||
[TRtlExport('pow', Pure)]
|
||||
class function Pow_Float_Ordinal_Float(A: Double; B: Int64): Double; static;
|
||||
|
||||
[TRtlExport('random', Impure)]
|
||||
class function Random_Void_Float: Double; static;
|
||||
[TRtlExport('random', Impure)]
|
||||
class function Random_Ordinal_Ordinal(Limit: Int64): Int64; static;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TRtlMathFunctions }
|
||||
|
||||
class function TRtlMathFunctions.Abs(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
case Arg.Kind of
|
||||
TScalar.TKind.Ordinal: Result := TScalar.FromInt64(System.Abs(Arg.Value.AsInt64));
|
||||
TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromDouble(System.Abs(Arg.Value.AsDouble));
|
||||
else
|
||||
raise EArgumentException.Create('Abs requires a numeric argument.');
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Round(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
case Arg.Kind of
|
||||
TScalar.TKind.Ordinal: Result := Arg;
|
||||
TScalar.TKind.Float, TScalar.TKind.DateTime:
|
||||
begin
|
||||
var val: Double := Arg.Value.AsDouble;
|
||||
Result := TScalar.FromInt64(System.Round(val));
|
||||
end;
|
||||
else
|
||||
raise EArgumentException.Create('Round requires a numeric argument.');
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Trunc(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
case Arg.Kind of
|
||||
TScalar.TKind.Ordinal: Result := Arg;
|
||||
TScalar.TKind.Float, TScalar.TKind.DateTime:
|
||||
begin
|
||||
var val: Double := Arg.Value.AsDouble;
|
||||
Result := TScalar.FromInt64(System.Trunc(val));
|
||||
end;
|
||||
else
|
||||
raise EArgumentException.Create('Trunc requires a numeric argument.');
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Ceil(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
case Arg.Kind of
|
||||
TScalar.TKind.Ordinal: Result := Arg;
|
||||
TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromInt64(System.Math.Ceil(Arg.Value.AsDouble));
|
||||
else
|
||||
raise EArgumentException.Create('Ceil requires a numeric argument.');
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Floor(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
case Arg.Kind of
|
||||
TScalar.TKind.Ordinal: Result := Arg;
|
||||
TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromInt64(System.Math.Floor(Arg.Value.AsDouble));
|
||||
else
|
||||
raise EArgumentException.Create('Floor requires a numeric argument.');
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Sign(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
case Arg.Kind of
|
||||
TScalar.TKind.Ordinal: Result := TScalar.FromInt64(System.Math.Sign(Arg.Value.AsInt64));
|
||||
TScalar.TKind.Float, TScalar.TKind.DateTime: Result := TScalar.FromInt64(System.Math.Sign(Arg.Value.AsDouble));
|
||||
else
|
||||
raise EArgumentException.Create('Sign requires a numeric argument.');
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Sqrt(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
var val: Double := Arg; // Implicit cast handles Ordinal and Float
|
||||
Result := TScalar.FromDouble(System.Sqrt(val));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Pow(const Args: TArray<TDataValue>): TDataValue;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Pow requires 2 arguments (Base, Exponent).');
|
||||
|
||||
var baseVal: Double := Args[0].AsScalar;
|
||||
var expVal: Double := Args[1].AsScalar;
|
||||
Result := TScalar.FromDouble(System.Math.Power(baseVal, expVal));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Random(const Args: TArray<TDataValue>): TDataValue;
|
||||
begin
|
||||
if Length(Args) = 0 then
|
||||
Result := TScalar.FromDouble(System.Random)
|
||||
else if (Length(Args) = 1) and (Args[0].AsScalar.Kind = TScalar.TKind.Ordinal) then
|
||||
Result := TScalar.FromInt64(System.Random(Integer(Args[0].AsScalar.Value.AsInt64)))
|
||||
else
|
||||
raise EArgumentException.Create('Random expects 0 arguments or 1 integer argument.');
|
||||
end;
|
||||
|
||||
// --- Static Specializations ---
|
||||
|
||||
class function TRtlMathFunctions.Abs_Ordinal_Ordinal(A: Int64): Int64;
|
||||
begin
|
||||
Result := System.Abs(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Abs_Float_Float(A: Double): Double;
|
||||
begin
|
||||
Result := System.Abs(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Round_Ordinal_Ordinal(A: Int64): Int64;
|
||||
begin
|
||||
Result := A;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Round_Float_Ordinal(A: Double): Int64;
|
||||
begin
|
||||
Result := System.Round(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Trunc_Ordinal_Ordinal(A: Int64): Int64;
|
||||
begin
|
||||
Result := A;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Trunc_Float_Ordinal(A: Double): Int64;
|
||||
begin
|
||||
Result := System.Trunc(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Sqrt_Ordinal_Float(A: Int64): Double;
|
||||
begin
|
||||
Result := System.Sqrt(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Sqrt_Float_Float(A: Double): Double;
|
||||
begin
|
||||
Result := System.Sqrt(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Pow_Ordinal_Ordinal_Float(A, B: Int64): Double;
|
||||
begin
|
||||
Result := System.Math.Power(A, B);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Pow_Float_Float_Float(A, B: Double): Double;
|
||||
begin
|
||||
Result := System.Math.Power(A, B);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Pow_Ordinal_Float_Float(A: Int64; B: Double): Double;
|
||||
begin
|
||||
Result := System.Math.Power(A, B);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Pow_Float_Ordinal_Float(A: Double; B: Int64): Double;
|
||||
begin
|
||||
Result := System.Math.Power(A, B);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Random_Void_Float: Double;
|
||||
begin
|
||||
Result := System.Random;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Random_Ordinal_Ordinal(Limit: Int64): Int64;
|
||||
begin
|
||||
Result := System.Random(Limit);
|
||||
end;
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user