Compiler errors
This commit is contained in:
@@ -39,7 +39,15 @@ type
|
||||
procedure SetExecutionStrategy(const AStrategy: IExecutionStrategy);
|
||||
|
||||
function ExpandMacros(const Node: IAstNode): IAstNode;
|
||||
function Bind(const Node: IAstNode; out Layout: IScopeLayout; const AArgTypes: TArray<IStaticType> = []): IAstNode;
|
||||
|
||||
// Updated Bind signature to accept Log
|
||||
function Bind(
|
||||
const Node: IAstNode;
|
||||
out Layout: IScopeLayout;
|
||||
const AArgTypes: TArray<IStaticType>;
|
||||
const Log: ICompilerLog
|
||||
): IAstNode;
|
||||
|
||||
function Specialize(const Node: IAstNode): IAstNode;
|
||||
|
||||
function Compile(const Node: IFunctionDefinition; const ArgTypes: TArray<IStaticType> = []): TCompiledFunction;
|
||||
@@ -162,7 +170,14 @@ type
|
||||
procedure SetExecutionStrategy(const AStrategy: IExecutionStrategy);
|
||||
|
||||
function ExpandMacros(const Node: IAstNode): IAstNode;
|
||||
function Bind(const Node: IAstNode; out Layout: IScopeLayout; const ArgTypes: TArray<IStaticType>): IAstNode;
|
||||
|
||||
function Bind(
|
||||
const Node: IAstNode;
|
||||
out Layout: IScopeLayout;
|
||||
const ArgTypes: TArray<IStaticType>;
|
||||
const Log: ICompilerLog
|
||||
): IAstNode;
|
||||
|
||||
function Specialize(const Node: IAstNode): IAstNode;
|
||||
|
||||
function Compile(const Node: IFunctionDefinition; const ArgTypes: TArray<IStaticType>): TCompiledFunction; overload;
|
||||
@@ -227,8 +242,6 @@ end;
|
||||
procedure TAstEnvironment.Define(const Name: String; const AScript: IAstNode);
|
||||
begin
|
||||
var compiled := Compile(AScript);
|
||||
// Note: Define now potentially handles Pure flags internally via the Node metadata,
|
||||
// but the runtime value is just the TDataValue.
|
||||
RootScope.Define(Name, compiled.Func([]), compiled.StaticType);
|
||||
end;
|
||||
|
||||
@@ -318,13 +331,18 @@ begin
|
||||
Result := FMonomorphCache;
|
||||
end;
|
||||
|
||||
function TEnvironment.Bind(const Node: IAstNode; out Layout: IScopeLayout; const ArgTypes: TArray<IStaticType>): IAstNode;
|
||||
function TEnvironment.Bind(
|
||||
const Node: IAstNode;
|
||||
out Layout: IScopeLayout;
|
||||
const ArgTypes: TArray<IStaticType>;
|
||||
const Log: ICompilerLog
|
||||
): IAstNode;
|
||||
begin
|
||||
// 1. Bind (produces Layout and Bound AST with Addresses)
|
||||
var boundAst := TAstBinder.Bind(FRootScope.Descriptor.Layout, Node, Layout, FFunctionRegistry, ArgTypes);
|
||||
var boundAst := TAstBinder.Bind(FRootScope.Descriptor.Layout, Node, Layout, Log, FFunctionRegistry, ArgTypes);
|
||||
|
||||
// 2. Check Types (produces Typed AST with Descriptors baked into nodes)
|
||||
Result := TTypeChecker.CheckTypes(boundAst, Layout);
|
||||
Result := TTypeChecker.CheckTypes(boundAst, Layout, Log);
|
||||
end;
|
||||
|
||||
function TEnvironment.GetMacroRegistry: IMacroRegistry;
|
||||
@@ -356,21 +374,38 @@ var
|
||||
|
||||
typedNode, specialized, tcoOptimized: IAstNode;
|
||||
isPure: Boolean;
|
||||
begin
|
||||
// Same steps as above, but Node is already a definition (Lambda)
|
||||
var expanded := ExpandMacros(Node);
|
||||
typedNode := Bind(expanded, layout, ArgTypes);
|
||||
|
||||
log: ICompilerLog;
|
||||
begin
|
||||
log := TCompilerLog.Create;
|
||||
|
||||
// 1. Expand Macros
|
||||
var expanded := ExpandMacros(Node);
|
||||
|
||||
// 2. Bind & TypeCheck (accumulating errors)
|
||||
typedNode := Bind(expanded, layout, ArgTypes, log);
|
||||
|
||||
// 3. Check for compilation errors
|
||||
if log.HasErrors then
|
||||
raise ECompilationFailed.Create(log.GetEntries);
|
||||
|
||||
// Note: If types are Unknown but no errors were logged (edge case), we proceed.
|
||||
// But Binder/TypeChecker logic ensures errors are logged for Unknowns that matter.
|
||||
|
||||
// 4. Specialization & Optimization
|
||||
descriptor := typedNode.AsLambdaExpression.Descriptor;
|
||||
// Descriptor might be nil if Bind failed badly, but HasErrors check above covers that.
|
||||
Assert(Assigned(descriptor));
|
||||
|
||||
funcType := typedNode.AsTypedNode.StaticType;
|
||||
|
||||
specialized := Specialize(typedNode);
|
||||
tcoOptimized := TAstTCO.Optimize(specialized);
|
||||
|
||||
// Purity Inference
|
||||
// 5. Purity Inference
|
||||
isPure := TPurityAnalyzer.IsPure(tcoOptimized.AsLambdaExpression.Body);
|
||||
|
||||
// 6. Generate Visitor/Closure
|
||||
var visitor := FExecutionStrategy.CreateVisitor(descriptor.CreateScope(FRootScope));
|
||||
var closure := tcoOptimized.Accept(visitor);
|
||||
|
||||
@@ -397,10 +432,18 @@ begin
|
||||
evaluator: IEvaluatorVisitor;
|
||||
boundSubAst: IAstNode;
|
||||
scratchScope: IExecutionScope;
|
||||
tempLog: ICompilerLog;
|
||||
begin
|
||||
// Create temporary log for the macro context
|
||||
tempLog := TCompilerLog.Create;
|
||||
|
||||
// 1. Binding
|
||||
// Note: Scope is dynamic (from TMacroExpander), so Descriptor.Layout describes current variables.
|
||||
boundSubAst := TAstBinder.Bind(Scope.Descriptor.Layout, ANode, tmpLayout);
|
||||
boundSubAst := TAstBinder.Bind(Scope.Descriptor.Layout, ANode, tmpLayout, tempLog);
|
||||
|
||||
// Macro execution is strictly fail-fast. If we can't bind arguments, we can't run the macro.
|
||||
if tempLog.HasErrors then
|
||||
raise EMacroException.Create('Macro Argument Error: ' + tempLog.GetEntries[0].Message);
|
||||
|
||||
// 2. Scope Matching
|
||||
// Create a child scope to ensure correct depth resolution (Binder sees Layout at depth 0 relative to itself)
|
||||
@@ -411,13 +454,7 @@ begin
|
||||
Result := evaluator.Execute(boundSubAst);
|
||||
end;
|
||||
|
||||
Result :=
|
||||
TMacroExpander.ExpandMacros(
|
||||
FMacroRegistry,
|
||||
FRootScope,
|
||||
Node,
|
||||
macroEvaluator // Injected single dependency
|
||||
);
|
||||
Result := TMacroExpander.ExpandMacros(FMacroRegistry, FRootScope, Node, macroEvaluator);
|
||||
end;
|
||||
|
||||
function TEnvironment.GetFunctionRegistry: IFunctionDefinitionRegistry;
|
||||
|
||||
Reference in New Issue
Block a user