Script Refactoring, ParseGet reads record fields
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -687,30 +687,77 @@ var
|
|||||||
newBase, newIndex: IAstNode;
|
newBase, newIndex: IAstNode;
|
||||||
baseType, elemType: IStaticType;
|
baseType, elemType: IStaticType;
|
||||||
isOpt: Boolean;
|
isOpt: Boolean;
|
||||||
|
idx: Integer;
|
||||||
|
key: IKeyword;
|
||||||
begin
|
begin
|
||||||
I := Node.AsIndexer;
|
I := Node.AsIndexer;
|
||||||
newBase := Accept(I.Base);
|
newBase := Accept(I.Base);
|
||||||
newIndex := Accept(I.Index);
|
newIndex := Accept(I.Index);
|
||||||
baseType := PrepareBaseType(newBase, isOpt);
|
|
||||||
|
|
||||||
|
// Unwrap optional types to check the underlying structure
|
||||||
|
baseType := PrepareBaseType(newBase, isOpt);
|
||||||
elemType := TTypes.Unknown;
|
elemType := TTypes.Unknown;
|
||||||
if baseType.Kind = stSeries then
|
|
||||||
elemType := baseType.AsSeries.ElementType
|
case baseType.Kind of
|
||||||
else if baseType.Kind = stRecordSeries then
|
// Case 1: Accessing Tuples (Heterogeneous fixed-size lists)
|
||||||
elemType := TTypes.CreateRecord(baseType.AsRecord.Definition)
|
// Static typing requires the index to be a constant integer to determine the specific element type.
|
||||||
else if baseType.Kind = stTuple then
|
stTuple:
|
||||||
begin
|
|
||||||
// Tuple Indexing (requires constant index for strong typing!)
|
|
||||||
if (newIndex.Kind = akConstant) and (newIndex.AsConstant.Value.Kind = vkScalar) then
|
|
||||||
begin
|
begin
|
||||||
var idx := newIndex.AsConstant.Value.AsScalar.Value.AsInt64;
|
if (newIndex.Kind = akConstant) and (newIndex.AsConstant.Value.Kind = vkScalar) then
|
||||||
var tpl := baseType.AsTuple;
|
begin
|
||||||
if (idx >= 0) and (idx < tpl.Count) then
|
var intIdx := newIndex.AsConstant.Value.AsScalar.Value.AsInt64;
|
||||||
elemType := tpl.Elements[Integer(idx)];
|
var tpl := baseType.AsTuple;
|
||||||
|
if (intIdx >= 0) and (intIdx < tpl.Count) then
|
||||||
|
elemType := tpl.Elements[Integer(intIdx)];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Case 2: Accessing Records or Record Series (Field Access)
|
||||||
|
// Static typing requires the index to be a Keyword literal.
|
||||||
|
stRecord, stRecordSeries:
|
||||||
|
begin
|
||||||
|
if newIndex.Kind = akKeyword then
|
||||||
|
begin
|
||||||
|
key := newIndex.AsKeyword.Value;
|
||||||
|
var def := baseType.AsRecord.Definition;
|
||||||
|
|
||||||
|
idx := def.IndexOf(key);
|
||||||
|
if idx >= 0 then
|
||||||
|
begin
|
||||||
|
var fieldType := TTypes.FromScalarKind(def[idx]);
|
||||||
|
|
||||||
|
// If we access a field on a Stream/Series of Records, the result is a Series of that field (Column).
|
||||||
|
// If we access a field on a single Record, the result is the scalar value.
|
||||||
|
if baseType.Kind = stRecordSeries then
|
||||||
|
elemType := TTypes.CreateSeries(fieldType)
|
||||||
|
else
|
||||||
|
elemType := fieldType;
|
||||||
|
end
|
||||||
|
else if Assigned(FLog) then
|
||||||
|
FLog.AddError(Format('Field ":%s" not found in record definition.', [key.Name]), Node);
|
||||||
|
end
|
||||||
|
else if Assigned(FLog) then
|
||||||
|
FLog.AddError('Record access requires a constant keyword literal (e.g. :close).', Node);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Case 3: Accessing Series via Integer Index (Row Access)
|
||||||
|
// Returns the scalar element at the specific position.
|
||||||
|
stSeries:
|
||||||
|
begin
|
||||||
|
elemType := baseType.AsSeries.ElementType;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Case 4: Vector / Matrix (Homogeneous)
|
||||||
|
// Accessing a Vector returns the ElementType.
|
||||||
|
stVector:
|
||||||
|
begin
|
||||||
|
elemType := baseType.AsVector.ElementType;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Propagate nullability if the base object was optional
|
||||||
elemType := ApplyOptionality(elemType, isOpt);
|
elemType := ApplyOptionality(elemType, isOpt);
|
||||||
|
|
||||||
Result := TAst.Indexer(Node.Identity, newBase, newIndex, elemType);
|
Result := TAst.Indexer(Node.Identity, newBase, newIndex, elemType);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
+725
-362
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user