From f3be4f7946c6f9e178d0a931dcbea009ef3be778 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Fri, 27 Feb 2026 16:19:50 +0000 Subject: [PATCH] small code improvements --- .../compiler/pbs/PbsFrontendCompiler.java | 5 ++-- .../p/studio/compiler/pbs/ast/PbsAst.java | 8 +++--- .../services/PBSFrontendPhaseService.java | 21 +++++++-------- .../compiler/pbs/PbsFrontendCompilerTest.java | 3 ++- .../stages/FrontendPhasePipelineStage.java | 1 - .../p/studio/compiler/models/IRBackend.java | 26 ++++++++++++++++--- .../studio/compiler/models/IRBackendFile.java | 19 ++++++++++++++ .../utilities/structures/MutableList.java | 17 ++++++++---- 8 files changed, 72 insertions(+), 28 deletions(-) create mode 100644 prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackendFile.java 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 fb09390a..bf5741a4 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 @@ -1,6 +1,7 @@ package p.studio.compiler.pbs; import p.studio.compiler.models.IRFunction; +import p.studio.compiler.models.IRBackendFile; import p.studio.compiler.pbs.ast.PbsAst; import p.studio.compiler.pbs.lexer.PbsLexer; import p.studio.compiler.pbs.parser.PbsParser; @@ -13,14 +14,14 @@ import java.util.HashSet; import java.util.Set; public final class PbsFrontendCompiler { - public ReadOnlyList compileFile( + public IRBackendFile compileFile( final FileId fileId, final String source, final DiagnosticSink diagnostics) { final var tokens = PbsLexer.lex(source, fileId, diagnostics); final var ast = PbsParser.parse(tokens, fileId, diagnostics); validateFunctionNames(ast, diagnostics); - return lowerFunctions(fileId, ast); + return new IRBackendFile(fileId, lowerFunctions(fileId, ast)); } private void validateFunctionNames( diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/ast/PbsAst.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/ast/PbsAst.java index df69d499..721d051c 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/ast/PbsAst.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/ast/PbsAst.java @@ -4,10 +4,6 @@ import p.studio.compiler.source.Span; import p.studio.utilities.structures.ReadOnlyList; public final class PbsAst { - public sealed interface Statement permits LetStatement, ReturnStatement, ExpressionStatement { - Span span(); - } - private PbsAst() { } @@ -36,6 +32,10 @@ public final class PbsAst { Span span) { } + public sealed interface Statement permits LetStatement, ReturnStatement, ExpressionStatement { + Span span(); + } + public record Block( ReadOnlyList statements, Span span) { diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/services/PBSFrontendPhaseService.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/services/PBSFrontendPhaseService.java index 5ae7a4bd..92f53939 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/services/PBSFrontendPhaseService.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/services/PBSFrontendPhaseService.java @@ -4,11 +4,9 @@ import lombok.extern.slf4j.Slf4j; import p.studio.compiler.messages.BuildingIssueSink; import p.studio.compiler.messages.FrontendPhaseContext; import p.studio.compiler.models.IRBackend; -import p.studio.compiler.models.IRFunction; import p.studio.compiler.pbs.PbsFrontendCompiler; import p.studio.compiler.source.diagnostics.DiagnosticSink; import p.studio.utilities.logs.LogAggregator; -import p.studio.utilities.structures.MutableList; @Slf4j public class PBSFrontendPhaseService implements FrontendPhaseService { @@ -20,7 +18,7 @@ public class PBSFrontendPhaseService implements FrontendPhaseService { final DiagnosticSink diagnostics, final LogAggregator logs, final BuildingIssueSink issues) { - final MutableList functions = MutableList.create(); + final var irBackendAggregator = IRBackend.aggregator(); for (final var pId : ctx.stack.reverseTopologicalOrder) { final var fileIds = ctx.fileTable.getFiles(pId); @@ -30,10 +28,11 @@ public class PBSFrontendPhaseService implements FrontendPhaseService { switch (sourceHandle.getExtension()) { case "pbs": { sourceHandle.readUtf8().ifPresentOrElse( - utf8Content -> functions.addAll(frontendCompiler - .compileFile(fId, utf8Content, diagnostics) - .stream() - .toList()), + utf8Content -> { + final var irBackendFile = frontendCompiler + .compileFile(fId, utf8Content, diagnostics); + irBackendAggregator.merge(irBackendFile); + }, () -> issues.report(builder -> builder .error(true) .message("Failed to read file content: %s".formatted(sourceHandle.toString())))); @@ -45,10 +44,8 @@ public class PBSFrontendPhaseService implements FrontendPhaseService { } } - logs.using(log).debug("PBS frontend lowered %d function(s) to IR".formatted(functions.size())); - return IRBackend - .builder() - .functions(functions.toReadOnlyList()) - .build(); + final var irBackend = irBackendAggregator.emit(); + logs.using(log).debug("PBS frontend lowered to IR BE:\n%s".formatted(irBackend)); + return irBackend; } } diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/pbs/PbsFrontendCompilerTest.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/pbs/PbsFrontendCompilerTest.java index a5038bce..a364ecfd 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/pbs/PbsFrontendCompilerTest.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/pbs/PbsFrontendCompilerTest.java @@ -23,7 +23,8 @@ class PbsFrontendCompilerTest { final var diagnostics = DiagnosticSink.empty(); final var compiler = new PbsFrontendCompiler(); - final var functions = compiler.compileFile(new FileId(0), source, diagnostics); + final var fileBackend = compiler.compileFile(new FileId(0), source, diagnostics); + final var functions = fileBackend.functions(); assertTrue(diagnostics.isEmpty(), "Valid program should not report diagnostics"); assertEquals(2, functions.size()); diff --git a/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/stages/FrontendPhasePipelineStage.java b/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/stages/FrontendPhasePipelineStage.java index a53e4670..53676a59 100644 --- a/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/stages/FrontendPhasePipelineStage.java +++ b/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/stages/FrontendPhasePipelineStage.java @@ -27,7 +27,6 @@ public class FrontendPhasePipelineStage implements PipelineStage { final var diagnostics = DiagnosticSink.empty(); final var issues = BuildingIssueSink.empty(); ctx.irBackend = service.get().compile(frontendPhaseContext, diagnostics, logs, issues); - logs.using(log).debug("IR Backend: " + ctx.irBackend); logs.using(log).debug("Frontend phase completed successfully!"); adaptDiagnostics(diagnostics, issues); return issues; diff --git a/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackend.java b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackend.java index 903758f5..3567c858 100644 --- a/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackend.java +++ b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackend.java @@ -2,6 +2,7 @@ package p.studio.compiler.models; import lombok.Builder; import lombok.Getter; +import p.studio.utilities.structures.MutableList; import p.studio.utilities.structures.ReadOnlyList; @Builder @@ -10,9 +11,28 @@ public class IRBackend { @Builder.Default private final ReadOnlyList functions = ReadOnlyList.empty(); - /** - * Returns a stable human-readable representation useful for debug logs and tests. - */ + public static IRBackendAggregator aggregator() { + return new IRBackendAggregator(); + } + + public static final class IRBackendAggregator { + private final MutableList functions = MutableList.create(); + + public void merge(final IRBackendFile backendFile) { + if (backendFile == null) { + return; + } + functions.addAll(backendFile.functions()); + } + + public IRBackend emit() { + return IRBackend + .builder() + .functions(functions.toReadOnlyList()) + .build(); + } + } + @Override public String toString() { final var sb = new StringBuilder(); diff --git a/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackendFile.java b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackendFile.java new file mode 100644 index 00000000..59c1f8c5 --- /dev/null +++ b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackendFile.java @@ -0,0 +1,19 @@ +package p.studio.compiler.models; + +import p.studio.compiler.source.identifiers.FileId; +import p.studio.utilities.structures.ReadOnlyList; + +import java.util.Objects; + +public record IRBackendFile( + FileId fileId, + ReadOnlyList functions) { + public IRBackendFile { + fileId = Objects.requireNonNull(fileId, "fileId"); + functions = functions == null ? ReadOnlyList.empty() : functions; + } + + public static IRBackendFile empty(final FileId fileId) { + return new IRBackendFile(fileId, ReadOnlyList.empty()); + } +} diff --git a/prometeu-infra/src/main/java/p/studio/utilities/structures/MutableList.java b/prometeu-infra/src/main/java/p/studio/utilities/structures/MutableList.java index 16a09d3f..7c68106c 100644 --- a/prometeu-infra/src/main/java/p/studio/utilities/structures/MutableList.java +++ b/prometeu-infra/src/main/java/p/studio/utilities/structures/MutableList.java @@ -1,10 +1,6 @@ package p.studio.utilities.structures; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.ListIterator; -import java.util.Objects; +import java.util.*; import java.util.stream.Stream; public interface MutableList extends ReadOnlyCollection, List { @@ -114,6 +110,17 @@ public interface MutableList extends ReadOnlyCollection, List { return asList().containsAll(c); } + /** + * Appends all functions from the given file using, similar to + * {@link java.util.List#addAll(java.util.Collection)} semantics. + */ + default boolean addAll(final ReadOnlyCollection c) { + if (ReadOnlyCollection.isEmpty(c)) { + return false; + } + return asList().addAll(c.asCollection()); + } + @Override default boolean addAll(final Collection c) { return asList().addAll(c);