Compiler exceptions

This commit is contained in:
Michael Schimmel
2025-11-25 15:27:57 +01:00
parent d84509c034
commit 4e508d90a5
8 changed files with 62 additions and 28 deletions
+16 -5
View File
@@ -16,6 +16,9 @@ uses
Myc.Ast.Compiler.Binder;
type
// Exception specific to specialization errors (e.g. internal compilation failures)
ESpecializerException = class(EAstException);
IAstSpecializer = interface(IAstVisitor)
function Execute(const RootNode: IAstNode): IAstNode;
end;
@@ -90,6 +93,12 @@ constructor TStaticSpecializer.Create(
);
begin
inherited Create;
if not Assigned(AMonomorphCache) then
raise ESpecializerException.Create('MonomorphCache cannot be nil.');
if not Assigned(AFunctionRegistry) then
raise ESpecializerException.Create('FunctionRegistry cannot be nil.');
// CompileFunc can be nil if no recursion is supported, but usually required.
FMonomorphCache := AMonomorphCache;
FFunctionRegistry := AFunctionRegistry;
FCompileFunc := ACompileFunc;
@@ -178,7 +187,6 @@ begin
if FMonomorphCache.TryGetFunction(key, specializedMethod) then
begin
// 4a. Cache Hit (Environment)
// Propagate IsPure flag from cache to AST node
Result :=
TAst.FunctionCall(
newCallee,
@@ -198,7 +206,6 @@ begin
// 5a. Cache Hit (RTL)
FMonomorphCache.Add(key, specializedMethod);
// Propagate IsPure flag from RTL definition to AST node
Result :=
TAst.FunctionCall(
newCallee,
@@ -228,17 +235,21 @@ begin
end;
// 6a. Compile func with KNOWN TYPES
// This recursively triggers Bind -> Check -> Specialize -> Purity Inference for the callee body!
if not Assigned(FCompileFunc) then
raise ESpecializerException.Create('Cannot specialize user function: Compiler callback is missing.');
var compiled := FCompileFunc(funcDef, argTypes);
// Safety check: The recursive compiler MUST produce a valid function pointer
if not Assigned(compiled.Func) then
raise ESpecializerException.CreateFmt('Internal Error: Failed to compile specialization for "%s"', [funcName]);
// 6b. Store in cache
// Get the return type from the *full function type* returned by Compile
var returnType := compiled.StaticType.Signatures[0].ReturnType;
specializedMethod := TSpecializedMethod.Create(compiled.Func, returnType, compiled.IsPure);
FMonomorphCache.Add(key, specializedMethod);
// 6c. Return the new node
// Propagate the inferred IsPure flag to the AST node
Result := TAst.FunctionCall(newCallee, newArgs, returnType, Node.IsTailCall, compiled.Func, compiled.IsPure);
exit;
end;