unit Myc.Ast.Compiler.Lowering; interface uses System.SysUtils, System.Classes, System.Generics.Collections, Myc.Data.Scalar, Myc.Data.Value, Myc.Ast.Nodes, // Provides EAstException Myc.Ast.Visitor, Myc.Ast.Scope, Myc.Ast.Types, Myc.Ast; type // Exception specific to AST lowering/rewriting errors ELoweringException = class(EAstException); IAstLowerer = interface(IAstVisitor) function Execute(const RootNode: IAstNode): IAstNode; end; // This transformer runs *after* TypeChecker (Phase 3). // It "lowers" the AST by rewriting complex nodes into simpler ones // that the evaluator can understand (e.g., operator folding). TAstLowerer = class(TAstTransformer, IAstLowerer) private FBinaryOperators: TDictionary; FUnaryOperators: TDictionary; protected // Implement Visit methods here when specific lowering logic is added // (e.g. converting operator function calls to specific node types if added in future) public constructor Create; destructor Destroy; override; function Execute(const RootNode: IAstNode): IAstNode; class function Lower(const RootNode: IAstNode): IAstNode; static; end; implementation uses System.Generics.Defaults, Myc.Data.Keyword; { TAstLowerer } constructor TAstLowerer.Create; begin inherited Create; // Operator folding maps (Reserved for future static optimization) FBinaryOperators := TDictionary.Create; FBinaryOperators.Add('+', TScalar.TBinaryOp.Add); FBinaryOperators.Add('-', TScalar.TBinaryOp.Subtract); FBinaryOperators.Add('*', TScalar.TBinaryOp.Multiply); FBinaryOperators.Add('/', TScalar.TBinaryOp.Divide); FBinaryOperators.Add('=', TScalar.TBinaryOp.Equal); FBinaryOperators.Add('<>', TScalar.TBinaryOp.NotEqual); FBinaryOperators.Add('<', TScalar.TBinaryOp.Less); FBinaryOperators.Add('<=', TScalar.TBinaryOp.LessOrEqual); FBinaryOperators.Add('>', TScalar.TBinaryOp.Greater); FBinaryOperators.Add('>=', TScalar.TBinaryOp.GreaterOrEqual); FUnaryOperators := TDictionary.Create; FUnaryOperators.Add('not', TScalar.TUnaryOp.Not); end; destructor TAstLowerer.Destroy; begin FUnaryOperators.Free; FBinaryOperators.Free; inherited; end; class function TAstLowerer.Lower(const RootNode: IAstNode): IAstNode; begin var lowerer := TAstLowerer.Create as IAstLowerer; try Result := lowerer.Execute(RootNode); except on E: Exception do raise ELoweringException.Create('Internal Error during AST Lowering: ' + E.Message); end; end; function TAstLowerer.Execute(const RootNode: IAstNode): IAstNode; begin if not Assigned(RootNode) then exit(nil); Result := Accept(RootNode); if not Assigned(Result) then Result := TAst.Block([]); end; end.