Ast series indexer

This commit is contained in:
Michael Schimmel
2025-09-02 16:58:52 +02:00
parent 375e64411b
commit a83bbf4f54
11 changed files with 734 additions and 79 deletions
+50 -5
View File
@@ -20,8 +20,8 @@ type
function ToString: string;
end;
// Added avkText to represent a string value.
TAstValueKind = (avkUndefined, avkScalar, avkClosure, avkText);
// Added avkRecord to represent a TScalarRecord value.
TAstValueKind = (avkUndefined, avkScalar, avkClosure, avkText, avkRecordSeries, avkRecord);
// --- Forward Declarations to break cycles ---
IExecutionScope = interface;
@@ -40,6 +40,8 @@ type
IBlockExpressionNode = interface;
IVariableDeclarationNode = interface;
IAssignmentNode = interface;
// Added forward declaration for the new indexer node.
IIndexerNode = interface;
IEvaluatorClosure = interface;
// --- Concrete Type Definitions ---
@@ -59,7 +61,7 @@ type
private
type
IVal<T> = interface
['{70210CAF-0857-4BF1-8254-B8239A155A02}']
['{7D5AD675-A008-4007-B1A4-CF7A05749510}'] // needed, do not remove
function GetValue: T;
property Value: T read GetValue;
end;
@@ -84,9 +86,13 @@ type
class function FromScalar(const AValue: TScalar): TAstValue; static;
class function FromClosure(const AValue: IEvaluatorClosure): TAstValue; static;
class function FromText(const AValue: String): TAstValue; static;
class function FromRecordSeries(const AValue: TScalarRecordSeries): TAstValue; static;
class function FromRecord(const AValue: TScalarRecord): TAstValue; static;
function AsScalar: TScalar;
function AsClosure: IEvaluatorClosure;
function AsText: String;
function AsRecordSeries: TScalarRecordSeries;
function AsRecord: TScalarRecord;
function ToString: String;
property IsVoid: Boolean read GetIsVoid;
property Kind: TAstValueKind read GetKind;
@@ -105,19 +111,18 @@ type
end;
IAstVisitor = interface
['{A58B0A8E-F438-4217-A964-6E35624A9A4A}']
function VisitConstant(const Node: IConstantNode): TAstValue;
function VisitIdentifier(const Node: IIdentifierNode): TAstValue;
function VisitBinaryExpression(const Node: IBinaryExpressionNode): TAstValue;
function VisitUnaryExpression(const Node: IUnaryExpressionNode): TAstValue;
function VisitIfExpression(const Node: IIfExpressionNode): TAstValue;
// Added visitor method for the new ternary expression node.
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TAstValue;
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TAstValue;
function VisitFunctionCall(const Node: IFunctionCallNode): TAstValue;
function VisitBlockExpression(const Node: IBlockExpressionNode): TAstValue;
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TAstValue;
function VisitAssignment(const Node: IAssignmentNode): TAstValue;
function VisitIndexer(const Node: IIndexerNode): TAstValue;
end;
IAstNode = interface(IInterface)
@@ -228,6 +233,16 @@ type
property Value: IExpressionNode read GetValue;
end;
// Represents an index access expression (e.g., series[index]).
IIndexerNode = interface(IExpressionNode)
{$region 'private'}
function GetBase: IExpressionNode;
function GetIndex: IExpressionNode;
{$endregion}
property Base: IExpressionNode read GetBase;
property Index: IExpressionNode read GetIndex;
end;
implementation
uses
@@ -261,6 +276,20 @@ begin
Result := IEvaluatorClosure(FInterface);
end;
function TAstValue.AsRecord: TScalarRecord;
begin
if (FKind <> avkRecord) then
raise EInvalidCast.Create('Cannot read value as Record.');
Result := (FInterface as IVal<TScalarRecord>).Value;
end;
function TAstValue.AsRecordSeries: TScalarRecordSeries;
begin
if (FKind <> avkRecordSeries) then
raise EInvalidCast.Create('Cannot read value as RecordSeries.');
Result := (FInterface as IVal<TScalarRecordSeries>).Value;
end;
function TAstValue.AsScalar: TScalar;
begin
if (FKind <> avkScalar) then
@@ -283,6 +312,20 @@ begin
Result.FScalar := Default(TScalar);
end;
class function TAstValue.FromRecord(const AValue: TScalarRecord): TAstValue;
begin
Result.FKind := avkRecord;
Result.FInterface := TVal<TScalarRecord>.Create(AValue);
Result.FScalar := Default(TScalar);
end;
class function TAstValue.FromRecordSeries(const AValue: TScalarRecordSeries): TAstValue;
begin
Result.FKind := avkRecordSeries;
Result.FInterface := TVal<TScalarRecordSeries>.Create(AValue);
Result.FScalar := Default(TScalar);
end;
class function TAstValue.FromScalar(const AValue: TScalar): TAstValue;
begin
Result.FKind := avkScalar;
@@ -313,6 +356,8 @@ begin
avkScalar: Result := FScalar.ToString;
avkClosure: Result := '<closure>';
avkText: Result := AsText;
avkRecordSeries: Result := '<record_series>';
avkRecord: Result := '<record>';
avkUndefined: Result := '<void>';
else
Result := '[Unknown AstValue]';