Nop-Node
This commit is contained in:
+17
-23
@@ -845,32 +845,26 @@ begin
|
||||
end;
|
||||
|
||||
procedure TForm1.Test1ButtonClick(Sender: TObject);
|
||||
var
|
||||
main, callAst: IAstNode;
|
||||
result: TDataValue;
|
||||
sw: TStopwatch;
|
||||
begin
|
||||
Memo1.Lines.Clear;
|
||||
Memo1.Lines.Add('--- Simple AST Execution ---');
|
||||
sw := TStopwatch.StartNew;
|
||||
|
||||
main :=
|
||||
TAst.LambdaExpr(
|
||||
[],
|
||||
TAst.Block(
|
||||
[
|
||||
TAst.VarDecl(TAst.Identifier('a'), TAst.Constant(10)),
|
||||
TAst.VarDecl(TAst.Identifier('b'), TAst.BinaryExpr(TAst.Identifier('a'), TScalar.TBinaryOp.Multiply, TAst.Constant(2))),
|
||||
TAst.BinaryExpr(TAst.Identifier('a'), TScalar.TBinaryOp.Add, TAst.Identifier('b'))
|
||||
]
|
||||
)
|
||||
FCurrUnboundAst :=
|
||||
TAst.Block(
|
||||
[
|
||||
TAst.LambdaExpr(
|
||||
[],
|
||||
TAst.Block(
|
||||
[
|
||||
TAst.VarDecl(TAst.Identifier('a'), TAst.Nop),
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('b'),
|
||||
TAst.BinaryExpr(TAst.Identifier('a'), TScalar.TBinaryOp.Multiply, TAst.Constant(2))
|
||||
),
|
||||
TAst.BinaryExpr(TAst.Identifier('a'), TScalar.TBinaryOp.Add, TAst.Identifier('b'))
|
||||
]
|
||||
)
|
||||
)
|
||||
]
|
||||
);
|
||||
|
||||
callAst := TAst.FunctionCall(main, []);
|
||||
result := ExecuteAst(callAst, FGScope);
|
||||
|
||||
sw.Stop;
|
||||
Memo1.Lines.Add(Format('Result: %s (calculated in %d ms)', [result.ToString, sw.ElapsedMilliseconds]));
|
||||
UpdateScript;
|
||||
end;
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ type
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TAuraNode; override;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): TAuraNode; override;
|
||||
function VisitRecurNode(const Node: IRecurNode): TAuraNode; override;
|
||||
function VisitNop(const Node: INopNode): TAuraNode; override;
|
||||
|
||||
public
|
||||
constructor Create(AWorkspace: TAuraWorkspace; AParentControl: TControl; AExprDepth: Integer);
|
||||
@@ -525,6 +526,17 @@ type
|
||||
property Node: ISeriesLengthNode read FNode;
|
||||
end;
|
||||
|
||||
TAuraNopNode = class(TAuraNode)
|
||||
private
|
||||
FNode: INopNode;
|
||||
protected
|
||||
procedure SetupNode; override;
|
||||
public
|
||||
constructor Create(const AVisualizer: IAstVisualizer; const ANode: INopNode);
|
||||
function CreateAst: IAstNode; override;
|
||||
property Node: INopNode read FNode;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TAstVisualizer }
|
||||
@@ -716,6 +728,11 @@ begin
|
||||
Result := TAuraVariableDeclarationNode.Create(Self, Node);
|
||||
end;
|
||||
|
||||
function TAstVisualizer.VisitNop(const Node: INopNode): TAuraNode;
|
||||
begin
|
||||
Result := TAuraNopNode.Create(Self, Node);
|
||||
end;
|
||||
|
||||
{ TAutoFitControl }
|
||||
|
||||
constructor TAutoFitControl.Create(AOwner: TComponent);
|
||||
@@ -1039,7 +1056,7 @@ begin
|
||||
Canvas.FillRect(TRectF.Create(0, 0, Width, Height), 0, 0, [], 1.0);
|
||||
Canvas.Stroke.Kind := TBrushKind.Solid;
|
||||
Canvas.Stroke.Color := FBorderColor;
|
||||
Canvas.Stroke.Thickness := 1;
|
||||
Canvas.Stroke.Thickness := FBorderWidth;
|
||||
Canvas.Stroke.Dash := TStrokeDash.Dot;
|
||||
Canvas.DrawRect(TRectF.Create(0, 0, Width, Height), 0, 0, [], 1.0);
|
||||
end
|
||||
@@ -2222,4 +2239,38 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TAuraNopNode }
|
||||
|
||||
constructor TAuraNopNode.Create(const AVisualizer: IAstVisualizer; const ANode: INopNode);
|
||||
begin
|
||||
inherited Create(AVisualizer);
|
||||
FNode := ANode;
|
||||
|
||||
// Visual style for Nop: Dotted border, minimal size, clear color.
|
||||
Frameless := true;
|
||||
Alignment := TLayoutAlignment.laCenter;
|
||||
Orientation := TLayoutOrientation.loHorizontal;
|
||||
end;
|
||||
|
||||
function TAuraNopNode.CreateAst: IAstNode;
|
||||
begin
|
||||
// The visual node returns the original Nop node, which the compiler pipeline must reject.
|
||||
Result := FNode;
|
||||
end;
|
||||
|
||||
procedure TAuraNopNode.SetupNode;
|
||||
var
|
||||
lbl: TLabel;
|
||||
begin
|
||||
BeginUpdate;
|
||||
try
|
||||
// Add a placeholder text
|
||||
lbl := AddLabel(Self, '...');
|
||||
lbl.Font.Style := lbl.Font.Style + [TFontStyle.fsBold];
|
||||
lbl.Margins.Rect := TRectF.Create(8, 4, 8, 4);
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -56,6 +56,7 @@ type
|
||||
procedure VisitCreateSeries(const Node: ICreateSeriesNode); override;
|
||||
procedure VisitAddSeriesItem(const Node: IAddSeriesItemNode); override;
|
||||
procedure VisitSeriesLength(const Node: ISeriesLengthNode); override;
|
||||
procedure VisitNop(const Node: INopNode); override;
|
||||
|
||||
public
|
||||
// Creates a new instance of the AST dumper.
|
||||
@@ -461,6 +462,11 @@ begin
|
||||
Unindent;
|
||||
end;
|
||||
|
||||
procedure TAstDumper.VisitNop(const Node: INopNode);
|
||||
begin
|
||||
Log('Nop');
|
||||
end;
|
||||
|
||||
procedure TAstDumper.VisitSeriesLength(const Node: ISeriesLengthNode);
|
||||
begin
|
||||
Log('SeriesLength');
|
||||
|
||||
@@ -47,6 +47,7 @@ type
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; virtual;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; virtual;
|
||||
function VisitRecurNode(const Node: IRecurNode): TDataValue; virtual;
|
||||
function VisitNop(const Node: INopNode): TDataValue; virtual;
|
||||
|
||||
function IsTruthy(const AValue: TDataValue): Boolean; inline;
|
||||
|
||||
@@ -445,6 +446,12 @@ var
|
||||
index: Int64;
|
||||
series: ISeries;
|
||||
recSeries: IRecordSeries;
|
||||
i, fieldCount: Integer;
|
||||
values: TArray<TScalar.TValue>;
|
||||
key: IKeyword;
|
||||
memberSeries: ISeries;
|
||||
scalarValue: TScalar;
|
||||
rec: TScalarRecord;
|
||||
begin
|
||||
baseValue := Node.Base.Accept(Self);
|
||||
indexValue := Node.Index.Accept(Self);
|
||||
@@ -467,12 +474,20 @@ begin
|
||||
recSeries := baseValue.AsRecordSeries;
|
||||
if (index < 0) or (index >= recSeries.TotalCount) then
|
||||
raise EArgumentException.CreateFmt('Index %d is out of bounds for series with %d elements.', [index, recSeries.TotalCount]);
|
||||
// Accessing a record series by index materializes the TScalarRecord
|
||||
var rec := TScalarRecord.Create(recSeries.Def, nil); // Nil fields, needs implementation
|
||||
// TODO: This path (materializing a record from TScalarRecordSeries) is not fully implemented.
|
||||
// We need to fetch the underlying TScalar.TValue array slice.
|
||||
// For now, returning an empty record shell.
|
||||
raise ENotSupportedException.Create('Indexing a RecordSeries to materialize a Record is not yet implemented.');
|
||||
|
||||
// Materialize the TScalarRecord by accessing each member series by index
|
||||
fieldCount := Length(recSeries.Def.Fields);
|
||||
SetLength(values, fieldCount);
|
||||
|
||||
for i := 0 to fieldCount - 1 do
|
||||
begin
|
||||
key := recSeries.Def.Fields[i].Key;
|
||||
memberSeries := recSeries[key];
|
||||
scalarValue := memberSeries[index];
|
||||
values[i] := scalarValue.Value;
|
||||
end;
|
||||
|
||||
rec := TScalarRecord.Create(recSeries.Def, values);
|
||||
Result := TDataValue.FromRecord(rec);
|
||||
end;
|
||||
else
|
||||
@@ -646,6 +661,13 @@ begin
|
||||
Result := expression.Accept(Self);
|
||||
end;
|
||||
|
||||
function TEvaluatorVisitor.VisitNop(const Node: INopNode): TDataValue;
|
||||
begin
|
||||
// This node should be rejected by the Binder/TypeChecker.
|
||||
// If it reaches the evaluator, it's a compiler bug, but we treat it as Void.
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TEvaluatorVisitor.VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
|
||||
var
|
||||
seriesValue: TDataValue;
|
||||
|
||||
@@ -51,6 +51,8 @@ type
|
||||
function JsonToCreateSeriesNode(const AObj: TJSONObject): ICreateSeriesNode;
|
||||
function JsonToAddSeriesItemNode(const AObj: TJSONObject): IAddSeriesItemNode;
|
||||
function JsonToSeriesLengthNode(const AObj: TJSONObject): ISeriesLengthNode;
|
||||
function JsonToNopNode(const AObj: TJSONObject): INopNode;
|
||||
|
||||
protected
|
||||
// IAstVisitor implementation for serialization (T = TJSONObject)
|
||||
function VisitConstant(const Node: IConstantNode): TJSONObject; override;
|
||||
@@ -77,6 +79,7 @@ type
|
||||
function VisitCreateSeries(const Node: ICreateSeriesNode): TJSONObject; override;
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TJSONObject; override;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): TJSONObject; override;
|
||||
function VisitNop(const Node: INopNode): TJSONObject; override;
|
||||
|
||||
function Serialize(const RootNode: IAstNode): TJSONObject;
|
||||
function Deserialize(const AJson: TJSONObject): IAstNode;
|
||||
@@ -456,6 +459,13 @@ begin
|
||||
Result.AddPair('Series', seriesObj);
|
||||
end;
|
||||
|
||||
function TJsonAstConverter.VisitNop(const Node: INopNode): TJSONObject;
|
||||
begin
|
||||
Result := TJSONObject.Create;
|
||||
Result.AddPair('NodeType', TJSONString.Create('Nop'));
|
||||
// No other properties needed, as it is stateless
|
||||
end;
|
||||
|
||||
{ TJsonAstConverter - Deserialization }
|
||||
|
||||
function TJsonAstConverter.JsonToDataValue(const AObj: TJSONObject; const AName: string): TDataValue;
|
||||
@@ -761,6 +771,11 @@ begin
|
||||
Result := TAst.SeriesLength(JsonToIdentifierNode(AObj.GetValue('Series') as TJSONObject));
|
||||
end;
|
||||
|
||||
function TJsonAstConverter.JsonToNopNode(const AObj: TJSONObject): INopNode;
|
||||
begin
|
||||
Result := TAst.Nop.AsNop;
|
||||
end;
|
||||
|
||||
function TJsonAstConverter.JsonToNode(const AJson: TJSONValue; const ExpectedType: String = ''): IAstNode;
|
||||
var
|
||||
obj: TJSONObject;
|
||||
@@ -823,6 +838,8 @@ begin
|
||||
Result := JsonToAddSeriesItemNode(obj)
|
||||
else if nodeType = 'SeriesLength' then
|
||||
Result := JsonToSeriesLengthNode(obj)
|
||||
else if nodeType = 'Nop' then // Added Nop Deserialization logic
|
||||
Result := JsonToNopNode(obj)
|
||||
else
|
||||
raise ENotSupportedException.CreateFmt('Unsupported NodeType "%s" for JSON deserialization.', [nodeType]);
|
||||
end;
|
||||
|
||||
@@ -37,6 +37,7 @@ type
|
||||
IAddSeriesItemNode = interface;
|
||||
ISeriesLengthNode = interface;
|
||||
IRecurNode = interface;
|
||||
INopNode = interface; // Added Nop
|
||||
|
||||
// Defines the concrete kinds of AST nodes
|
||||
TAstNodeKind = (
|
||||
@@ -63,7 +64,8 @@ type
|
||||
akCreateSeries,
|
||||
akAddSeriesItem,
|
||||
akSeriesLength,
|
||||
akRecur
|
||||
akRecur,
|
||||
akNop // Added Nop
|
||||
);
|
||||
|
||||
// --- Concrete Type Definitions ---
|
||||
@@ -113,6 +115,7 @@ type
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
|
||||
function VisitRecurNode(const Node: IRecurNode): TDataValue;
|
||||
function VisitNop(const Node: INopNode): TDataValue; // Added Nop
|
||||
end;
|
||||
|
||||
IAstNode = interface(IInterface)
|
||||
@@ -145,10 +148,16 @@ type
|
||||
function AsAddSeriesItem: IAddSeriesItemNode;
|
||||
function AsSeriesLength: ISeriesLengthNode;
|
||||
function AsRecur: IRecurNode;
|
||||
function AsNop: INopNode; // Added Nop
|
||||
|
||||
property Kind: TAstNodeKind read GetKind;
|
||||
end;
|
||||
|
||||
INopNode = interface(IAstNode)
|
||||
// A placeholder node for the UI (e.g., drag target).
|
||||
// This node is illegal during compilation.
|
||||
end;
|
||||
|
||||
IConstantNode = interface(IAstNode)
|
||||
// Represents a constant value in the AST (Scalar, Text, or Void).
|
||||
{$region 'private'}
|
||||
|
||||
@@ -9,6 +9,7 @@ uses
|
||||
|
||||
var
|
||||
// This BNF should always be kept up to date and valid. It is used to comunicate with LLMs.
|
||||
// (Nop isn't part of the language syntax.)
|
||||
|
||||
BNF: String =
|
||||
'''
|
||||
@@ -221,6 +222,7 @@ type
|
||||
procedure VisitAddSeriesItem(const Node: IAddSeriesItemNode); override;
|
||||
procedure VisitSeriesLength(const Node: ISeriesLengthNode); override;
|
||||
procedure VisitRecurNode(const Node: IRecurNode); override;
|
||||
procedure VisitNop(const Node: INopNode); override;
|
||||
end;
|
||||
|
||||
{ TLexer }
|
||||
@@ -716,7 +718,24 @@ begin
|
||||
end;
|
||||
tkIdentifier:
|
||||
begin
|
||||
Result.Node := TAst.Identifier(FCurrentToken.Text);
|
||||
// Check for the NOP token ('...')
|
||||
if FCurrentToken.Text = '...' then
|
||||
begin
|
||||
// The token '...' represents the Nop node, a non-compilable placeholder used exclusively
|
||||
// for visual representations (e.g., UI drag targets).
|
||||
//
|
||||
// We handle it as a special case of tkIdentifier instead of introducing a dedicated tkNop
|
||||
// TokenKind because of its **unofficial and transient status**.
|
||||
//
|
||||
// This allows the Parser to immediately apply the syntactic policy: mapping this
|
||||
// specific identifier string directly to the non-standard TAst.Nop node, ensuring
|
||||
// it bypasses the regular identifier creation and maintains its "placeholder" identity.
|
||||
Result.Node := TAst.Nop;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Result.Node := TAst.Identifier(FCurrentToken.Text);
|
||||
end;
|
||||
NextToken;
|
||||
end;
|
||||
tkLeftParen: Result.Node := ParseList;
|
||||
@@ -1068,6 +1087,13 @@ begin
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
procedure TPrettyPrintVisitor.VisitNop(const Node: INopNode);
|
||||
begin
|
||||
// A placeholder node, usually for UI.
|
||||
//TODO Nop soll durch ein spezielles ...-Token repräsentiert werden. Analysiere, ob dies syntaktisch möglich ist. Wenn ja, soll der Parser "inoffiziell" in der Lage sein Nops zu lesen und zu erzeugen.
|
||||
Append('...');
|
||||
end;
|
||||
|
||||
procedure TPrettyPrintVisitor.VisitSeriesLength(const Node: ISeriesLengthNode);
|
||||
begin
|
||||
Append('(count ');
|
||||
|
||||
@@ -37,6 +37,7 @@ type
|
||||
function IAstVisitor.VisitAddSeriesItem = DoVisitAddSeriesItem;
|
||||
function IAstVisitor.VisitSeriesLength = DoVisitSeriesLength;
|
||||
function IAstVisitor.VisitRecurNode = DoVisitRecurNode;
|
||||
function IAstVisitor.VisitNop = DoVisitNop; // Added Nop
|
||||
|
||||
// Private bridge method implementations
|
||||
function DoVisitConstant(const Node: IConstantNode): TDataValue;
|
||||
@@ -63,6 +64,7 @@ type
|
||||
function DoVisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
|
||||
function DoVisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
|
||||
function DoVisitRecurNode(const Node: IRecurNode): TDataValue;
|
||||
function DoVisitNop(const Node: INopNode): TDataValue; // Added Nop
|
||||
|
||||
protected
|
||||
// Visit a node.
|
||||
@@ -92,6 +94,7 @@ type
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): T; virtual; abstract;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): T; virtual; abstract;
|
||||
function VisitRecurNode(const Node: IRecurNode): T; virtual; abstract;
|
||||
function VisitNop(const Node: INopNode): T; virtual; abstract; // Added Nop
|
||||
end;
|
||||
|
||||
TAstTransformer = class abstract(TAstVisitor<IAstNode>)
|
||||
@@ -123,6 +126,7 @@ type
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): IAstNode; override;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): IAstNode; override;
|
||||
function VisitRecurNode(const Node: IRecurNode): IAstNode; override;
|
||||
function VisitNop(const Node: INopNode): IAstNode; override; // Added Nop
|
||||
end;
|
||||
|
||||
TAstVisitor = class abstract(TInterfacedObject, IAstVisitor)
|
||||
@@ -152,6 +156,7 @@ type
|
||||
function IAstVisitor.VisitAddSeriesItem = DoVisitAddSeriesItem;
|
||||
function IAstVisitor.VisitSeriesLength = DoVisitSeriesLength;
|
||||
function IAstVisitor.VisitRecurNode = DoVisitRecurNode;
|
||||
function IAstVisitor.VisitNop = DoVisitNop; // Added Nop
|
||||
|
||||
// Private bridge method implementations
|
||||
function DoVisitConstant(const Node: IConstantNode): TDataValue;
|
||||
@@ -178,6 +183,7 @@ type
|
||||
function DoVisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
|
||||
function DoVisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
|
||||
function DoVisitRecurNode(const Node: IRecurNode): TDataValue;
|
||||
function DoVisitNop(const Node: INopNode): TDataValue; // Added Nop
|
||||
|
||||
protected
|
||||
// Virtual procedures for descendants (Interpreters/Side-effects) to override
|
||||
@@ -205,6 +211,7 @@ type
|
||||
procedure VisitAddSeriesItem(const Node: IAddSeriesItemNode); virtual; abstract;
|
||||
procedure VisitSeriesLength(const Node: ISeriesLengthNode); virtual; abstract;
|
||||
procedure VisitRecurNode(const Node: IRecurNode); virtual; abstract;
|
||||
procedure VisitNop(const Node: INopNode); virtual; abstract; // Added Nop
|
||||
end;
|
||||
|
||||
implementation
|
||||
@@ -341,6 +348,12 @@ begin
|
||||
Result := TDataValue.FromGeneric<T>(VisitRecurNode(Node));
|
||||
end;
|
||||
|
||||
function TAstVisitor<T>.DoVisitNop(const Node: INopNode): TDataValue;
|
||||
begin
|
||||
// Added Nop implementation
|
||||
Result := TDataValue.FromGeneric<T>(VisitNop(Node));
|
||||
end;
|
||||
|
||||
function TAstTransformer.AcceptParameters(const Nodes: TArray<IIdentifierNode>): TArray<IIdentifierNode>;
|
||||
var
|
||||
i: Integer;
|
||||
@@ -418,6 +431,12 @@ begin
|
||||
Result := Node; // Leaf node
|
||||
end;
|
||||
|
||||
function TAstTransformer.VisitNop(const Node: INopNode): IAstNode;
|
||||
begin
|
||||
// Added Nop implementation
|
||||
Result := Node; // Leaf node
|
||||
end;
|
||||
|
||||
function TAstTransformer.VisitBinaryExpression(const Node: IBinaryExpressionNode): IAstNode;
|
||||
var
|
||||
N: TBinaryExpressionNode;
|
||||
@@ -753,4 +772,10 @@ begin
|
||||
VisitRecurNode(Node);
|
||||
end;
|
||||
|
||||
function TAstVisitor.DoVisitNop(const Node: INopNode): TDataValue;
|
||||
begin
|
||||
// Added Nop implementation
|
||||
VisitNop(Node);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -28,6 +28,10 @@ type
|
||||
class procedure RegisterLibrary(const AProc: TRegisterLibraryProc); static;
|
||||
class function CreateScope(Parent: IExecutionScope; const Descriptor: IScopeDescriptor = nil): IExecutionScope; static;
|
||||
|
||||
// A No-Operation node, used as a placeholder/stub (e.g., for UI drop targets).
|
||||
// This node is illegal in the compiler (Binder/TypeChecker will reject it).
|
||||
class function Nop: IAstNode; static;
|
||||
|
||||
// --- Factory functions ---
|
||||
class function Constant(const AValue: TDataValue): IConstantNode; overload; static;
|
||||
class function Constant(const AValue: String): IConstantNode; overload; static;
|
||||
@@ -103,6 +107,7 @@ type
|
||||
function AsAddSeriesItem: IAddSeriesItemNode; virtual;
|
||||
function AsSeriesLength: ISeriesLengthNode; virtual;
|
||||
function AsRecur: IRecurNode; virtual;
|
||||
function AsNop: INopNode; virtual; // Added Nop
|
||||
|
||||
property StaticType: IStaticType read FStaticType write SetStaticType;
|
||||
property Kind: TAstNodeKind read GetKind;
|
||||
@@ -474,6 +479,17 @@ implementation
|
||||
uses
|
||||
System.Generics.Defaults;
|
||||
|
||||
// Added Nop
|
||||
type
|
||||
TNopNode = class(TAstNode, INopNode)
|
||||
private
|
||||
function GetKind: TAstNodeKind; override;
|
||||
public
|
||||
constructor Create;
|
||||
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||
function AsNop: INopNode; override;
|
||||
end;
|
||||
|
||||
{ TAst }
|
||||
|
||||
class function TAst.CreateScope(Parent: IExecutionScope; const Descriptor: IScopeDescriptor): IExecutionScope;
|
||||
@@ -603,6 +619,12 @@ begin
|
||||
Result := TMemberAccessNode.Create(ABase, AMember);
|
||||
end;
|
||||
|
||||
class function TAst.Nop: IAstNode;
|
||||
begin
|
||||
// Factory function for the new Nop node
|
||||
Result := TNopNode.Create;
|
||||
end;
|
||||
|
||||
class function TAst.Quasiquote(const AExpression: IAstNode): IQuasiquoteNode;
|
||||
begin
|
||||
Result := TQuasiquoteNode.Create(AExpression);
|
||||
@@ -650,6 +672,30 @@ begin
|
||||
Result := TVariableDeclarationNode.Create(AIdentifier, AInitializer);
|
||||
end;
|
||||
|
||||
{ TNopNode }
|
||||
|
||||
constructor TNopNode.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
// Nop nodes are 'Void' by default, though TypeChecker will reject them anyway.
|
||||
StaticType := TTypes.Void;
|
||||
end;
|
||||
|
||||
function TNopNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
||||
begin
|
||||
Result := Visitor.VisitNop(Self);
|
||||
end;
|
||||
|
||||
function TNopNode.AsNop: INopNode;
|
||||
begin
|
||||
Result := Self;
|
||||
end;
|
||||
|
||||
function TNopNode.GetKind: TAstNodeKind;
|
||||
begin
|
||||
Result := akNop;
|
||||
end;
|
||||
|
||||
{ TAstNode }
|
||||
|
||||
constructor TAstNode.Create;
|
||||
@@ -733,6 +779,12 @@ begin
|
||||
raise ETypeException.Create('Node is not a MemberAccess');
|
||||
end;
|
||||
|
||||
function TAstNode.AsNop: INopNode;
|
||||
begin
|
||||
// Added Nop implementation
|
||||
raise ETypeException.Create('Node is not a Nop');
|
||||
end;
|
||||
|
||||
function TAstNode.AsQuasiquote: IQuasiquoteNode;
|
||||
begin
|
||||
raise ETypeException.Create('Node is not a Quasiquote');
|
||||
|
||||
Reference in New Issue
Block a user