unit Myc.Ast.RTL.Core; interface uses System.SysUtils, System.Math, Myc.Data.Scalar, Myc.Data.Value, Myc.Ast.Attributes; type TRtlCoreFunctions = record public // --- Constants --- [TRtlConst('false')] [AstDoc('Boolean false.')] class function CFalse: Boolean; static; [TRtlConst('true')] [AstDoc('Boolean true.')] class function CTrue: Boolean; static; [TRtlConst('NaN')] [AstDoc('Not a Number (IEEE 754).')] class function CNaN: Double; static; // --- Arithmetic Operators --- [TRtlExport('+', Pure)] [AstDoc('Adds two numbers or concatenates two strings.')] [AstSignature('(number, number) -> number')] [AstSignature('(string, string) -> string')] class function Add(const Args: TArray): TDataValue; overload; static; [TRtlExport('-', Pure)] [AstDoc('Subtracts B from A, or negates A if called with one argument.')] [AstSignature('(number, number) -> number')] [AstSignature('(number) -> number')] class function Subtract(const Args: TArray): TDataValue; static; [TRtlExport('*', Pure)] [AstDoc('Multiplies two numbers.')] [AstSignature('(number, number) -> number')] class function Multiply(const Args: TArray): TDataValue; static; [TRtlExport('/', Pure)] [AstDoc('Divides A by B. Returns NaN on division by zero.')] [AstSignature('(number, number) -> number')] class function Divide(const Args: TArray): TDataValue; static; [TRtlExport('div', Pure)] [AstDoc('Performs integer division. Returns NaN on division by zero.')] [AstSignature('(number, number) -> number')] class function IntDivide(const Args: TArray): TDataValue; static; [TRtlExport('mod', Pure)] [AstDoc('Returns the remainder of integer division. Returns NaN on division by zero.')] [AstSignature('(number, number) -> number')] class function Modulus(const Args: TArray): TDataValue; static; // --- Comparison Operators --- [TRtlExport('=', Pure)] [AstDoc('Checks if A is equal to B.')] [AstSignature('(any, any) -> boolean')] class function Equal(const Args: TArray): TDataValue; static; [TRtlExport('<>', Pure)] [AstDoc('Checks if A is not equal to B.')] [AstSignature('(any, any) -> boolean')] class function NotEqual(const Args: TArray): TDataValue; static; [TRtlExport('<', Pure)] [AstDoc('Checks if A is less than B.')] [AstSignature('(number, number) -> boolean')] class function LessThan(const Args: TArray): TDataValue; static; [TRtlExport('<=', Pure)] [AstDoc('Checks if A is less than or equal to B.')] [AstSignature('(number, number) -> boolean')] class function LessThanOrEqual(const Args: TArray): TDataValue; static; [TRtlExport('>', Pure)] [AstDoc('Checks if A is greater than B.')] [AstSignature('(number, number) -> boolean')] class function GreaterThan(const Args: TArray): TDataValue; static; [TRtlExport('>=', Pure)] [AstDoc('Checks if A is greater than or equal to B.')] [AstSignature('(number, number) -> boolean')] class function GreaterThanOrEqual(const Args: TArray): TDataValue; static; // --- Logic / Bitwise Operators --- [TRtlExport('not', Pure)] [AstDoc('Logical or bitwise NOT operation.')] [AstSignature('(boolean) -> boolean')] [AstSignature('(number) -> number')] class function LogicalNot(const Args: TArray): TDataValue; static; [TRtlExport('and', Pure)] [AstDoc('Logical or bitwise AND operation.')] [AstSignature('(boolean, boolean) -> boolean')] [AstSignature('(number, number) -> number')] class function BitwiseAnd(const Args: TArray): TDataValue; static; [TRtlExport('or', Pure)] [AstDoc('Logical or bitwise OR operation.')] [AstSignature('(boolean, boolean) -> boolean')] [AstSignature('(number, number) -> number')] class function BitwiseOr(const Args: TArray): TDataValue; static; [TRtlExport('xor', Pure)] [AstDoc('Logical or bitwise XOR operation.')] [AstSignature('(boolean, boolean) -> boolean')] [AstSignature('(number, number) -> number')] class function BitwiseXor(const Args: TArray): TDataValue; static; [TRtlExport('shl', Pure)] [AstDoc('Bitwise shift left.')] [AstSignature('(number, number) -> number')] class function LeftShift(const Args: TArray): TDataValue; static; [TRtlExport('shr', Pure)] [AstDoc('Bitwise shift right.')] [AstSignature('(number, number) -> number')] class function RightShift(const Args: TArray): TDataValue; static; // --- Static Specializations (Targets for TypeChecker/Specializer) --- [TRtlExport('+', Pure)] class function Add_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('+', Pure)] class function Add_Float_Float_Float(A, B: Double): Double; static; [TRtlExport('+', Pure)] class function Add_Ordinal_Float_Float(A: Int64; B: Double): Double; static; [TRtlExport('+', Pure)] class function Add_Float_Ordinal_Float(A: Double; B: Int64): Double; static; [TRtlExport('+', Pure)] class function Add_Text_Text_Text(const A: string; const B: string): string; static; [TRtlExport('-', Pure)] class function Subtract_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('-', Pure)] class function Subtract_Float_Float_Float(A, B: Double): Double; static; [TRtlExport('-', Pure)] class function Subtract_Ordinal_Float_Float(A: Int64; B: Double): Double; static; [TRtlExport('-', Pure)] class function Subtract_Float_Ordinal_Float(A: Double; B: Int64): Double; static; [TRtlExport('*', Pure)] class function Multiply_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('*', Pure)] class function Multiply_Float_Float_Float(A, B: Double): Double; static; [TRtlExport('*', Pure)] class function Multiply_Ordinal_Float_Float(A: Int64; B: Double): Double; static; [TRtlExport('*', Pure)] class function Multiply_Float_Ordinal_Float(A: Double; B: Int64): Double; static; [TRtlExport('/', Pure)] class function Divide_Ordinal_Ordinal_Float(A, B: Int64): Double; static; [TRtlExport('/', Pure)] class function Divide_Float_Float_Float(A, B: Double): Double; static; [TRtlExport('/', Pure)] class function Divide_Ordinal_Float_Float(A: Int64; B: Double): Double; static; [TRtlExport('/', Pure)] class function Divide_Float_Ordinal_Float(A: Double; B: Int64): Double; static; [TRtlExport('=', Pure)] class function Equal_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('=', Pure)] class function Equal_Float_Float_Ordinal(A, B: Double): Int64; static; [TRtlExport('=', Pure)] class function Equal_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; static; [TRtlExport('=', Pure)] class function Equal_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; static; [TRtlExport('=', Pure)] class function Equal_Keyword_Keyword_Ordinal(A, B: Int64): Int64; static; [TRtlExport('<>', Pure)] class function NotEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('<>', Pure)] class function NotEqual_Float_Float_Ordinal(A, B: Double): Int64; static; [TRtlExport('<>', Pure)] class function NotEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; static; [TRtlExport('<>', Pure)] class function NotEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; static; [TRtlExport('<>', Pure)] class function NotEqual_Keyword_Keyword_Ordinal(A, B: Int64): Int64; static; [TRtlExport('<', Pure)] class function Less_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('<', Pure)] class function Less_Float_Float_Ordinal(A, B: Double): Int64; static; [TRtlExport('<', Pure)] class function Less_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; static; [TRtlExport('<', Pure)] class function Less_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; static; [TRtlExport('<=', Pure)] class function LessOrEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('<=', Pure)] class function LessOrEqual_Float_Float_Ordinal(A, B: Double): Int64; static; [TRtlExport('<=', Pure)] class function LessOrEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; static; [TRtlExport('<=', Pure)] class function LessOrEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; static; [TRtlExport('>', Pure)] class function Greater_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('>', Pure)] class function Greater_Float_Float_Ordinal(A, B: Double): Int64; static; [TRtlExport('>', Pure)] class function Greater_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; static; [TRtlExport('>', Pure)] class function Greater_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; static; [TRtlExport('>=', Pure)] class function GreaterOrEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('>=', Pure)] class function GreaterOrEqual_Float_Float_Ordinal(A, B: Double): Int64; static; [TRtlExport('>=', Pure)] class function GreaterOrEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; static; [TRtlExport('>=', Pure)] class function GreaterOrEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; static; [TRtlExport('and', Pure)] class function And_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('or', Pure)] class function Or_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('xor', Pure)] class function Xor_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('shl', Pure)] class function Shl_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('shr', Pure)] class function Shr_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static; [TRtlExport('-', Pure)] class function Negate_Ordinal_Ordinal(A: Int64): Int64; static; [TRtlExport('-', Pure)] class function Negate_Float_Float(A: Double): Double; static; [TRtlExport('not', Pure)] class function Not_Ordinal_Ordinal(A: Int64): Int64; static; end; implementation { TRtlCoreFunctions - Constants } class function TRtlCoreFunctions.CNaN: Double; begin Result := System.Math.NaN; end; { TRtlCoreFunctions - Operator Implementations } class function TRtlCoreFunctions.Add(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator + requires 2 arguments.'); if (Args[0].Kind = vkText) and (Args[1].Kind = vkText) then Result := Args[0].AsText + Args[1].AsText else Result := Args[0].AsScalar + Args[1].AsScalar; end; class function TRtlCoreFunctions.Subtract(const Args: TArray): TDataValue; begin if Length(Args) = 1 then Result := -Args[0].AsScalar else if Length(Args) = 2 then Result := Args[0].AsScalar - Args[1].AsScalar else raise EArgumentException.Create('Operator - requires 1 or 2 arguments.'); end; class function TRtlCoreFunctions.Multiply(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator * requires 2 arguments.'); Result := Args[0].AsScalar * Args[1].AsScalar; end; class function TRtlCoreFunctions.Divide(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator / requires 2 arguments.'); Result := Args[0].AsScalar / Args[1].AsScalar; end; class function TRtlCoreFunctions.IntDivide(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator div requires 2 arguments.'); Result := Args[0].AsScalar div Args[1].AsScalar; end; class function TRtlCoreFunctions.Modulus(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator mod requires 2 arguments.'); Result := TScalar.FromInt64(Int64(Args[0].AsScalar) mod Args[1].AsScalar); end; class function TRtlCoreFunctions.Equal(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator = requires 2 arguments.'); Result := TScalar.FromBoolean(Args[0].AsScalar = Args[1].AsScalar); end; class function TRtlCoreFunctions.NotEqual(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator <> requires 2 arguments.'); Result := TScalar.FromBoolean(Args[0].AsScalar <> Args[1].AsScalar); end; class function TRtlCoreFunctions.LessThan(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator < requires 2 arguments.'); Result := TScalar.FromBoolean(Args[0].AsScalar < Args[1].AsScalar); end; class function TRtlCoreFunctions.LessThanOrEqual(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator <= requires 2 arguments.'); Result := TScalar.FromBoolean(Args[0].AsScalar <= Args[1].AsScalar); end; class function TRtlCoreFunctions.GreaterThan(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator > requires 2 arguments.'); Result := TScalar.FromBoolean(Args[0].AsScalar > Args[1].AsScalar); end; class function TRtlCoreFunctions.GreaterThanOrEqual(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator >= requires 2 arguments.'); Result := TScalar.FromBoolean(Args[0].AsScalar >= Args[1].AsScalar); end; // --- Logic / Bitwise --- class function TRtlCoreFunctions.LogicalNot(const Args: TArray): TDataValue; begin if Length(Args) <> 1 then raise EArgumentException.Create('Operator not requires 1 argument.'); Result := not Args[0].AsScalar; end; class function TRtlCoreFunctions.BitwiseAnd(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator and requires 2 arguments.'); Result := Args[0].AsScalar and Args[1].AsScalar; end; class function TRtlCoreFunctions.BitwiseOr(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator or requires 2 arguments.'); Result := Args[0].AsScalar or Args[1].AsScalar; end; class function TRtlCoreFunctions.BitwiseXor(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator xor requires 2 arguments.'); Result := Args[0].AsScalar xor Args[1].AsScalar; end; class function TRtlCoreFunctions.LeftShift(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator shl requires 2 arguments.'); Result := Args[0].AsScalar shl Args[1].AsScalar; end; class function TRtlCoreFunctions.RightShift(const Args: TArray): TDataValue; begin if Length(Args) <> 2 then raise EArgumentException.Create('Operator shr requires 2 arguments.'); Result := Args[0].AsScalar shr Args[1].AsScalar; end; // --- Static Specializations --- // Add class function TRtlCoreFunctions.Add_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := A + B; end; class function TRtlCoreFunctions.Add_Float_Float_Float(A, B: Double): Double; begin Result := A + B; end; class function TRtlCoreFunctions.Add_Ordinal_Float_Float(A: Int64; B: Double): Double; begin Result := A + B; end; class function TRtlCoreFunctions.Add_Float_Ordinal_Float(A: Double; B: Int64): Double; begin Result := A + B; end; class function TRtlCoreFunctions.Add_Text_Text_Text(const A: String; const B: String): String; begin Result := A + B; end; // Subtract class function TRtlCoreFunctions.Subtract_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := A - B; end; class function TRtlCoreFunctions.Subtract_Float_Float_Float(A, B: Double): Double; begin Result := A - B; end; class function TRtlCoreFunctions.Subtract_Ordinal_Float_Float(A: Int64; B: Double): Double; begin Result := A - B; end; class function TRtlCoreFunctions.Subtract_Float_Ordinal_Float(A: Double; B: Int64): Double; begin Result := A - B; end; // Multiply class function TRtlCoreFunctions.Multiply_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := A * B; end; class function TRtlCoreFunctions.Multiply_Float_Float_Float(A, B: Double): Double; begin Result := A * B; end; class function TRtlCoreFunctions.Multiply_Ordinal_Float_Float(A: Int64; B: Double): Double; begin Result := A * B; end; class function TRtlCoreFunctions.Multiply_Float_Ordinal_Float(A: Double; B: Int64): Double; begin Result := A * B; end; // Divide - Updated to return NaN on div0 class function TRtlCoreFunctions.Divide_Ordinal_Ordinal_Float(A, B: Int64): Double; begin Result := A / B; end; class function TRtlCoreFunctions.Divide_Float_Float_Float(A, B: Double): Double; begin if B = 0.0 then Result := NaN else Result := A / B; end; class function TRtlCoreFunctions.Divide_Ordinal_Float_Float(A: Int64; B: Double): Double; begin if B = 0.0 then Result := NaN else Result := A / B; end; class function TRtlCoreFunctions.Divide_Float_Ordinal_Float(A: Double; B: Int64): Double; begin Result := A / B; end; // Comparisons class function TRtlCoreFunctions.Equal_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := Ord(A = B); end; class function TRtlCoreFunctions.Equal_Float_Float_Ordinal(A, B: Double): Int64; begin Result := Ord(A = B); end; class function TRtlCoreFunctions.Equal_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; begin Result := Ord(A = B); end; class function TRtlCoreFunctions.Equal_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; begin Result := Ord(A = B); end; class function TRtlCoreFunctions.Equal_Keyword_Keyword_Ordinal(A, B: Int64): Int64; begin Result := Ord(A = B); end; class function TRtlCoreFunctions.NotEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := Ord(A <> B); end; class function TRtlCoreFunctions.NotEqual_Float_Float_Ordinal(A, B: Double): Int64; begin Result := Ord(A <> B); end; class function TRtlCoreFunctions.NotEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; begin Result := Ord(A <> B); end; class function TRtlCoreFunctions.NotEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; begin Result := Ord(A <> B); end; class function TRtlCoreFunctions.NotEqual_Keyword_Keyword_Ordinal(A, B: Int64): Int64; begin Result := Ord(A <> B); end; class function TRtlCoreFunctions.Less_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := Ord(A < B); end; class function TRtlCoreFunctions.Less_Float_Float_Ordinal(A, B: Double): Int64; begin Result := Ord(A < B); end; class function TRtlCoreFunctions.Less_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; begin Result := Ord(A < B); end; class function TRtlCoreFunctions.Less_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; begin Result := Ord(A < B); end; class function TRtlCoreFunctions.LessOrEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := Ord(A <= B); end; class function TRtlCoreFunctions.LessOrEqual_Float_Float_Ordinal(A, B: Double): Int64; begin Result := Ord(A <= B); end; class function TRtlCoreFunctions.LessOrEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; begin Result := Ord(A <= B); end; class function TRtlCoreFunctions.LessOrEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; begin Result := Ord(A <= B); end; class function TRtlCoreFunctions.Greater_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := Ord(A > B); end; class function TRtlCoreFunctions.Greater_Float_Float_Ordinal(A, B: Double): Int64; begin Result := Ord(A > B); end; class function TRtlCoreFunctions.Greater_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; begin Result := Ord(A > B); end; class function TRtlCoreFunctions.Greater_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; begin Result := Ord(A > B); end; class function TRtlCoreFunctions.GreaterOrEqual_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := Ord(A >= B); end; class function TRtlCoreFunctions.GreaterOrEqual_Float_Float_Ordinal(A, B: Double): Int64; begin Result := Ord(A >= B); end; class function TRtlCoreFunctions.GreaterOrEqual_Ordinal_Float_Ordinal(A: Int64; B: Double): Int64; begin Result := Ord(A >= B); end; class function TRtlCoreFunctions.GreaterOrEqual_Float_Ordinal_Ordinal(A: Double; B: Int64): Int64; begin Result := Ord(A >= B); end; // Bitwise Static class function TRtlCoreFunctions.And_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := A and B; end; class function TRtlCoreFunctions.CFalse: Boolean; begin Result := false; end; class function TRtlCoreFunctions.CTrue: Boolean; begin Result := true; end; class function TRtlCoreFunctions.Or_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := A or B; end; class function TRtlCoreFunctions.Xor_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := A xor B; end; class function TRtlCoreFunctions.Shl_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := A shl B; end; class function TRtlCoreFunctions.Shr_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; begin Result := A shr B; end; // Unary class function TRtlCoreFunctions.Negate_Ordinal_Ordinal(A: Int64): Int64; begin Result := -A; end; class function TRtlCoreFunctions.Negate_Float_Float(A: Double): Double; begin Result := -A; end; class function TRtlCoreFunctions.Not_Ordinal_Ordinal(A: Int64): Int64; begin Result := Ord(A = 0); end; end.