Ast development
This commit is contained in:
@@ -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{');
|
||||
|
||||
Reference in New Issue
Block a user