Scalar operators
This commit is contained in:
@@ -26,6 +26,9 @@ type
|
||||
skDecimal
|
||||
);
|
||||
|
||||
TBinaryOperator = (boAdd, boSubtract, boMultiply, boDivide, boEqual, boNotEqual, boLess, boGreater, boLessOrEqual, boGreaterOrEqual);
|
||||
TUnaryOperator = (uoNegate, uoNot);
|
||||
|
||||
TScalarBytes = array[0..7] of Byte;
|
||||
TScalarPChar = array[0..3] of Char;
|
||||
TScalarString = String[7];
|
||||
@@ -94,11 +97,12 @@ type
|
||||
|
||||
function ToString: String;
|
||||
|
||||
class function IsBinaryOperatorSupported(Op: TBinaryOperator; A, B: TScalarKind): Boolean; static;
|
||||
class function IsUnaryOperatorSupported(Op: TUnaryOperator; A: TScalarKind): Boolean; static;
|
||||
|
||||
class operator Add(const A, B: TScalar): TScalar;
|
||||
class operator Divide(const A, B: TScalar): TScalar;
|
||||
class operator Equal(const A, B: TScalar): Boolean;
|
||||
|
||||
//TODO implementieren
|
||||
class operator GreaterThan(const A, B: TScalar): Boolean;
|
||||
class operator GreaterThanOrEqual(const A, B: TScalar): Boolean;
|
||||
class operator LessThan(const A, B: TScalar): Boolean;
|
||||
@@ -406,6 +410,65 @@ begin
|
||||
Result.Value := TScalarValue.FromUInt64(AValue);
|
||||
end;
|
||||
|
||||
class function TScalar.IsBinaryOperatorSupported(Op: TBinaryOperator; A, B: TScalarKind): Boolean;
|
||||
begin
|
||||
const FLOAT_KINDS: set of TScalarKind = [skSingle, skDouble];
|
||||
const ORDINAL_KINDS: set of TScalarKind = [skInteger, skInt64, skUInt64];
|
||||
const NUMERIC_KINDS: set of TScalarKind = FLOAT_KINDS + ORDINAL_KINDS + [skDecimal];
|
||||
const COMPARABLE_KINDS: set of TScalarKind = NUMERIC_KINDS + [skDateTime, skChar, skString];
|
||||
|
||||
// General check for incompatible types
|
||||
if (A = B) then
|
||||
begin
|
||||
case Op of
|
||||
boAdd, boSubtract, boMultiply, boDivide: Result := A in NUMERIC_KINDS + [skDateTime];
|
||||
boEqual, boNotEqual, boLess, boGreater, boLessOrEqual, boGreaterOrEqual: Result := A in COMPARABLE_KINDS;
|
||||
else
|
||||
Result := False;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// Mixed-type checks
|
||||
case Op of
|
||||
boAdd:
|
||||
Result :=
|
||||
(((A in NUMERIC_KINDS) and (B in NUMERIC_KINDS))
|
||||
or ((A = skDateTime) and (B in ORDINAL_KINDS + FLOAT_KINDS))
|
||||
or ((B = skDateTime) and (A in ORDINAL_KINDS + FLOAT_KINDS)));
|
||||
boSubtract:
|
||||
Result := (((A in NUMERIC_KINDS) and (B in NUMERIC_KINDS)) or ((A = skDateTime) and (B in NUMERIC_KINDS + [skDateTime])));
|
||||
boMultiply, boDivide: Result := (A in NUMERIC_KINDS) and (B in NUMERIC_KINDS);
|
||||
boEqual, boNotEqual, boLess, boGreater, boLessOrEqual, boGreaterOrEqual:
|
||||
Result := (A in NUMERIC_KINDS) and (B in NUMERIC_KINDS);
|
||||
else
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Specific exclusion rules
|
||||
if Result then
|
||||
begin
|
||||
// Decimal cannot be mixed with floats for any operator
|
||||
if ((A = skDecimal) and (B in FLOAT_KINDS)) or ((B = skDecimal) and (A in FLOAT_KINDS)) then
|
||||
Result :=
|
||||
False
|
||||
// Cannot subtract a DateTime from a Numeric type
|
||||
else if (Op = boSubtract) and (A in NUMERIC_KINDS) and (B = skDateTime) then
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TScalar.IsUnaryOperatorSupported(Op: TUnaryOperator; A: TScalarKind): Boolean;
|
||||
begin
|
||||
case Op of
|
||||
uoNegate: Result := A in [skInteger, skInt64, skSingle, skDouble, skDecimal];
|
||||
uoNot: Result := A in [skBoolean, skInteger, skInt64, skUInt64];
|
||||
else
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TScalar.StringToKind(const AName: string): TScalarKind;
|
||||
begin
|
||||
if SameText(AName, 'integer') then
|
||||
|
||||
Reference in New Issue
Block a user