diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/PbsFrontendCompiler.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/PbsFrontendCompiler.java index 9c691f31..7bce22e4 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/PbsFrontendCompiler.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/PbsFrontendCompiler.java @@ -183,14 +183,18 @@ public final class PbsFrontendCompiler { final NameTable nameTable, final DiagnosticSink diagnostics) { final var normalizedModuleKey = moduleKey == null ? "" : moduleKey; - final var hostByMethodName = new HashMap(); + final var hostByMethodName = new HashMap>(); for (final var hostBinding : reservedMetadata.hostMethodBindings()) { - hostByMethodName.put(hostBinding.sourceMethodName(), hostBinding); + hostByMethodName + .computeIfAbsent(nameTable.register(hostBinding.sourceMethodName()), ignored -> new ArrayList<>()) + .add(hostBinding); } - final var intrinsicByMethodName = new HashMap(); + final var intrinsicByMethodName = new HashMap>(); for (final var builtinType : reservedMetadata.builtinTypeSurfaces()) { for (final var intrinsicSurface : builtinType.intrinsics()) { - intrinsicByMethodName.put(intrinsicSurface.sourceMethodName(), intrinsicSurface); + intrinsicByMethodName + .computeIfAbsent(nameTable.register(intrinsicSurface.sourceMethodName()), ignored -> new ArrayList<>()) + .add(intrinsicSurface); } } final var callableIdTable = new CallableTable(); @@ -591,13 +595,41 @@ public final class PbsFrontendCompiler { private void lowerCallsite( final PbsAst.CallExpr callExpr, final ExecutableLoweringContext context) { - final var calleeName = extractSimpleCalleeName(callExpr.callee()); - if (calleeName == null || calleeName.isBlank()) { + final var calleeIdentity = resolveCalleeIdentity(callExpr.callee(), context.nameTable()); + if (calleeIdentity == null) { reportUnsupportedLowering("executable lowering requires resolvable callee identity", callExpr.span(), context); return; } - final var host = context.hostByMethodName().get(calleeName); - if (host != null) { + final var callableCandidates = context.callableIdsByNameAndArity().get( + new CallableResolutionKey(calleeIdentity.nameId(), callExpr.arguments().size())); + final var hostCandidates = context.hostByMethodName().getOrDefault(calleeIdentity.nameId(), List.of()); + final var intrinsicCandidates = context.intrinsicByMethodName().getOrDefault(calleeIdentity.nameId(), List.of()); + + var categoryCount = 0; + if (callableCandidates != null && !callableCandidates.isEmpty()) { + categoryCount++; + } + if (!hostCandidates.isEmpty()) { + categoryCount++; + } + if (!intrinsicCandidates.isEmpty()) { + categoryCount++; + } + if (categoryCount == 0) { + reportUnsupportedLowering("executable lowering requires resolvable callee identity", callExpr.span(), context); + return; + } + if (categoryCount > 1) { + reportUnsupportedLowering("executable lowering found ambiguous callsite category", callExpr.span(), context); + return; + } + + if (!hostCandidates.isEmpty()) { + if (hostCandidates.size() > 1) { + reportUnsupportedLowering("executable lowering found ambiguous host binding identity", callExpr.span(), context); + return; + } + final var host = hostCandidates.getFirst(); context.instructions().add(new IRBackendExecutableFunction.Instruction( IRBackendExecutableFunction.InstructionKind.CALL_HOST, "", @@ -613,8 +645,12 @@ public final class PbsFrontendCompiler { return; } - final var intrinsic = context.intrinsicByMethodName().get(calleeName); - if (intrinsic != null) { + if (!intrinsicCandidates.isEmpty()) { + if (intrinsicCandidates.size() > 1) { + reportUnsupportedLowering("executable lowering found ambiguous intrinsic identity", callExpr.span(), context); + return; + } + final var intrinsic = intrinsicCandidates.getFirst(); context.instructions().add(new IRBackendExecutableFunction.Instruction( IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC, "", @@ -628,21 +664,19 @@ public final class PbsFrontendCompiler { return; } - final var candidateCallableIds = context.callableIdsByNameAndArity().get( - new CallableResolutionKey(context.nameTable().register(calleeName), callExpr.arguments().size())); - if (candidateCallableIds == null || candidateCallableIds.isEmpty()) { - reportUnsupportedLowering("executable lowering requires resolvable callee identity", callExpr.span(), context); + if (callableCandidates == null || callableCandidates.isEmpty()) { + reportUnsupportedLowering("executable lowering requires resolvable callable identity", callExpr.span(), context); return; } - if (candidateCallableIds.size() > 1) { + if (callableCandidates.size() > 1) { reportUnsupportedLowering("executable lowering found ambiguous callable identity", callExpr.span(), context); return; } - final var calleeCallableId = candidateCallableIds.getFirst(); + final var calleeCallableId = callableCandidates.getFirst(); context.instructions().add(new IRBackendExecutableFunction.Instruction( IRBackendExecutableFunction.InstructionKind.CALL_FUNC, context.moduleKey(), - calleeName, + calleeIdentity.displayName(), calleeCallableId, null, null, @@ -651,6 +685,21 @@ public final class PbsFrontendCompiler { callExpr.span())); } + private CalleeIdentity resolveCalleeIdentity( + final PbsAst.Expression callee, + final NameTable nameTable) { + return switch (callee) { + case PbsAst.IdentifierExpr identifierExpr -> + new CalleeIdentity(nameTable.register(identifierExpr.name()), identifierExpr.name()); + case PbsAst.MemberExpr memberExpr -> + new CalleeIdentity(nameTable.register(memberExpr.memberName()), memberExpr.memberName()); + case PbsAst.BindExpr bindExpr -> + new CalleeIdentity(nameTable.register(bindExpr.functionName()), bindExpr.functionName()); + case PbsAst.GroupExpr groupExpr -> resolveCalleeIdentity(groupExpr.expression(), nameTable); + default -> null; + }; + } + private void emitJump( final IRBackendExecutableFunction.InstructionKind jumpKind, final String targetLabel, @@ -701,16 +750,6 @@ public final class PbsFrontendCompiler { span); } - private String extractSimpleCalleeName(final PbsAst.Expression callee) { - return switch (callee) { - case PbsAst.IdentifierExpr identifierExpr -> identifierExpr.name(); - case PbsAst.MemberExpr memberExpr -> memberExpr.memberName(); - case PbsAst.BindExpr bindExpr -> bindExpr.functionName(); - case PbsAst.GroupExpr groupExpr -> extractSimpleCalleeName(groupExpr.expression()); - default -> null; - }; - } - private int analyzeMaxStackSlots( final ReadOnlyList instructions, final int returnSlots) { @@ -812,8 +851,8 @@ public final class PbsFrontendCompiler { private final String moduleKey; private final DiagnosticSink diagnostics; private final NameTable nameTable; - private final Map hostByMethodName; - private final Map intrinsicByMethodName; + private final Map> hostByMethodName; + private final Map> intrinsicByMethodName; private final Map> callableIdsByNameAndArity; private final Map returnSlotsByCallableId; private final IntrinsicTable intrinsicIdTable; @@ -825,8 +864,8 @@ public final class PbsFrontendCompiler { final String moduleKey, final DiagnosticSink diagnostics, final NameTable nameTable, - final Map hostByMethodName, - final Map intrinsicByMethodName, + final Map> hostByMethodName, + final Map> intrinsicByMethodName, final Map> callableIdsByNameAndArity, final Map returnSlotsByCallableId, final IntrinsicTable intrinsicIdTable) { @@ -852,11 +891,11 @@ public final class PbsFrontendCompiler { return nameTable; } - private Map hostByMethodName() { + private Map> hostByMethodName() { return hostByMethodName; } - private Map intrinsicByMethodName() { + private Map> intrinsicByMethodName() { return intrinsicByMethodName; } @@ -911,6 +950,11 @@ public final class PbsFrontendCompiler { int arity) { } + private record CalleeIdentity( + NameId nameId, + String displayName) { + } + private static final class ExecutableLoweringAnalysisException extends RuntimeException { private ExecutableLoweringAnalysisException(final String message) { super(message);