Ast development

This commit is contained in:
Michael Schimmel
2025-09-02 17:49:30 +02:00
parent a83bbf4f54
commit eb7902d9e8
7 changed files with 257 additions and 83 deletions
+62 -11
View File
@@ -32,6 +32,7 @@ type
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TAstValue; virtual;
function VisitAssignment(const Node: IAssignmentNode): TAstValue; virtual;
function VisitIndexer(const Node: IIndexerNode): TAstValue; virtual;
function VisitMemberAccess(const Node: IMemberAccessNode): TAstValue; virtual;
end;
// TDebugEvaluatorVisitor now overrides all visit methods for full tracing
@@ -61,6 +62,7 @@ type
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TAstValue; override;
function VisitAssignment(const Node: IAssignmentNode): TAstValue; override;
function VisitIndexer(const Node: IIndexerNode): TAstValue; override;
function VisitMemberAccess(const Node: IMemberAccessNode): TAstValue; override;
end;
// Registers all native core functions in the given scope.
@@ -208,7 +210,7 @@ begin
skInteger: Result := (AValue.AsScalar.Value.AsInteger <> 0);
skInt64: Result := (AValue.AsScalar.Value.AsInt64 <> 0);
skUInt64: Result := (AValue.AsScalar.Value.AsUInt64 <> 0);
skBoolean: Result := AValue.AsScalar.Value.AsBoolean;
skBoolean: Result := (AValue.AsScalar.Value.AsBoolean);
else
Result := False;
end;
@@ -248,17 +250,13 @@ end;
function TEvaluatorVisitor.VisitIndexer(const Node: IIndexerNode): TAstValue;
var
baseValue, indexValue: TAstValue;
series: TScalarRecordSeries;
rec: TScalarRecord;
index: Int64;
indexScalar: TScalar;
begin
baseValue := Node.Base.Accept(Self);
indexValue := Node.Index.Accept(Self);
if (baseValue.Kind <> avkRecordSeries) then
raise EArgumentException.Create('Indexer `[]` can only be applied to a RecordSeries.');
// Index validation (common for all indexable types)
if (indexValue.Kind <> avkScalar) then
raise EArgumentException.Create('Indexer `[]` requires a scalar integer argument.');
@@ -270,13 +268,54 @@ begin
raise EArgumentException.Create('Indexer `[]` requires an integer type argument.');
end;
series := baseValue.AsRecordSeries;
// Base type dispatching
case baseValue.Kind of
avkRecordSeries:
begin
var series := baseValue.AsRecordSeries;
if (index < 0) or (index >= series.TotalCount) then
raise EArgumentException.CreateFmt('Index %d is out of bounds for series with %d elements.', [index, series.TotalCount]);
if (index < 0) or (index >= series.TotalCount) then
raise EArgumentException.CreateFmt('Index %d is out of bounds for series with %d elements.', [index, series.TotalCount]);
var recordValue := series.Items[Integer(index)];
Result := TAstValue.FromRecord(recordValue);
end;
avkMemberSeries:
begin
var memberSeries := baseValue.AsMemberSeries;
if (index < 0) or (index >= memberSeries.Count) then
raise EArgumentException
.CreateFmt('Index %d is out of bounds for member series with %d elements.', [index, memberSeries.Count]);
rec := series.Items[Integer(index)];
Result := TAstValue.FromRecord(rec);
var scalarValue := memberSeries.Items[Integer(index)];
Result := TAstValue.FromScalar(scalarValue);
end;
else
raise EArgumentException.Create('Indexer `[]` is not supported for this value type.');
end;
end;
function TEvaluatorVisitor.VisitMemberAccess(const Node: IMemberAccessNode): TAstValue;
var
baseValue: TAstValue;
memberName: string;
begin
baseValue := Node.Base.Accept(Self);
memberName := Node.Member.Name;
case baseValue.Kind of
avkRecordSeries:
begin
var series := baseValue.AsRecordSeries;
Result := TAstValue.FromMemberSeries(series.CreateMemberSeries(memberName));
end;
avkRecord:
begin
var recordValue := baseValue.AsRecord;
Result := TAstValue.FromScalar(recordValue.Items[memberName]);
end;
else
raise EArgumentException.Create('Member access operator `.` is not supported for this value type.');
end;
end;
function TEvaluatorVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TAstValue;
@@ -607,6 +646,18 @@ begin
AppendLine(Format('} -> %s', [Result.ToString]));
end;
function TDebugEvaluatorVisitor.VisitMemberAccess(const Node: IMemberAccessNode): TAstValue;
begin
AppendLine(Format('MemberAccess (Member: %s) {', [Node.Member.Name]));
Indent;
try
Result := inherited VisitMemberAccess(Node);
finally
Unindent;
end;
AppendLine(Format('} -> %s', [Result.ToString]));
end;
function TDebugEvaluatorVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): TAstValue;
begin
AppendLine('TernaryExpr{');