diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-12-20 18:44:59 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-12-20 18:44:59 +0000 |
| commit | 2d86046067a1db8d6eac019088f511fc192b660c (patch) | |
| tree | 26e6a3a53c885a52c3340ccc2a49054d758e068a /src/main/java | |
| parent | 9cc3f85bf25089e4db840380fb09cbdac34ec821 (diff) | |
Extract and test namespace linearisation
Diffstat (limited to 'src/main/java')
3 files changed, 62 insertions, 37 deletions
diff --git a/src/main/java/org/shedlang/compiler/ShedCompiler.java b/src/main/java/org/shedlang/compiler/ShedCompiler.java index 8c2407d6..177f6fd5 100644 --- a/src/main/java/org/shedlang/compiler/ShedCompiler.java +++ b/src/main/java/org/shedlang/compiler/ShedCompiler.java @@ -6,9 +6,9 @@ import org.shedlang.compiler.backends.paths.TargetDir; import org.shedlang.compiler.config.ConfigChecker; import org.shedlang.compiler.config.ProjectConfig; import org.shedlang.compiler.parser.Parser; -import org.shedlang.compiler.sources.Sources; import org.shedlang.compiler.shid.ShidCodeGen; import org.shedlang.compiler.shid.ShidNamespace; +import org.shedlang.compiler.sources.Sources; import org.shedlang.compiler.typechecker.TypeChecker; import org.shedlang.compiler.typechecker.TypeCheckerContext; import org.shedlang.compiler.types.*; @@ -21,11 +21,14 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; -import java.util.*; -import java.util.stream.Collectors; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; import java.util.stream.StreamSupport; import static org.shedlang.compiler.parser.Tokeniser.tokenise; +import static org.shedlang.compiler.typechecker.NamespaceDependencyLineariser.orderNamespaces; public class ShedCompiler { public void compile(Path projectRoot, Backend backend) throws IOException, InterruptedException { @@ -56,7 +59,7 @@ public class ShedCompiler { Map.entry(ShedBuiltins.PRINT_NAME, ShedBuiltins.PRINT_TYPE) )); - for (var untypedNamespaceNode : orderSourceFiles(untypedNamespaceNodes)) { + for (var untypedNamespaceNode : orderNamespaces(untypedNamespaceNodes)) { var typeCheckNamespaceResult = TypeChecker.typeCheckNamespace(untypedNamespaceNode, typeCheckerContext); typeCheckerContext = typeCheckNamespaceResult.context(); @@ -128,37 +131,4 @@ public class ShedCompiler { return untypedNamespaceNodes; } - - private List<UntypedNamespaceNode> orderSourceFiles( - List<UntypedNamespaceNode> untypedNamespaceNodes - ) { - var nodesByName = untypedNamespaceNodes.stream() - .collect(Collectors.toMap(x -> x.namespaceName(), x -> x)); - - var seen = new HashSet<NamespaceName>(); - var ordered = new ArrayList<UntypedNamespaceNode>(); - - // TODO: test this! - // TODO: handle infinite loops - // TODO: handle missing namespaces - - var adder = new Object() { - private void add(NamespaceName name) { - if (!seen.contains(name)) { - var untypedNamespaceNode = nodesByName.get(name); - for (var import_ : untypedNamespaceNode.imports()) { - add(import_.namespaceName()); - } - seen.add(name); - ordered.add(untypedNamespaceNode); - } - } - }; - - for (var untypedNamespaceNode : untypedNamespaceNodes) { - adder.add(untypedNamespaceNode.namespaceName()); - } - - return ordered; - } } diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNamespaceNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNamespaceNode.java index 164feb6f..20126d59 100644 --- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNamespaceNode.java +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNamespaceNode.java @@ -27,6 +27,14 @@ public record UntypedNamespaceNode( return new UntypedNamespaceNode(namespaceName, imports, body, Sources.NULL); } + public Builder withNamespaceName(NamespaceName namespaceName) { + return new Builder( + namespaceName, + this.imports, + this.body + ); + } + public Builder addImport(UntypedImportNode import_) { return new Builder(namespaceName, imports.plus(import_), body); } diff --git a/src/main/java/org/shedlang/compiler/typechecker/NamespaceDependencyLineariser.java b/src/main/java/org/shedlang/compiler/typechecker/NamespaceDependencyLineariser.java new file mode 100644 index 00000000..bedb0070 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/typechecker/NamespaceDependencyLineariser.java @@ -0,0 +1,47 @@ +package org.shedlang.compiler.typechecker; + +import org.shedlang.compiler.ast.untyped.UntypedNamespaceNode; +import org.shedlang.compiler.types.NamespaceName; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +public class NamespaceDependencyLineariser { + private NamespaceDependencyLineariser() { + } + + public static List<UntypedNamespaceNode> orderNamespaces( + List<UntypedNamespaceNode> untypedNamespaceNodes + ) { + var nodesByName = untypedNamespaceNodes.stream() + .collect(Collectors.toMap(x -> x.namespaceName(), x -> x)); + + var seen = new HashSet<NamespaceName>(); + var ordered = new ArrayList<UntypedNamespaceNode>(); + + // TODO: test this! + // TODO: handle infinite loops + // TODO: handle missing namespaces + + var adder = new Object() { + private void add(NamespaceName name) { + if (!seen.contains(name)) { + var untypedNamespaceNode = nodesByName.get(name); + for (var import_ : untypedNamespaceNode.imports()) { + add(import_.namespaceName()); + } + seen.add(name); + ordered.add(untypedNamespaceNode); + } + } + }; + + for (var untypedNamespaceNode : untypedNamespaceNodes) { + adder.add(untypedNamespaceNode.namespaceName()); + } + + return ordered; + } +} |
