Keywords as basic scalar type
This commit is contained in:
+22
-16
@@ -381,6 +381,9 @@ begin
|
||||
exit(False);
|
||||
|
||||
var otherDef := Other.Definition;
|
||||
if (not Assigned(Self.FDefinition)) or (not Assigned(otherDef)) then
|
||||
exit(False); // Should not happen if Kind is equal, but defensive check
|
||||
|
||||
if Length(Self.FDefinition.Fields) <> Length(otherDef.Fields) then
|
||||
exit(False);
|
||||
|
||||
@@ -399,11 +402,14 @@ var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := GetKind.ToString + '{';
|
||||
for i := 0 to High(FDefinition.Fields) do
|
||||
if Assigned(FDefinition) then
|
||||
begin
|
||||
Result := Result + FDefinition.Fields[i].Key.Name + ': ' + FDefinition.Fields[i].Value.ToString;
|
||||
if i < High(FDefinition.Fields) then
|
||||
Result := Result + ', ';
|
||||
for i := 0 to High(FDefinition.Fields) do
|
||||
begin
|
||||
Result := Result + FDefinition.Fields[i].Key.Name + ': ' + FDefinition.Fields[i].Value.ToString;
|
||||
if i < High(FDefinition.Fields) then
|
||||
Result := Result + ', ';
|
||||
end;
|
||||
end;
|
||||
Result := Result + '}';
|
||||
end;
|
||||
@@ -446,6 +452,7 @@ begin
|
||||
case AKind of
|
||||
TScalar.TKind.Ordinal: Result := FOrdinal;
|
||||
TScalar.TKind.Float: Result := FFloat;
|
||||
TScalar.TKind.Keyword: Result := FKeyword;
|
||||
else
|
||||
raise ETypeException.Create('Cannot convert invalid TScalar.TKind to TStaticType.');
|
||||
end;
|
||||
@@ -472,6 +479,9 @@ begin
|
||||
if (Target.Kind = stVoid) and (Source.Kind = stMethod) then
|
||||
exit(True);
|
||||
|
||||
if (Target.Kind = stOrdinal) and (Source.Kind = stKeyword) then
|
||||
exit(True);
|
||||
|
||||
// TODO: Implement full assignment compatibility rules (e.g., for records/series)
|
||||
|
||||
Result := False;
|
||||
@@ -499,11 +509,11 @@ begin
|
||||
if (A.Kind = stOrdinal) and (B.Kind = stOrdinal) then
|
||||
exit(TTypes.Ordinal);
|
||||
|
||||
// If types are identical and not numeric, return that type (e.g. Text + Text might be valid later)
|
||||
// If types are identical (incl. Keyword, Text, etc.), return that type.
|
||||
if A.IsEqual(B) then
|
||||
exit(A);
|
||||
|
||||
// Cannot promote other combinations during basic inference
|
||||
// Cannot promote other combinations (e.g., Ordinal and Keyword)
|
||||
raise ETypeException.CreateFmt('Cannot promote types %s and %s', [A.ToString, B.ToString]);
|
||||
end;
|
||||
|
||||
@@ -551,24 +561,18 @@ begin
|
||||
|
||||
TScalar.TBinaryOp.Equal, TScalar.TBinaryOp.NotEqual:
|
||||
begin
|
||||
// Allow equality checks for Keywords
|
||||
if (promotedKind = stKeyword) then
|
||||
begin
|
||||
Result := TTypes.Ordinal;
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Comparison requires Ordinal or Float, but *always* results in Ordinal (boolean)
|
||||
if not (promotedKind in [stOrdinal, stFloat]) then
|
||||
// Allow equality checks for Ordinal, Float, or Keyword
|
||||
if not (promotedKind in [stOrdinal, stFloat, stKeyword]) then
|
||||
raise ETypeException.CreateFmt(
|
||||
'Comparison operator %s requires Ordinal, Float, or Keyword, but got %s after promotion',
|
||||
[Op.ToString, promotedType.ToString]);
|
||||
// Result is always Ordinal (boolean)
|
||||
Result := TTypes.Ordinal;
|
||||
end;
|
||||
|
||||
TScalar.TBinaryOp.Less, TScalar.TBinaryOp.Greater, TScalar.TBinaryOp.LessOrEqual, TScalar.TBinaryOp.GreaterOrEqual:
|
||||
begin
|
||||
// Comparison requires Ordinal or Float, but *always* results in Ordinal (boolean)
|
||||
// Comparison requires Ordinal or Float (Keywords are not ordered)
|
||||
if not (promotedKind in [stOrdinal, stFloat]) then
|
||||
raise ETypeException.CreateFmt(
|
||||
'Comparison operator %s requires Ordinal or Float, but got %s after promotion',
|
||||
@@ -593,6 +597,7 @@ begin
|
||||
case Op of
|
||||
TScalar.TUnaryOp.Negate:
|
||||
begin
|
||||
// Negation requires Ordinal or Float
|
||||
if not (rightKind in [stOrdinal, stFloat]) then
|
||||
raise ETypeException.CreateFmt('Unary negation cannot be applied to %s', [Right.ToString]);
|
||||
Result := Right; // Negation preserves type
|
||||
@@ -600,6 +605,7 @@ begin
|
||||
|
||||
TScalar.TUnaryOp.Not:
|
||||
begin
|
||||
// Logical not only applies to Ordinal (booleans)
|
||||
if not (rightKind = stOrdinal) then
|
||||
raise ETypeException.CreateFmt('Logical not cannot be applied to %s', [Right.ToString]);
|
||||
Result := TTypes.Ordinal;
|
||||
|
||||
Reference in New Issue
Block a user