Ast environments
This commit is contained in:
@@ -12,11 +12,12 @@ uses
|
||||
Myc.Ast.Visitor,
|
||||
Myc.Ast.Scope,
|
||||
Myc.Ast.Types,
|
||||
Myc.Ast;
|
||||
Myc.Ast,
|
||||
Myc.Ast.Environment; // Added for IMacroRegistry
|
||||
|
||||
type
|
||||
IAstMacroExpander = interface(IAstVisitor)
|
||||
// Signatur geändert: Descriptor wird nicht mehr zurückgegeben
|
||||
// Signatur geaendert: Descriptor wird nicht mehr zurueckgegeben
|
||||
function Execute(const RootNode: IAstNode): IAstNode;
|
||||
end;
|
||||
|
||||
@@ -46,28 +47,10 @@ type
|
||||
// This transformer traverses the entire AST *before* the binder,
|
||||
// to find and expand macros.
|
||||
TMacroExpander = class(TAstTransformer, IAstMacroExpander)
|
||||
type
|
||||
TMacroRegistry = class
|
||||
private
|
||||
FParent: TMacroRegistry;
|
||||
FMacros: TDictionary<string, IMacroDefinitionNode>;
|
||||
public
|
||||
constructor Create(AParent: TMacroRegistry);
|
||||
destructor Destroy; override;
|
||||
procedure Define(const Node: IMacroDefinitionNode);
|
||||
function Find(const Name: string): IMacroDefinitionNode;
|
||||
end;
|
||||
|
||||
strict private
|
||||
class var
|
||||
FGlobalMacroRegistry: TMacroRegistry;
|
||||
class constructor CreateClass;
|
||||
class destructor DestroyClass;
|
||||
|
||||
private
|
||||
FInitialScope: IExecutionScope;
|
||||
|
||||
FCurrentMacroRegistry: TMacroRegistry;
|
||||
FCurrentMacroRegistry: IMacroRegistry; // Changed from TMacroRegistry
|
||||
|
||||
FEvaluatorFactory: TEvaluatorFactory;
|
||||
|
||||
@@ -87,18 +70,23 @@ type
|
||||
function VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; override;
|
||||
|
||||
public
|
||||
constructor Create(const AInitialScope: IExecutionScope; const AEvaluatorFactory: TEvaluatorFactory);
|
||||
destructor Destroy; override;
|
||||
// Updated Constructor
|
||||
constructor Create(
|
||||
const ARootRegistry: IMacroRegistry;
|
||||
const AInitialScope: IExecutionScope;
|
||||
const AEvaluatorFactory: TEvaluatorFactory
|
||||
);
|
||||
destructor Destroy; override; // Modified
|
||||
|
||||
function Execute(const RootNode: IAstNode): IAstNode;
|
||||
|
||||
// Updated static helper
|
||||
class function ExpandMacros(
|
||||
const InitialScope: IExecutionScope;
|
||||
const ARootRegistry: IMacroRegistry; // Added
|
||||
const AInitialScope: IExecutionScope;
|
||||
const RootNode: IAstNode;
|
||||
const EvaluatorFactory: TEvaluatorFactory
|
||||
): IAstNode; static;
|
||||
|
||||
class property GlobalMacroRegistry: TMacroRegistry read FGlobalMacroRegistry;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@@ -109,40 +97,6 @@ uses
|
||||
Myc.Ast.Evaluator, // Required for TEvaluatorVisitor.Execute
|
||||
Myc.Data.Keyword;
|
||||
|
||||
{ TMacroRegistry }
|
||||
|
||||
constructor TMacroExpander.TMacroRegistry.Create(AParent: TMacroRegistry);
|
||||
begin
|
||||
inherited Create;
|
||||
FParent := AParent;
|
||||
FMacros := TDictionary<string, IMacroDefinitionNode>.Create;
|
||||
end;
|
||||
|
||||
destructor TMacroExpander.TMacroRegistry.Destroy;
|
||||
begin
|
||||
FMacros.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TMacroExpander.TMacroRegistry.Define(const Node: IMacroDefinitionNode);
|
||||
begin
|
||||
FMacros.AddOrSetValue(Node.Name.Name, Node);
|
||||
end;
|
||||
|
||||
function TMacroExpander.TMacroRegistry.Find(const Name: string): IMacroDefinitionNode;
|
||||
var
|
||||
current: TMacroRegistry;
|
||||
begin
|
||||
current := Self;
|
||||
while Assigned(current) do
|
||||
begin
|
||||
if current.FMacros.TryGetValue(Name, Result) then
|
||||
exit;
|
||||
current := current.FParent;
|
||||
end;
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
{ TExpansionVisitor }
|
||||
|
||||
constructor TExpansionVisitor.Create(const AMacroScope: IExecutionScope; const AEvaluate: TEvaluateProc);
|
||||
@@ -288,57 +242,52 @@ end;
|
||||
|
||||
{ TMacroExpander }
|
||||
|
||||
constructor TMacroExpander.Create(const AInitialScope: IExecutionScope; const AEvaluatorFactory: TEvaluatorFactory);
|
||||
constructor TMacroExpander.Create(
|
||||
const ARootRegistry: IMacroRegistry;
|
||||
const AInitialScope: IExecutionScope;
|
||||
const AEvaluatorFactory: TEvaluatorFactory
|
||||
);
|
||||
begin
|
||||
inherited Create;
|
||||
Assert(Assigned(ARootRegistry));
|
||||
Assert(Assigned(AInitialScope));
|
||||
Assert(Assigned(AEvaluatorFactory));
|
||||
|
||||
FInitialScope := AInitialScope;
|
||||
FEvaluatorFactory := AEvaluatorFactory;
|
||||
|
||||
// Erzeugt die Root-Registry für Makros
|
||||
FCurrentMacroRegistry := TMacroRegistry.Create(FGlobalMacroRegistry);
|
||||
end;
|
||||
|
||||
class constructor TMacroExpander.CreateClass;
|
||||
begin
|
||||
FGlobalMacroRegistry := TMacroRegistry.Create(nil);
|
||||
// Creates the root registry for this specific compilation run,
|
||||
// parented to the global registry from the environment.
|
||||
FCurrentMacroRegistry := ARootRegistry.CreateChildRegistry;
|
||||
end;
|
||||
|
||||
destructor TMacroExpander.Destroy;
|
||||
begin
|
||||
FCurrentMacroRegistry.Free;
|
||||
// FCurrentMacroRegistry is an interface, managed by ARC
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
class destructor TMacroExpander.DestroyClass;
|
||||
begin
|
||||
FGlobalMacroRegistry.Free;
|
||||
end;
|
||||
|
||||
procedure TMacroExpander.EnterMacroScope;
|
||||
begin
|
||||
// Erstellt eine neue Registry mit der aktuellen als Parent
|
||||
FCurrentMacroRegistry := TMacroRegistry.Create(FCurrentMacroRegistry);
|
||||
// Creates a new registry with the current as Parent
|
||||
FCurrentMacroRegistry := FCurrentMacroRegistry.CreateChildRegistry;
|
||||
end;
|
||||
|
||||
procedure TMacroExpander.ExitMacroScope;
|
||||
var
|
||||
oldRegistry: TMacroRegistry;
|
||||
begin
|
||||
oldRegistry := FCurrentMacroRegistry;
|
||||
FCurrentMacroRegistry := oldRegistry.FParent;
|
||||
oldRegistry.Free;
|
||||
// Revert to parent registry. ARC will free the old child.
|
||||
FCurrentMacroRegistry := FCurrentMacroRegistry.Parent;
|
||||
end;
|
||||
|
||||
class function TMacroExpander.ExpandMacros(
|
||||
const InitialScope: IExecutionScope;
|
||||
const ARootRegistry: IMacroRegistry;
|
||||
const AInitialScope: IExecutionScope;
|
||||
const RootNode: IAstNode;
|
||||
const EvaluatorFactory: TEvaluatorFactory
|
||||
): IAstNode;
|
||||
begin
|
||||
// IAstMacroExpander.Execute gibt keinen Descriptor mehr zurück
|
||||
var expander := TMacroExpander.Create(InitialScope, EvaluatorFactory) as IAstMacroExpander;
|
||||
// IAstMacroExpander.Execute gibt keinen Descriptor mehr zurueck
|
||||
var expander := TMacroExpander.Create(ARootRegistry, AInitialScope, EvaluatorFactory) as IAstMacroExpander;
|
||||
Result := expander.Execute(RootNode);
|
||||
end;
|
||||
|
||||
@@ -400,7 +349,7 @@ begin
|
||||
// --- It is a macro, expand it ---
|
||||
|
||||
// 1. Create the temporary scope for the macro parameters
|
||||
// It must be parented to the *initial* scope to find other macros/globals.
|
||||
// It must be parented to the *initial* scope to find other globals.
|
||||
var expansionScope := TAst.CreateScope(FInitialScope);
|
||||
var params := macroDef.Parameters;
|
||||
if Length(Node.Arguments) <> Length(params) then
|
||||
@@ -422,8 +371,8 @@ begin
|
||||
boundSubAst: IAstNode;
|
||||
begin
|
||||
// This is the compile-time evaluation (Binder + Evaluator)
|
||||
// Es wird der 'expansionScope' verwendet, der die AST-Argumente enthält
|
||||
boundSubAst := TAstBinder.Bind(expansionScope, ANodeToEvaluate, subDescriptor);
|
||||
// Es wird der 'expansionScope' verwendet, der die AST-Argumente enthaelt
|
||||
boundSubAst := TAstBinder.Bind(expansionScope.CreateDescriptor, ANodeToEvaluate, subDescriptor);
|
||||
|
||||
// Create eval scope from the new descriptor, parented to the expansion scope
|
||||
evalScope := subDescriptor.CreateScope(expansionScope);
|
||||
|
||||
Reference in New Issue
Block a user