AST testing
This commit is contained in:
@@ -212,7 +212,7 @@ begin
|
||||
|
||||
// 2. Define the variable in the CURRENT scope
|
||||
// Store the Node reference so we can add it to FBoxedDeclarations if captured.
|
||||
FCurrentScope.Define(Node.Identifier.Name, Node);
|
||||
FCurrentScope.Define(Node.Target.AsIdentifier.Name, Node);
|
||||
|
||||
Result := Node;
|
||||
end;
|
||||
|
||||
@@ -256,10 +256,11 @@ var
|
||||
newIdent: IIdentifierNode;
|
||||
isBoxed: Boolean;
|
||||
begin
|
||||
if not IsValidIdentifier(Node.Identifier.Name) then
|
||||
raise Exception.CreateFmt('Invalid identifier name: "%s".', [Node.Identifier.Name]);
|
||||
var identifier := Node.Target.AsIdentifier;
|
||||
if not IsValidIdentifier(identifier.Name) then
|
||||
raise Exception.CreateFmt('Invalid identifier name: "%s".', [identifier.Name]);
|
||||
|
||||
slot := FCurrentBuilder.Define(Node.Identifier.Name);
|
||||
slot := FCurrentBuilder.Define(identifier.Name);
|
||||
addr := TResolvedAddress.Create(akLocalOrParent, 0, slot);
|
||||
|
||||
if Assigned(Node.Initializer) then
|
||||
@@ -267,7 +268,7 @@ begin
|
||||
else
|
||||
newInit := nil;
|
||||
|
||||
newIdent := TAst.Identifier(Node.Identifier.Name, addr, TTypes.Unknown);
|
||||
newIdent := TAst.Identifier(identifier.Name, addr, TTypes.Unknown);
|
||||
isBoxed := (FBoxedDeclarations <> nil) and FBoxedDeclarations.Contains(Node);
|
||||
|
||||
Result := TAst.VarDecl(newIdent, newInit, TTypes.Unknown, isBoxed);
|
||||
@@ -281,7 +282,7 @@ var
|
||||
newIdent: IAstNode;
|
||||
newValue: IAstNode;
|
||||
begin
|
||||
newIdent := Accept(Node.Identifier);
|
||||
newIdent := Accept(Node.Target);
|
||||
newValue := Accept(Node.Value);
|
||||
|
||||
Result := TAst.Assign(newIdent.AsIdentifier, newValue, TTypes.Unknown);
|
||||
|
||||
@@ -87,6 +87,19 @@ type
|
||||
): IAstNode; static;
|
||||
end;
|
||||
|
||||
TMacroRegistry = class(TInterfacedObject, IMacroRegistry)
|
||||
private
|
||||
FParent: IMacroRegistry;
|
||||
FMacros: TDictionary<string, IMacroDefinitionNode>;
|
||||
function GetParent: IMacroRegistry;
|
||||
public
|
||||
constructor Create(AParent: IMacroRegistry);
|
||||
destructor Destroy; override;
|
||||
procedure Define(const Node: IMacroDefinitionNode);
|
||||
function Find(const Name: string): IMacroDefinitionNode;
|
||||
function CreateChildRegistry: IMacroRegistry;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@@ -193,14 +206,23 @@ end;
|
||||
|
||||
function TExpansionVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): IAstNode;
|
||||
var
|
||||
newTarget, newInit: IAstNode;
|
||||
newName: string;
|
||||
newIdent: IIdentifierNode;
|
||||
newInit: IAstNode;
|
||||
begin
|
||||
newInit := Accept(Node.Initializer);
|
||||
newName := Gensym(Node.Identifier.Name);
|
||||
newIdent := TAst.Identifier(newName, TTypes.Unknown);
|
||||
Result := TAst.VarDecl(newIdent, newInit, TTypes.Unknown);
|
||||
|
||||
// Check if target is identifier before trying to rename
|
||||
if Node.Target.Kind = akIdentifier then
|
||||
begin
|
||||
newName := Gensym(Node.Target.AsIdentifier.Name);
|
||||
newTarget := TAst.Identifier(newName, TTypes.Unknown);
|
||||
end
|
||||
else
|
||||
begin
|
||||
newTarget := Accept(Node.Target); // Recursively expand unquotes in target position!
|
||||
end;
|
||||
|
||||
Result := TAst.VarDecl(newTarget, newInit, TTypes.Unknown);
|
||||
end;
|
||||
|
||||
function TExpansionVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode;
|
||||
@@ -438,4 +460,48 @@ begin
|
||||
raise Exception.Create('Unquote-splicing (`~@`) can only be used inside a quasiquote.');
|
||||
end;
|
||||
|
||||
{ TMacroRegistry }
|
||||
|
||||
constructor TMacroRegistry.Create(AParent: IMacroRegistry);
|
||||
begin
|
||||
inherited Create;
|
||||
FParent := AParent;
|
||||
FMacros := TDictionary<string, IMacroDefinitionNode>.Create;
|
||||
end;
|
||||
|
||||
destructor TMacroRegistry.Destroy;
|
||||
begin
|
||||
FMacros.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TMacroRegistry.GetParent: IMacroRegistry;
|
||||
begin
|
||||
Result := FParent;
|
||||
end;
|
||||
|
||||
procedure TMacroRegistry.Define(const Node: IMacroDefinitionNode);
|
||||
begin
|
||||
FMacros.AddOrSetValue(Node.Name.Name, Node);
|
||||
end;
|
||||
|
||||
function TMacroRegistry.Find(const Name: string): IMacroDefinitionNode;
|
||||
var
|
||||
current: IMacroRegistry;
|
||||
begin
|
||||
current := Self;
|
||||
while Assigned(current) do
|
||||
begin
|
||||
if (current as TMacroRegistry).FMacros.TryGetValue(Name, Result) then
|
||||
exit;
|
||||
current := current.Parent;
|
||||
end;
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
function TMacroRegistry.CreateChildRegistry: IMacroRegistry;
|
||||
begin
|
||||
Result := TMacroRegistry.Create(Self);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -240,7 +240,7 @@ var
|
||||
placeholderType: IStaticType;
|
||||
i: Integer;
|
||||
begin
|
||||
adr := Node.Identifier.Address;
|
||||
adr := Node.Target.AsIdentifier.Address;
|
||||
initType := TTypes.Unknown;
|
||||
|
||||
// Recursive lambda bootstrap logic
|
||||
@@ -274,7 +274,7 @@ begin
|
||||
if initType.Kind <> stUnknown then
|
||||
FCurrentContext.SetType(adr.SlotIndex, initType);
|
||||
|
||||
newIdent := TAst.Identifier(Node.Identifier.Name, adr, initType);
|
||||
newIdent := TAst.Identifier(Node.Target.AsIdentifier.Name, adr, initType);
|
||||
|
||||
Result := TAst.VarDecl(newIdent.AsIdentifier, newInitializer, initType, Node.IsBoxed);
|
||||
end;
|
||||
@@ -288,7 +288,7 @@ var
|
||||
placeholderType: IStaticType;
|
||||
i: Integer;
|
||||
begin
|
||||
newIdent := Accept(Node.Identifier);
|
||||
newIdent := Accept(Node.Target);
|
||||
targetType := newIdent.AsTypedNode.StaticType;
|
||||
adr := newIdent.AsIdentifier.Address;
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ end;
|
||||
|
||||
function TDebugEvaluatorVisitor.VisitAssignment(const Node: IAssignmentNode): TDataValue;
|
||||
begin
|
||||
AppendLine(Format('Assignment to "%s" {', [Node.Identifier.Name]));
|
||||
AppendLine(Format('Assignment to "%s" {', [Node.Target.AsIdentifier.Name]));
|
||||
Indent;
|
||||
try
|
||||
Result := inherited VisitAssignment(Node);
|
||||
@@ -278,7 +278,7 @@ end;
|
||||
|
||||
function TDebugEvaluatorVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
||||
begin
|
||||
AppendLine(Format('VarDecl %s :=', [Node.Identifier.Name]));
|
||||
AppendLine(Format('VarDecl %s :=', [Node.Target.AsIdentifier.Name]));
|
||||
Indent;
|
||||
try
|
||||
Result := inherited VisitVariableDeclaration(Node);
|
||||
|
||||
@@ -355,7 +355,7 @@ procedure TAstDumper.VisitVariableDeclaration(const Node: IVariableDeclarationNo
|
||||
begin
|
||||
LogFmt('VariableDeclaration (IsBoxed: %s)', [Node.IsBoxed.ToString(TUseBoolStrs.True)], Node);
|
||||
Indent;
|
||||
Node.Identifier.Accept(Self);
|
||||
Node.Target.Accept(Self);
|
||||
if Assigned(Node.Initializer) then
|
||||
begin
|
||||
Log('Initializer:');
|
||||
@@ -368,7 +368,7 @@ procedure TAstDumper.VisitAssignment(const Node: IAssignmentNode);
|
||||
begin
|
||||
Log('Assignment', Node);
|
||||
Indent;
|
||||
Node.Identifier.Accept(Self);
|
||||
Node.Target.Accept(Self);
|
||||
Log('Value:');
|
||||
Node.Value.Accept(Self);
|
||||
Unindent;
|
||||
|
||||
@@ -228,20 +228,6 @@ type
|
||||
function CreateVisitor(const AScope: IExecutionScope): IEvaluatorVisitor;
|
||||
end;
|
||||
|
||||
{ TMacroRegistryImpl }
|
||||
TMacroRegistryImpl = class(TInterfacedObject, IMacroRegistry)
|
||||
private
|
||||
FParent: IMacroRegistry;
|
||||
FMacros: TDictionary<string, IMacroDefinitionNode>;
|
||||
function GetParent: IMacroRegistry;
|
||||
public
|
||||
constructor Create(AParent: IMacroRegistry);
|
||||
destructor Destroy; override;
|
||||
procedure Define(const Node: IMacroDefinitionNode);
|
||||
function Find(const Name: string): IMacroDefinitionNode;
|
||||
function CreateChildRegistry: IMacroRegistry;
|
||||
end;
|
||||
|
||||
TFunctionDefinitionRegistry = class(TInterfacedObject, IFunctionDefinitionRegistry)
|
||||
private
|
||||
FMap: TDictionary<TResolvedAddress, IFunctionDefinition>;
|
||||
@@ -336,7 +322,7 @@ begin
|
||||
// Initialize root scope with library registration
|
||||
RootScope := TAst.CreateScope(nil, nil, True);
|
||||
|
||||
Result.Create(TEnvironment.Create(RootScope, TMacroRegistryImpl.Create(nil), TStandardExecutionStrategy.Create));
|
||||
Result.Create(TEnvironment.Create(RootScope, TMacroRegistry.Create(nil), TStandardExecutionStrategy.Create));
|
||||
end;
|
||||
|
||||
function TAstEnvironment.CreateEnvironment: TAstEnvironment;
|
||||
@@ -393,50 +379,6 @@ begin
|
||||
Result := TDebugEvaluatorVisitor.Create(AScope, FLog, FShowScope, 0);
|
||||
end;
|
||||
|
||||
{ TMacroRegistryImpl }
|
||||
|
||||
constructor TMacroRegistryImpl.Create(AParent: IMacroRegistry);
|
||||
begin
|
||||
inherited Create;
|
||||
FParent := AParent;
|
||||
FMacros := TDictionary<string, IMacroDefinitionNode>.Create;
|
||||
end;
|
||||
|
||||
destructor TMacroRegistryImpl.Destroy;
|
||||
begin
|
||||
FMacros.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TMacroRegistryImpl.GetParent: IMacroRegistry;
|
||||
begin
|
||||
Result := FParent;
|
||||
end;
|
||||
|
||||
procedure TMacroRegistryImpl.Define(const Node: IMacroDefinitionNode);
|
||||
begin
|
||||
FMacros.AddOrSetValue(Node.Name.Name, Node);
|
||||
end;
|
||||
|
||||
function TMacroRegistryImpl.Find(const Name: string): IMacroDefinitionNode;
|
||||
var
|
||||
current: IMacroRegistry;
|
||||
begin
|
||||
current := Self;
|
||||
while Assigned(current) do
|
||||
begin
|
||||
if (current as TMacroRegistryImpl).FMacros.TryGetValue(Name, Result) then
|
||||
exit;
|
||||
current := current.Parent;
|
||||
end;
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
function TMacroRegistryImpl.CreateChildRegistry: IMacroRegistry;
|
||||
begin
|
||||
Result := TMacroRegistryImpl.Create(Self);
|
||||
end;
|
||||
|
||||
{ TFunctionDefinitionRegistry }
|
||||
|
||||
constructor TFunctionDefinitionRegistry.Create;
|
||||
@@ -514,7 +456,7 @@ end;
|
||||
|
||||
function TEnvironment.CreateEnvironment: IEnvironment;
|
||||
begin
|
||||
Result := TEnvironment.Create(TAst.CreateScope(FRootScope), TMacroRegistryImpl.Create(FMacroRegistry), FExecutionStrategy);
|
||||
Result := TEnvironment.Create(TAst.CreateScope(FRootScope), TMacroRegistry.Create(FMacroRegistry), FExecutionStrategy);
|
||||
end;
|
||||
|
||||
function TEnvironment.Compile(
|
||||
|
||||
@@ -168,6 +168,7 @@ begin
|
||||
TScalar.TKind.Ordinal: Result := AValue.AsScalar.Value.AsInt64 <> 0;
|
||||
TScalar.TKind.Float: Result := AValue.AsScalar.Value.AsDouble <> 0.0;
|
||||
TScalar.TKind.Keyword: Result := AValue.AsScalar.Value.AsInt64 <> 0;
|
||||
TScalar.TKind.Boolean: Result := AValue.AsScalar.Value.AsInt64 <> 0;
|
||||
else
|
||||
Result := false;
|
||||
end;
|
||||
@@ -392,10 +393,13 @@ end;
|
||||
|
||||
function TEvaluatorVisitor.VisitAssignment(const Node: IAssignmentNode): TDataValue;
|
||||
begin
|
||||
// Evaluate the new value.
|
||||
if Node.Target.Kind <> akIdentifier then
|
||||
raise ETypeException.Create('Runtime Error: Assignment target must be an identifier.');
|
||||
|
||||
// Evaluate value
|
||||
Result := Node.Value.Accept(Self);
|
||||
// Assign it.
|
||||
FScope[Node.Identifier.Address] := Result;
|
||||
// Assign
|
||||
FScope[Node.Target.AsIdentifier.Address] := Result;
|
||||
end;
|
||||
|
||||
function TEvaluatorVisitor.VisitConstant(const Node: IConstantNode): TDataValue;
|
||||
@@ -561,6 +565,9 @@ function TEvaluatorVisitor.VisitVariableDeclaration(const Node: IVariableDeclara
|
||||
var
|
||||
address: TResolvedAddress;
|
||||
begin
|
||||
if Node.Target.Kind <> akIdentifier then
|
||||
raise ETypeException.Create('Runtime Error: Variable declaration target must be an identifier.');
|
||||
|
||||
// 1. Evaluate Initializer
|
||||
if Assigned(Node.Initializer) then
|
||||
Result := Node.Initializer.Accept(Self)
|
||||
@@ -568,7 +575,7 @@ begin
|
||||
Result := TDataValue.Void;
|
||||
|
||||
// 2. Get Address (assigned by Binder)
|
||||
address := Node.Identifier.Address;
|
||||
address := Node.Target.AsIdentifier.Address;
|
||||
|
||||
// 3. Store Value
|
||||
if Node.IsBoxed then
|
||||
|
||||
@@ -319,7 +319,7 @@ function TJsonAstConverter.VisitVariableDeclaration(const Node: IVariableDeclara
|
||||
var
|
||||
identObj, initObj: TJSONObject;
|
||||
begin
|
||||
identObj := Accept(Node.Identifier);
|
||||
identObj := Accept(Node.Target);
|
||||
initObj := Accept(Node.Initializer); // Accept handles nil
|
||||
|
||||
Result := TJSONObject.Create;
|
||||
@@ -336,7 +336,7 @@ function TJsonAstConverter.VisitAssignment(const Node: IAssignmentNode): TJSONOb
|
||||
var
|
||||
identObj, valueObj: TJSONObject;
|
||||
begin
|
||||
identObj := Accept(Node.Identifier);
|
||||
identObj := Accept(Node.Target);
|
||||
valueObj := Accept(Node.Value);
|
||||
|
||||
Result := TJSONObject.Create;
|
||||
|
||||
@@ -287,21 +287,21 @@ type
|
||||
|
||||
IVariableDeclarationNode = interface(IAstTypedNode)
|
||||
{$region 'private'}
|
||||
function GetIdentifier: IIdentifierNode;
|
||||
function GetTarget: IAstNode;
|
||||
function GetInitializer: IAstNode;
|
||||
function GetIsBoxed: Boolean;
|
||||
{$endregion}
|
||||
property Identifier: IIdentifierNode read GetIdentifier;
|
||||
property Target: IAstNode read GetTarget;
|
||||
property Initializer: IAstNode read GetInitializer;
|
||||
property IsBoxed: Boolean read GetIsBoxed;
|
||||
end;
|
||||
|
||||
IAssignmentNode = interface(IAstTypedNode)
|
||||
{$region 'private'}
|
||||
function GetIdentifier: IIdentifierNode;
|
||||
function GetTarget: IAstNode;
|
||||
function GetValue: IAstNode;
|
||||
{$endregion}
|
||||
property Identifier: IIdentifierNode read GetIdentifier;
|
||||
property Target: IAstNode read GetTarget;
|
||||
property Value: IAstNode read GetValue;
|
||||
end;
|
||||
|
||||
|
||||
@@ -574,20 +574,15 @@ begin
|
||||
end
|
||||
else if SameText(head.Token.Text, 'def') then
|
||||
begin
|
||||
// Validate argument count for 'def' special form.
|
||||
// Identifier check removed to support macros (e.g. def ~x 1)
|
||||
if not (Length(tailNodes) in [1, 2]) then
|
||||
raise Exception.CreateFmt(
|
||||
'Syntax Error: ''def'' requires an identifier and an optional initializer (1 or 2 arguments), but got %d.',
|
||||
[Length(tailNodes)]);
|
||||
|
||||
if tailTokens[0].Kind <> tkIdentifier then
|
||||
raise Exception.Create('Syntax Error: Expected an identifier for def statement.');
|
||||
raise Exception.CreateFmt('Syntax Error: ''def'' requires a target and an optional initializer.', []);
|
||||
|
||||
initializer := nil;
|
||||
if Length(tailNodes) = 2 then
|
||||
initializer := tailNodes[1];
|
||||
|
||||
Result := TAst.VarDecl(IIdentifierNode(tailNodes[0]), initializer);
|
||||
Result := TAst.VarDecl(tailNodes[0], initializer);
|
||||
end
|
||||
else if SameText(head.Token.Text, 'defmacro') then
|
||||
begin
|
||||
@@ -606,11 +601,11 @@ begin
|
||||
end
|
||||
else if SameText(head.Token.Text, 'assign') then
|
||||
begin
|
||||
// Identifier check removed
|
||||
if Length(tailNodes) <> 2 then
|
||||
raise Exception.Create('Syntax Error: ''assign'' requires exactly 2 arguments (identifier and value).');
|
||||
if tailTokens[0].Kind <> tkIdentifier then
|
||||
raise Exception.Create('Syntax Error: Expected an identifier for assignment.');
|
||||
Result := TAst.Assign(IIdentifierNode(tailNodes[0]), tailNodes[1]);
|
||||
raise Exception.Create('Syntax Error: ''assign'' requires exactly 2 arguments (target and value).');
|
||||
|
||||
Result := TAst.Assign(tailNodes[0], tailNodes[1]);
|
||||
end
|
||||
else if SameText(head.Token.Text, 'fn') then
|
||||
begin
|
||||
@@ -988,7 +983,7 @@ end;
|
||||
procedure TPrettyPrintVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode);
|
||||
begin
|
||||
Append('(def ');
|
||||
Node.Identifier.Accept(Self);
|
||||
Node.Target.Accept(Self);
|
||||
if Assigned(Node.Initializer) then
|
||||
begin
|
||||
Append(' ');
|
||||
@@ -1000,7 +995,7 @@ end;
|
||||
procedure TPrettyPrintVisitor.VisitAssignment(const Node: IAssignmentNode);
|
||||
begin
|
||||
Append('(assign ');
|
||||
Node.Identifier.Accept(Self);
|
||||
Node.Target.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Value.Accept(Self);
|
||||
Append(')');
|
||||
|
||||
@@ -545,35 +545,32 @@ end;
|
||||
|
||||
function TAstTransformer.VisitVariableDeclaration(const Node: IVariableDeclarationNode): IAstNode;
|
||||
var
|
||||
newIdent: IIdentifierNode;
|
||||
newTarget: IAstNode;
|
||||
newInit: IAstNode;
|
||||
begin
|
||||
// No longer cast to concrete class, use interface
|
||||
newIdent := Accept(Node.Identifier).AsIdentifier;
|
||||
newInit := Accept(Node.Initializer); // Accept handles nil
|
||||
newTarget := Accept(Node.Target);
|
||||
newInit := Accept(Node.Initializer);
|
||||
|
||||
if (newIdent = Node.Identifier) and (newInit = Node.Initializer) then
|
||||
if (newTarget = Node.Target) and (newInit = Node.Initializer) then
|
||||
Result := Node
|
||||
else
|
||||
begin
|
||||
// Use TAst factory and copy properties via interface getters
|
||||
Result := TAst.VarDecl(newIdent, newInit, Node.StaticType, Node.IsBoxed);
|
||||
Result := TAst.VarDecl(newTarget, newInit, Node.StaticType, Node.IsBoxed);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TAstTransformer.VisitAssignment(const Node: IAssignmentNode): IAstNode;
|
||||
var
|
||||
newIdent: IIdentifierNode;
|
||||
newTarget: IAstNode;
|
||||
newValue: IAstNode;
|
||||
begin
|
||||
newTarget := Accept(Node.Target);
|
||||
newValue := Accept(Node.Value);
|
||||
newIdent := Accept(Node.Identifier).AsIdentifier;
|
||||
|
||||
if (newValue = Node.Value) and (newIdent = Node.Identifier) then
|
||||
if (newTarget = Node.Target) and (newValue = Node.Value) then
|
||||
Result := Node
|
||||
else
|
||||
// Use TAst factory
|
||||
Result := TAst.Assign(newIdent, newValue, Node.StaticType);
|
||||
Result := TAst.Assign(newTarget, newValue, Node.StaticType);
|
||||
end;
|
||||
|
||||
function TAstTransformer.VisitMacroDefinition(const Node: IMacroDefinitionNode): IAstNode;
|
||||
|
||||
+20
-34
@@ -95,17 +95,13 @@ type
|
||||
class function Block(const AExpressions: array of IAstNode; const AStaticType: IStaticType = nil): IBlockExpressionNode; static;
|
||||
|
||||
class function VarDecl(
|
||||
const AIdentifier: IIdentifierNode;
|
||||
const AIdentifier: IAstNode;
|
||||
AInitializer: IAstNode = nil;
|
||||
const AStaticType: IStaticType = nil;
|
||||
const AIsBoxed: Boolean = False
|
||||
): IVariableDeclarationNode; static;
|
||||
|
||||
class function Assign(
|
||||
const AIdentifier: IIdentifierNode;
|
||||
const AValue: IAstNode;
|
||||
const AStaticType: IStaticType = nil
|
||||
): IAssignmentNode; static;
|
||||
class function Assign(const ATarget, AValue: IAstNode; const AStaticType: IStaticType = nil): IAssignmentNode; static;
|
||||
class function AssignResult(const AValue: IAstNode): IAssignmentNode; static; deprecated;
|
||||
class function Indexer(const ABase: IAstNode; const AIndex: IAstNode; const AStaticType: IStaticType = nil): IIndexerNode; static;
|
||||
class function MemberAccess(
|
||||
@@ -249,23 +245,17 @@ type
|
||||
function AsFunctionCall: IFunctionCallNode; override;
|
||||
end;
|
||||
|
||||
// ... (Other node definitions unchanged) ...
|
||||
TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode)
|
||||
private
|
||||
FIdentifier: IIdentifierNode;
|
||||
FInitializer: IAstNode;
|
||||
FTarget: IAstNode;
|
||||
FIsBoxed: Boolean;
|
||||
function GetIdentifier: IIdentifierNode;
|
||||
function GetTarget: IAstNode;
|
||||
function GetInitializer: IAstNode;
|
||||
function GetIsBoxed: Boolean;
|
||||
function GetKind: TAstNodeKind; override;
|
||||
public
|
||||
constructor Create(
|
||||
const AIdentifier: IIdentifierNode;
|
||||
AInitializer: IAstNode;
|
||||
const AStaticType: IStaticType;
|
||||
const AIsBoxed: Boolean
|
||||
);
|
||||
constructor Create(const ATarget: IAstNode; AInitializer: IAstNode; const AStaticType: IStaticType; const AIsBoxed: Boolean);
|
||||
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||
function AsVariableDeclaration: IVariableDeclarationNode; override;
|
||||
end;
|
||||
@@ -440,16 +430,16 @@ type
|
||||
|
||||
TAssignmentNode = class(TAstTypedNode, IAssignmentNode)
|
||||
private
|
||||
FIdentifier: IIdentifierNode;
|
||||
FTarget: IAstNode;
|
||||
FValue: IAstNode;
|
||||
function GetIdentifier: IIdentifierNode;
|
||||
function GetTarget: IAstNode;
|
||||
function GetValue: IAstNode;
|
||||
function GetKind: TAstNodeKind; override;
|
||||
public
|
||||
constructor Create(const AIdentifier: IIdentifierNode; const AValue: IAstNode; const AStaticType: IStaticType);
|
||||
constructor Create(const ATarget: IAstNode; const AValue: IAstNode; const AStaticType: IStaticType);
|
||||
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||
function AsAssignment: IAssignmentNode; override;
|
||||
property Identifier: IIdentifierNode read FIdentifier;
|
||||
property Target: IAstNode read FTarget;
|
||||
property Value: IAstNode read FValue;
|
||||
end;
|
||||
|
||||
@@ -619,15 +609,11 @@ begin
|
||||
);
|
||||
end;
|
||||
|
||||
class function TAst.Assign(
|
||||
const AIdentifier: IIdentifierNode;
|
||||
const AValue: IAstNode;
|
||||
const AStaticType: IStaticType = nil
|
||||
): IAssignmentNode;
|
||||
class function TAst.Assign(const ATarget, AValue: IAstNode; const AStaticType: IStaticType = nil): IAssignmentNode;
|
||||
begin
|
||||
Result :=
|
||||
TAssignmentNode.Create(
|
||||
AIdentifier,
|
||||
ATarget,
|
||||
AValue,
|
||||
if AStaticType <> nil then AStaticType
|
||||
else TTypes.Unknown
|
||||
@@ -884,7 +870,7 @@ begin
|
||||
end;
|
||||
|
||||
class function TAst.VarDecl(
|
||||
const AIdentifier: IIdentifierNode;
|
||||
const AIdentifier: IAstNode;
|
||||
AInitializer: IAstNode = nil;
|
||||
const AStaticType: IStaticType = nil;
|
||||
const AIsBoxed: Boolean = False
|
||||
@@ -1614,14 +1600,14 @@ end;
|
||||
{ TVariableDeclarationNode }
|
||||
|
||||
constructor TVariableDeclarationNode.Create(
|
||||
const AIdentifier: IIdentifierNode;
|
||||
const ATarget: IAstNode;
|
||||
AInitializer: IAstNode;
|
||||
const AStaticType: IStaticType;
|
||||
const AIsBoxed: Boolean
|
||||
);
|
||||
begin
|
||||
inherited Create(AStaticType);
|
||||
FIdentifier := AIdentifier;
|
||||
FTarget := ATarget;
|
||||
FInitializer := AInitializer;
|
||||
FIsBoxed := AIsBoxed;
|
||||
end;
|
||||
@@ -1636,9 +1622,9 @@ begin
|
||||
Result := Self;
|
||||
end;
|
||||
|
||||
function TVariableDeclarationNode.GetIdentifier: IIdentifierNode;
|
||||
function TVariableDeclarationNode.GetTarget: IAstNode;
|
||||
begin
|
||||
Result := FIdentifier;
|
||||
Result := FTarget;
|
||||
end;
|
||||
|
||||
function TVariableDeclarationNode.GetInitializer: IAstNode;
|
||||
@@ -1658,10 +1644,10 @@ end;
|
||||
|
||||
{ TAssignmentNode }
|
||||
|
||||
constructor TAssignmentNode.Create(const AIdentifier: IIdentifierNode; const AValue: IAstNode; const AStaticType: IStaticType);
|
||||
constructor TAssignmentNode.Create(const ATarget: IAstNode; const AValue: IAstNode; const AStaticType: IStaticType);
|
||||
begin
|
||||
inherited Create(AStaticType);
|
||||
FIdentifier := AIdentifier;
|
||||
FTarget := ATarget;
|
||||
FValue := AValue;
|
||||
end;
|
||||
|
||||
@@ -1675,9 +1661,9 @@ begin
|
||||
Result := Self;
|
||||
end;
|
||||
|
||||
function TAssignmentNode.GetIdentifier: IIdentifierNode;
|
||||
function TAssignmentNode.GetTarget: IAstNode;
|
||||
begin
|
||||
Result := FIdentifier;
|
||||
Result := FTarget;
|
||||
end;
|
||||
|
||||
function TAssignmentNode.GetValue: IAstNode;
|
||||
|
||||
Reference in New Issue
Block a user