small code improvements
This commit is contained in:
parent
956d3128a9
commit
f3be4f7946
@ -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<IRFunction> 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(
|
||||
|
||||
@ -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<Statement> statements,
|
||||
Span span) {
|
||||
|
||||
@ -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<IRFunction> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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<IRFunction> 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<IRFunction> 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();
|
||||
|
||||
@ -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<IRFunction> 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());
|
||||
}
|
||||
}
|
||||
@ -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<T> extends ReadOnlyCollection<T>, List<T> {
|
||||
@ -114,6 +110,17 @@ public interface MutableList<T> extends ReadOnlyCollection<T>, List<T> {
|
||||
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<? extends T> c) {
|
||||
if (ReadOnlyCollection.isEmpty(c)) {
|
||||
return false;
|
||||
}
|
||||
return asList().addAll(c.asCollection());
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean addAll(final Collection<? extends T> c) {
|
||||
return asList().addAll(c);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user