diff options
Diffstat (limited to 'src')
4 files changed, 39 insertions, 43 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNode.java index d457b60..2355e41 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNode.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNode.java @@ -2,22 +2,26 @@ package org.zwobble.hobgoblin.compiler.ast.untyped; -public record UntypedImportNode(java.util.List<String> importedNames, org.zwobble.hobgoblin.compiler.types.NamespaceName namespaceName) { +public record UntypedImportNode(java.util.List<String> importedNames, java.util.Optional<java.lang.Integer> ancestorDepth, org.zwobble.hobgoblin.compiler.types.NamespaceName namespaceName) { public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder arbitrary() { - return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(java.util.List.of(), org.zwobble.hobgoblin.compiler.ast.untyped.Native.arbitraryNamespaceName()); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(java.util.List.of(), java.util.Optional.empty(), org.zwobble.hobgoblin.compiler.ast.untyped.Native.arbitraryNamespaceName()); } - public record Builder(java.util.List<String> importedNames, org.zwobble.hobgoblin.compiler.types.NamespaceName namespaceName) { + public record Builder(java.util.List<String> importedNames, java.util.Optional<java.lang.Integer> ancestorDepth, org.zwobble.hobgoblin.compiler.types.NamespaceName namespaceName) { public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode build() { - return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode(importedNames, namespaceName); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode(importedNames, ancestorDepth, namespaceName); } public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder withImportedNames(java.util.List<String> importedNames) { - return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(importedNames, namespaceName); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(importedNames, ancestorDepth, namespaceName); + } + + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder withAncestorDepth(java.util.Optional<java.lang.Integer> ancestorDepth) { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(importedNames, ancestorDepth, namespaceName); } public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder withNamespaceName(org.zwobble.hobgoblin.compiler.types.NamespaceName namespaceName) { - return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(importedNames, namespaceName); + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder(importedNames, ancestorDepth, namespaceName); } // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode.Builder body diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java b/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java index 2a51257..72bd60e 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java @@ -11,6 +11,7 @@ import org.zwobble.sourcetext.SourceText; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.function.BooleanSupplier; import java.util.function.Supplier; @@ -68,11 +69,28 @@ public class Parser { tokens.skip(TokenType.SYMBOL_BRACE_CLOSE); tokens.skip(TokenType.KEYWORD_FROM); - var namespaceName = parseRelativeNamespaceName(tokens); + var isSibling = tokens.trySkip(TokenType.SYMBOL_DOT); + + Optional<Integer> ancestorDepth; + if (isSibling) { + tokens.skip(TokenType.SYMBOL_FORWARD_SLASH); + ancestorDepth = Optional.of(0); + } else if (tokens.isNext(TokenType.SYMBOL_DOT_DOT)) { + int depth = 0; + while (tokens.trySkip(TokenType.SYMBOL_DOT_DOT)) { + depth += 1; + tokens.skip(TokenType.SYMBOL_FORWARD_SLASH); + } + ancestorDepth = Optional.of(depth); + } else { + ancestorDepth = Optional.empty(); + } + + var namespaceName = parseNamespaceName(tokens); tokens.skip(TokenType.SYMBOL_SEMICOLON); - return new UntypedImportNode(importedNames, namespaceName); + return new UntypedImportNode(importedNames, ancestorDepth, namespaceName); } static UntypedNamespaceStatementNode parseNamespaceStatement( @@ -307,39 +325,6 @@ public class Parser { return new NamespaceName(namespaceParts); } - private static NamespaceName parseRelativeNamespaceName(TokenIterator tokens) { - var isSibling = tokens.trySkip(TokenType.SYMBOL_DOT); - - List<String> parentParts; - if (isSibling) { - tokens.skip(TokenType.SYMBOL_FORWARD_SLASH); - parentParts = List.of("."); - } else if (tokens.isNext(TokenType.SYMBOL_DOT_DOT)) { - parentParts = new ArrayList<>(); - while (tokens.trySkip(TokenType.SYMBOL_DOT_DOT)) { - parentParts.add(".."); - tokens.skip(TokenType.SYMBOL_FORWARD_SLASH); - } - } else { - parentParts = List.of(parseIdentifier(tokens)); - } - - var childParts = parseMany( - () -> !tokens.isNext(TokenType.IDENTIFIER), - () -> { - tokens.trySkip(TokenType.SYMBOL_FORWARD_SLASH); - return parseIdentifier(tokens); - }, - () -> true - ); - - var namespaceParts = new ArrayList<String>(); - namespaceParts.addAll(parentParts); - namespaceParts.addAll(childParts); - - return new NamespaceName(namespaceParts); - } - private static String parseIdentifier(TokenIterator tokens) { return tokens.next(TokenType.IDENTIFIER).charSequence().toString(); } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNodeMatcher.java index 9c8c183..e902170 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNodeMatcher.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedImportNodeMatcher.java @@ -29,6 +29,10 @@ public class UntypedImportNodeMatcher implements org.zwobble.precisely.Matcher<j return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNodeMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("importedNames", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode::importedNames, importedNames))).toList()); } + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNodeMatcher withAncestorDepth(org.zwobble.precisely.Matcher<? super java.util.Optional<java.lang.Integer>> ancestorDepth) { + return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNodeMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("ancestorDepth", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode::ancestorDepth, ancestorDepth))).toList()); + } + public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNodeMatcher withNamespaceName(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.types.NamespaceName> namespaceName) { return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNodeMatcher(java.util.stream.Stream.concat(this.submatchers.stream(), java.util.stream.Stream.of(org.zwobble.precisely.Matchers.has("namespaceName", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedImportNode::namespaceName, namespaceName))).toList()); } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserNamespaceTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserNamespaceTests.java index 4df8b95..ada6414 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserNamespaceTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/parser/ParserNamespaceTests.java @@ -42,13 +42,16 @@ public class ParserNamespaceTests { .withImports(isSequence( isUntypedImportNode() .withImportedNames(isSequence(equalTo("Point"))) + .withAncestorDepth(isOptionalEmpty()) .withNamespaceName(equalTo(NamespaceName.of("point"))), isUntypedImportNode() .withImportedNames(isSequence(equalTo("Square"), equalTo("Rectangle"))) - .withNamespaceName(equalTo(NamespaceName.of(".", "shapes"))), + .withAncestorDepth(isOptionalOf(equalTo(0))) + .withNamespaceName(equalTo(NamespaceName.of("shapes"))), isUntypedImportNode() .withImportedNames(isSequence(equalTo("Line"))) - .withNamespaceName(equalTo(NamespaceName.of("..", "..", "line"))) + .withAncestorDepth(isOptionalOf(equalTo(2))) + .withNamespaceName(equalTo(NamespaceName.of("line"))) )) ); } |
