diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-05-02 10:04:44 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-05-02 10:04:44 +0100 |
| commit | cd5745dfdf422ceb2a4154b575a8c512b41a8f66 (patch) | |
| tree | 2e63453dfb4715f84195b969e40f01f3c7bb635f | |
| parent | 5d76fa1b86ff1bd15b9c6b546916bc03c9d9b9b4 (diff) | |
Create generators from config
8 files changed, 118 insertions, 12 deletions
diff --git a/examples/01-struct/hobgoblin.json5 b/examples/01-struct/hobgoblin.json5 index 0967ef4..b6bb102 100644 --- a/examples/01-struct/hobgoblin.json5 +++ b/examples/01-struct/hobgoblin.json5 @@ -1 +1,9 @@ -{} +{ + "outputs": [ + { + "generator": "java-types", + "path": "output/java/src/gen/java", + "package-name": "org.zwobble.example.types" + }, + ], +} diff --git a/examples/02-sum/hobgoblin.json5 b/examples/02-sum/hobgoblin.json5 index 0967ef4..b6bb102 100644 --- a/examples/02-sum/hobgoblin.json5 +++ b/examples/02-sum/hobgoblin.json5 @@ -1 +1,9 @@ -{} +{ + "outputs": [ + { + "generator": "java-types", + "path": "output/java/src/gen/java", + "package-name": "org.zwobble.example.types" + }, + ], +} @@ -62,6 +62,11 @@ <version>0.1.0</version> </dependency> <dependency> + <groupId>org.zwobble.json5</groupId> + <artifactId>zwobble-json5</artifactId> + <version>0.1.0</version> + </dependency> + <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java index 698d68f..873ecfd 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java @@ -2,7 +2,7 @@ package org.zwobble.hobgoblin.compiler; import org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceNode; import org.zwobble.hobgoblin.compiler.builtins.BuiltinTypes; -import org.zwobble.hobgoblin.compiler.output.generators.Generator; +import org.zwobble.hobgoblin.compiler.config.ProjectConfig; import org.zwobble.hobgoblin.compiler.parser.Parser; import org.zwobble.hobgoblin.compiler.typechecker.TypeChecker; import org.zwobble.hobgoblin.compiler.typechecker.TypeCheckerGlobalContext; @@ -14,7 +14,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.List; public class HobgoblinCompiler { public static final String FILE_NAME_EXTENSION = ".hob"; @@ -22,7 +21,10 @@ public class HobgoblinCompiler { private HobgoblinCompiler() { } - public static void compile(Path projectRoot, List<? extends Generator> generators) throws IOException { + public static void compile(Path projectRoot) throws IOException { + var config = ProjectConfig.read(projectRoot); + var generators = config.createGenerators(); + var sourceDirectory = projectRoot.resolve("src"); var sourceFiles = sourceDirectory.toFile() .listFiles(file -> file.toPath().toString().endsWith(FILE_NAME_EXTENSION)); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/config/OutputConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/config/OutputConfig.java new file mode 100644 index 0000000..ae31bdd --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/config/OutputConfig.java @@ -0,0 +1,7 @@ +package org.zwobble.hobgoblin.compiler.config; + +import org.zwobble.hobgoblin.compiler.output.generators.Generator; + +public interface OutputConfig { + Generator createGenerator(); +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java new file mode 100644 index 0000000..ee70dba --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/config/ProjectConfig.java @@ -0,0 +1,68 @@ +package org.zwobble.hobgoblin.compiler.config; + +import org.zwobble.hobgoblin.compiler.output.generators.Generator; +import org.zwobble.hobgoblin.compiler.output.generators.javatypes.JavaTypesGenerator; +import org.zwobble.json5.parser.Json5Parser; +import org.zwobble.json5.values.Json5Array; +import org.zwobble.json5.values.Json5Object; +import org.zwobble.json5.values.Json5String; +import org.zwobble.json5.values.Json5Value; +import org.zwobble.sourcetext.SourceText; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +public record ProjectConfig( + List<OutputConfig> output +) { + public static ProjectConfig read(Path projectRoot) throws IOException { + var configPath = projectRoot.resolve("hobgoblin.json5"); + var contents = Files.readString(configPath); + var sourceText = SourceText.fromString(configPath.toString(), contents); + return fromSourceText(projectRoot, sourceText); + } + + private static ProjectConfig fromSourceText(Path projectRoot, SourceText sourceText) { + return fromJson5(projectRoot, Json5Parser.parse(sourceText)); + } + + private static ProjectConfig fromJson5(Path projectRoot, Json5Value document) { + if (!(document instanceof Json5Object documentObject)) { + throw new UnsupportedOperationException("TODO"); + } + + var outputsValue = documentObject.getValue("outputs").orElseThrow(); + if (!(outputsValue instanceof Json5Array outputsArray)) { + throw new UnsupportedOperationException("TODO"); + } + + var outputs = new ArrayList<OutputConfig>(); + for (var outputValue : outputsArray.elements()) { + if (!(outputValue instanceof Json5Object outputObject)) { + throw new UnsupportedOperationException("TODO"); + } + var generatorName = (Json5String) outputObject.getValue("generator").orElseThrow(); + + var output = switch (generatorName.value()) { + case JavaTypesGenerator.NAME -> + JavaTypesGenerator.parseOutputConfig(projectRoot, outputObject); + + default -> + throw new UnsupportedOperationException("TODO"); + }; + + outputs.add(output); + } + + return new ProjectConfig(outputs); + } + + public List<Generator> createGenerators() { + return this.output.stream() + .map(output -> output.createGenerator()) + .toList(); + } +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java index 98d4c12..4c06e8e 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java @@ -5,11 +5,14 @@ import org.zwobble.hobgoblin.compiler.ast.typed.TypedStructDefinitionNode; import org.zwobble.hobgoblin.compiler.ast.typed.TypedSumDefinitionNode; import org.zwobble.hobgoblin.compiler.ast.typed.TypedTypeLevelExpressionNode; import org.zwobble.hobgoblin.compiler.builtins.BuiltinTypes; +import org.zwobble.hobgoblin.compiler.config.OutputConfig; import org.zwobble.hobgoblin.compiler.output.CodeWriter; import org.zwobble.hobgoblin.compiler.output.generators.Generator; import org.zwobble.hobgoblin.compiler.output.java.JavaWriter; import org.zwobble.hobgoblin.compiler.output.java.ast.*; import org.zwobble.hobgoblin.compiler.types.*; +import org.zwobble.json5.values.Json5Object; +import org.zwobble.json5.values.Json5String; import java.io.File; import java.io.IOException; @@ -19,6 +22,17 @@ import java.util.HashMap; import java.util.List; public class JavaTypesGenerator implements Generator { + public static final String NAME = "java-types"; + + public static OutputConfig parseOutputConfig(Path projectRoot, Json5Object output) { + return () -> { + var relativeOutputPath = ((Json5String) output.getValue("path").orElseThrow()).value(); + var outputPath = projectRoot.resolve(relativeOutputPath); + var packageName = ((Json5String) output.getValue("package-name").orElseThrow()).value(); + return new JavaTypesGenerator(outputPath, packageName); + }; + } + private final Path sourceRootDirectory; private final List<String> packageName; diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java index fb5cc55..fd38a84 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java @@ -2,7 +2,6 @@ package org.zwobble.hobgoblin.compiler; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; -import org.zwobble.hobgoblin.compiler.output.generators.javatypes.JavaTypesGenerator; import org.zwobble.hobgoblin.compiler.testing.TestProcessRunner; import java.io.IOException; @@ -22,12 +21,7 @@ public class ExampleTests { private void runTest(ExampleSet exampleSet) throws IOException, InterruptedException { var javaProjectPath = exampleSet.path().resolve("output/java"); - var javaTypesGenerator = new JavaTypesGenerator( - javaProjectPath.resolve("src/gen/java"), - "org.zwobble.example.types" - ); - var generators = List.of(javaTypesGenerator); - HobgoblinCompiler.compile(exampleSet.path(), generators); + HobgoblinCompiler.compile(exampleSet.path()); TestProcessRunner.command(List.of("mvn", "compile")) .cwd(javaProjectPath) |
