90 lines
2.5 KiB
ObjectPascal
90 lines
2.5 KiB
ObjectPascal
unit Myc.Ast.Compiler.Lowering;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils,
|
|
System.Classes,
|
|
System.Generics.Collections,
|
|
Myc.Data.Scalar,
|
|
Myc.Data.Value,
|
|
Myc.Ast.Nodes,
|
|
Myc.Ast.Visitor,
|
|
Myc.Ast.Scope,
|
|
Myc.Ast.Types,
|
|
Myc.Ast;
|
|
|
|
type
|
|
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<string, TScalar.TBinaryOp>;
|
|
FUnaryOperators: TDictionary<string, TScalar.TUnaryOp>;
|
|
protected
|
|
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
|
|
FBinaryOperators := TDictionary<string, TScalar.TBinaryOp>.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<string, TScalar.TUnaryOp>.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;
|
|
Result := lowerer.Execute(RootNode);
|
|
end;
|
|
|
|
function TAstLowerer.Execute(const RootNode: IAstNode): IAstNode;
|
|
begin
|
|
Result := Accept(RootNode); // Use IAstNode-returning Accept
|
|
if not Assigned(Result) then
|
|
Result := TAst.Block([]);
|
|
end;
|
|
|
|
end.
|