aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-12-20 18:44:59 +0000
committerMichael Williamson <mike@zwobble.org>2023-12-20 18:44:59 +0000
commit2d86046067a1db8d6eac019088f511fc192b660c (patch)
tree26e6a3a53c885a52c3340ccc2a49054d758e068a /src/main/java
parent9cc3f85bf25089e4db840380fb09cbdac34ec821 (diff)
Extract and test namespace linearisation
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ShedCompiler.java44
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedNamespaceNode.java8
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/NamespaceDependencyLineariser.java47
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;
+ }
+}