summaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/zwobble')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCli.java25
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java19
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/Relation.java18
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/RelationTable.java32
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNamespaceStatementNode.java2
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedQueryDefinitionNode.java54
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedBinaryOperationNode.java58
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedBinaryOperator.java13
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedCallNode.java60
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedExpressionNode.java18
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedFunctionExpressionNode.java60
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedMemberAccessNode.java48
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedNamespaceStatementNode.java2
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedNumberLiteralNode.java38
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedParamNode.java38
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedQueryDefinitionNode.java62
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReferenceNode.java38
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReturnNode.java42
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedStatementNode.java18
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNode.java12
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/math/HobgoblinNativeMath.java11
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java156
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/Generator.java1
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/Stripper.java12
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java5
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java9
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java9
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java5
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java53
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sqlscripts/SqlScriptsGenerator.java69
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java5
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java11
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java11
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/SqlWriter.java74
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlExpression.java18
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlIntLiteral.java32
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlOrderingTerm.java36
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlRef.java36
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlResultColumn.java46
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlSelectStatement.java72
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlStatement.java2
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java11
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/parser/OperationParser.java15
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/parser/OperatorPrecedence.java6
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java289
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/parser/TokenType.java5
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/parser/Tokenizer.java44
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java184
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java11
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java2
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfoInMemory.java23
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchMemberError.java24
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/ConstantNumber.java12
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/DatabaseSchema.java8
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/DatabaseSchemaInfo.java6
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java8
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/RelationMethod.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/Table.java8
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/TableInfo.java8
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValue.java2
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java7
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/Types.java12
66 files changed, 1985 insertions, 80 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCli.java b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCli.java
index 7e2dcee..9a1e054 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCli.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCli.java
@@ -3,6 +3,7 @@ package org.zwobble.hobgoblin.compiler;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;
+import net.sourceforge.argparse4j.inf.Subparser;
import org.zwobble.hobgoblin.compiler.errors.SourceError;
import org.zwobble.hobgoblin.compiler.sources.NullSource;
import org.zwobble.hobgoblin.compiler.util.argparse4j.PathArgumentType;
@@ -31,6 +32,9 @@ public class HobgoblinCli {
case COMPILE -> {
HobgoblinCompiler.compile(sourcePath);
}
+ case STRIP -> {
+ HobgoblinCompiler.strip(sourcePath);
+ }
}
}
@@ -40,12 +44,13 @@ public class HobgoblinCli {
var subparsers = parser.addSubparsers();
- var compileSubParser = subparsers.addParser("compile");
- compileSubParser.setDefault("command", Command.COMPILE);
- compileSubParser
- .addArgument("source")
- .type(new PathArgumentType())
- .required(true);
+ var compileSubparser = subparsers.addParser("compile");
+ compileSubparser.setDefault("command", Command.COMPILE);
+ addSourceArgument(compileSubparser);
+
+ var stripSubparser = subparsers.addParser("strip");
+ stripSubparser.setDefault("command", Command.STRIP);
+ addSourceArgument(stripSubparser);
try {
return parser.parseArgs(args);
@@ -56,7 +61,15 @@ public class HobgoblinCli {
}
}
+ private static void addSourceArgument(Subparser subparser) {
+ subparser
+ .addArgument("source")
+ .type(new PathArgumentType())
+ .required(true);
+ }
+
private enum Command {
COMPILE,
+ STRIP,
}
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java
index 0bd9192..1a34f2b 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java
@@ -3,6 +3,7 @@ package org.zwobble.hobgoblin.compiler;
import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceNode;
import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
import org.zwobble.hobgoblin.compiler.config.ProjectConfig;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.parser.Parser;
import org.zwobble.hobgoblin.compiler.typechecker.TypeChecker;
import org.zwobble.hobgoblin.compiler.typechecker.TypeCheckerGlobalContext;
@@ -17,6 +18,7 @@ import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
public class HobgoblinCompiler {
@@ -63,6 +65,23 @@ public class HobgoblinCompiler {
}
}
+ public static void strip(Path projectRoot) throws IOException {
+ var config = ProjectConfig.read(projectRoot);
+ var generators = config.createGenerators();
+
+ // Multiple generators may write the same language to the same
+ // directory, so we de-duplicate strippers rather than asking the
+ // generator to strip directly.
+ var strippers = new HashSet<Stripper>();
+ for (var generator : generators) {
+ strippers.addAll(generator.strippers());
+ }
+
+ for (var stripper : strippers) {
+ stripper.strip();
+ }
+ }
+
static NamespaceName sourceFileNamespaceName(Path sourceDirectory, Path sourceFilePath) {
var relativePath = sourceDirectory.relativize(sourceFilePath);
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/Relation.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/Relation.java
new file mode 100644
index 0000000..7f08714
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/Relation.java
@@ -0,0 +1,18 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.typed;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.Relation imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.Relation imports
+
+public sealed interface Relation permits org.zwobble.hobgoblin.compiler.ast.typed.RelationTable {
+ public interface Builder {
+ public org.zwobble.hobgoblin.compiler.ast.typed.Relation build();
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.Relation.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.Relation.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.Relation body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.Relation body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/RelationTable.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/RelationTable.java
new file mode 100644
index 0000000..d62753e
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/RelationTable.java
@@ -0,0 +1,32 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.typed;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.RelationTable imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.RelationTable imports
+
+public record RelationTable(
+ org.zwobble.hobgoblin.compiler.types.Table table
+) implements org.zwobble.hobgoblin.compiler.ast.typed.Relation {
+ public static org.zwobble.hobgoblin.compiler.ast.typed.RelationTable.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.RelationTable.Builder(org.zwobble.hobgoblin.compiler.types.HobgoblinNativeTypes.arbitraryTable());
+ }
+
+ public record Builder(
+ org.zwobble.hobgoblin.compiler.types.Table table
+ ) implements org.zwobble.hobgoblin.compiler.ast.typed.Relation.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.typed.RelationTable build() {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.RelationTable(table);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.RelationTable.Builder withTable(org.zwobble.hobgoblin.compiler.types.Table table) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.RelationTable.Builder(table);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.RelationTable.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.RelationTable.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.RelationTable body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.RelationTable body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNamespaceStatementNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNamespaceStatementNode.java
index 8e8bd77..a20416e 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNamespaceStatementNode.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNamespaceStatementNode.java
@@ -5,7 +5,7 @@ package org.zwobble.hobgoblin.compiler.ast.typed;
// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceStatementNode imports
// Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceStatementNode imports
-public sealed interface TypedNamespaceStatementNode permits org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode, org.zwobble.hobgoblin.compiler.ast.typed.TypedEnumDefinitionNode, org.zwobble.hobgoblin.compiler.ast.typed.TypedNativeTypeDefinitionNode, org.zwobble.hobgoblin.compiler.ast.typed.TypedStructDefinitionNode, org.zwobble.hobgoblin.compiler.ast.typed.TypedSumDefinitionNode {
+public sealed interface TypedNamespaceStatementNode permits org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode, org.zwobble.hobgoblin.compiler.ast.typed.TypedEnumDefinitionNode, org.zwobble.hobgoblin.compiler.ast.typed.TypedNativeTypeDefinitionNode, org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode, org.zwobble.hobgoblin.compiler.ast.typed.TypedStructDefinitionNode, org.zwobble.hobgoblin.compiler.ast.typed.TypedSumDefinitionNode {
public interface Builder {
public org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceStatementNode build();
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedQueryDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedQueryDefinitionNode.java
new file mode 100644
index 0000000..dc61d28
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedQueryDefinitionNode.java
@@ -0,0 +1,54 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.typed;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode imports
+
+public record TypedQueryDefinitionNode(
+ String name,
+ org.zwobble.hobgoblin.compiler.ast.typed.Relation relation,
+ org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceStatementNode {
+ public static org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder("", org.zwobble.hobgoblin.compiler.ast.typed.RelationTable.arbitrary().build(), org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ String name,
+ org.zwobble.hobgoblin.compiler.ast.typed.Relation relation,
+ org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceStatementNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode(name, relation, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder withName(String name) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder(name, relation, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder withRelation(org.zwobble.hobgoblin.compiler.ast.typed.Relation relation) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder(name, relation, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder withRelation(org.zwobble.hobgoblin.compiler.ast.typed.Relation.Builder relation) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder(name, relation.build(), docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder withDocComment(org.zwobble.hobgoblin.compiler.ast.DocComment docComment) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder(name, relation, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder(name, relation, docComment, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedBinaryOperationNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedBinaryOperationNode.java
new file mode 100644
index 0000000..b6fb024
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedBinaryOperationNode.java
@@ -0,0 +1,58 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode imports
+
+public record UntypedBinaryOperationNode(
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperator operator,
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode left,
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode right,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode {
+ public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperator.EQUALS, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.arbitrary().build(), org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.arbitrary().build(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperator operator,
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode left,
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode right,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode(operator, left, right, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder withOperator(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperator operator) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder(operator, left, right, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder withLeft(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode left) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder(operator, left, right, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder withLeft(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder left) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder(operator, left.build(), right, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder withRight(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode right) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder(operator, left, right, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder withRight(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder right) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder(operator, left, right.build(), source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder(operator, left, right, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedBinaryOperator.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedBinaryOperator.java
new file mode 100644
index 0000000..b479e9b
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedBinaryOperator.java
@@ -0,0 +1,13 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperator imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperator imports
+
+public enum UntypedBinaryOperator {
+ EQUALS
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperator body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperator body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedCallNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedCallNode.java
new file mode 100644
index 0000000..8da37c1
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedCallNode.java
@@ -0,0 +1,60 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode imports
+
+public record UntypedCallNode(
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode receiver,
+ java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode> args,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode {
+ public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.arbitrary().build(), java.util.List.of(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode receiver,
+ java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode> args,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode(receiver, args, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder withReceiver(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode receiver) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder(receiver, args, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder withReceiver(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder receiver) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder(receiver.build(), args, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder withArgs(java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode> args) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder(receiver, args, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder addArg(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode arg) {
+ var args = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode>(this.args);
+ args.add(arg);
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder(receiver, args, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder addArg(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder arg) {
+ var args = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode>(this.args);
+ args.add(arg.build());
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder(receiver, args, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder(receiver, args, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedExpressionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedExpressionNode.java
new file mode 100644
index 0000000..2fd499e
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedExpressionNode.java
@@ -0,0 +1,18 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode imports
+
+public sealed interface UntypedExpressionNode permits org.zwobble.hobgoblin.compiler.ast.untyped.UntypedBinaryOperationNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedCallNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode {
+ public interface Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode build();
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedFunctionExpressionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedFunctionExpressionNode.java
new file mode 100644
index 0000000..d4a6034
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedFunctionExpressionNode.java
@@ -0,0 +1,60 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode imports
+
+public record UntypedFunctionExpressionNode(
+ java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode> params,
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode body,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode {
+ public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder(java.util.List.of(), org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.arbitrary().build(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode> params,
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode body,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode(params, body, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder withParams(java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode> params) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder(params, body, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder addParam(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode param) {
+ var params = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode>(this.params);
+ params.add(param);
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder(params, body, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder addParam(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.Builder param) {
+ var params = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode>(this.params);
+ params.add(param.build());
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder(params, body, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder withBody(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode body) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder(params, body, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder withBody(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder body) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder(params, body.build(), source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder(params, body, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedFunctionExpressionNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedMemberAccessNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedMemberAccessNode.java
new file mode 100644
index 0000000..4fef83e
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedMemberAccessNode.java
@@ -0,0 +1,48 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode imports
+
+public record UntypedMemberAccessNode(
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode receiver,
+ String memberName,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode {
+ public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.arbitrary().build(), "", org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode receiver,
+ String memberName,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode(receiver, memberName, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder withReceiver(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode receiver) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder(receiver, memberName, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder withReceiver(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder receiver) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder(receiver.build(), memberName, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder withMemberName(String memberName) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder(receiver, memberName, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder(receiver, memberName, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedMemberAccessNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedNamespaceStatementNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedNamespaceStatementNode.java
index 3f805bf..2e78f39 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedNamespaceStatementNode.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedNamespaceStatementNode.java
@@ -5,7 +5,7 @@ package org.zwobble.hobgoblin.compiler.ast.untyped;
// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceStatementNode imports
// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceStatementNode imports
-public sealed interface UntypedNamespaceStatementNode permits org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedEnumDefinitionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNativeTypeDefinitionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStructDefinitionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedSumDefinitionNode {
+public sealed interface UntypedNamespaceStatementNode permits org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedEnumDefinitionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNativeTypeDefinitionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStructDefinitionNode, org.zwobble.hobgoblin.compiler.ast.untyped.UntypedSumDefinitionNode {
public interface Builder {
public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceStatementNode build();
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedNumberLiteralNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedNumberLiteralNode.java
new file mode 100644
index 0000000..1e041ea
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedNumberLiteralNode.java
@@ -0,0 +1,38 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode imports
+
+public record UntypedNumberLiteralNode(
+ java.math.BigDecimal value,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode {
+ public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.Builder(org.zwobble.hobgoblin.compiler.math.HobgoblinNativeMath.arbitraryBigDecimal(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ java.math.BigDecimal value,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode(value, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.Builder withValue(java.math.BigDecimal value) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.Builder(value, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.Builder(value, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedParamNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedParamNode.java
new file mode 100644
index 0000000..068097f
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedParamNode.java
@@ -0,0 +1,38 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode imports
+
+public record UntypedParamNode(
+ String name,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) {
+ public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.Builder("", org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ String name,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode(name, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.Builder withName(String name) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.Builder(name, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.Builder(name, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedParamNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedQueryDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedQueryDefinitionNode.java
new file mode 100644
index 0000000..b48a95c
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedQueryDefinitionNode.java
@@ -0,0 +1,62 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode imports
+
+public record UntypedQueryDefinitionNode(
+ String name,
+ java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode> statements,
+ org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceStatementNode {
+ public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder("", java.util.List.of(), org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ String name,
+ java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode> statements,
+ org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceStatementNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode(name, statements, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder withName(String name) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder(name, statements, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder withStatements(java.util.List<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode> statements) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder(name, statements, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder addStatement(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode statement) {
+ var statements = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode>(this.statements);
+ statements.add(statement);
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder(name, statements, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder addStatement(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode.Builder statement) {
+ var statements = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode>(this.statements);
+ statements.add(statement.build());
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder(name, statements, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder withDocComment(org.zwobble.hobgoblin.compiler.ast.DocComment docComment) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder(name, statements, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder(name, statements, docComment, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedQueryDefinitionNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReferenceNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReferenceNode.java
new file mode 100644
index 0000000..edd3066
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReferenceNode.java
@@ -0,0 +1,38 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode imports
+
+public record UntypedReferenceNode(
+ String name,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode {
+ public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode.Builder("", org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ String name,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode(name, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode.Builder withName(String name) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode.Builder(name, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode.Builder(name, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReferenceNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReturnNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReturnNode.java
new file mode 100644
index 0000000..03c3446
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedReturnNode.java
@@ -0,0 +1,42 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode imports
+
+public record UntypedReturnNode(
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode expression,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode {
+ public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNumberLiteralNode.arbitrary().build(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode expression,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode(expression, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder withExpression(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode expression) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder(expression, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder withExpression(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedExpressionNode.Builder expression) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder(expression.build(), source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder(expression, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedStatementNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedStatementNode.java
new file mode 100644
index 0000000..8121f93
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedStatementNode.java
@@ -0,0 +1,18 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.untyped;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode imports
+
+public sealed interface UntypedStatementNode permits org.zwobble.hobgoblin.compiler.ast.untyped.UntypedReturnNode {
+ public interface Builder {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode build();
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStatementNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNode.java
index ebff463..072d12a 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNode.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/untyped/UntypedTableDefinitionNode.java
@@ -8,18 +8,18 @@ package org.zwobble.hobgoblin.compiler.ast.untyped;
public record UntypedTableDefinitionNode(
String name,
org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelExpressionNode rowType,
- String primaryKey,
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode primaryKey,
org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
org.zwobble.hobgoblin.compiler.sources.Source source
) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode {
public static org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder arbitrary() {
- return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder("", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode.arbitrary().build(), "", org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder("", org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode.arbitrary().build(), org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode.arbitrary().build(), org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
}
public record Builder(
String name,
org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelExpressionNode rowType,
- String primaryKey,
+ org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode primaryKey,
org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
org.zwobble.hobgoblin.compiler.sources.Source source
) implements org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaStatementNode.Builder {
@@ -39,10 +39,14 @@ public record UntypedTableDefinitionNode(
return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder(name, rowType.build(), primaryKey, docComment, source);
}
- public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder withPrimaryKey(String primaryKey) {
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder withPrimaryKey(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode primaryKey) {
return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder(name, rowType, primaryKey, docComment, source);
}
+ public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder withPrimaryKey(org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode.Builder primaryKey) {
+ return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder(name, rowType, primaryKey.build(), docComment, source);
+ }
+
public org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder withDocComment(org.zwobble.hobgoblin.compiler.ast.DocComment docComment) {
return new org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode.Builder(name, rowType, primaryKey, docComment, source);
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/math/HobgoblinNativeMath.java b/src/main/java/org/zwobble/hobgoblin/compiler/math/HobgoblinNativeMath.java
new file mode 100644
index 0000000..1592b50
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/math/HobgoblinNativeMath.java
@@ -0,0 +1,11 @@
+package org.zwobble.hobgoblin.compiler.math;
+
+import java.math.BigDecimal;
+
+public class HobgoblinNativeMath {
+ private HobgoblinNativeMath() {}
+
+ public static BigDecimal arbitraryBigDecimal() {
+ return BigDecimal.ZERO;
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java
index 81fd091..551683e 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/CodeWriter.java
@@ -1,5 +1,7 @@
package org.zwobble.hobgoblin.compiler.output;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
+
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
@@ -10,6 +12,30 @@ import java.nio.file.Path;
import java.util.*;
public class CodeWriter implements AutoCloseable {
+ public static class CodeWriterConfig {
+ private final String header;
+ private final String customAreaStart;
+ private final String customAreaEnd;
+
+ public CodeWriterConfig(String lineCommentStart) {
+ this.header = lineCommentStart + " Generated by hobgoblin.\n\n";
+ this.customAreaStart = lineCommentStart + " Custom area start: ";
+ this.customAreaEnd = lineCommentStart + " Custom area end: ";
+ }
+
+ public String header() {
+ return this.header;
+ }
+
+ public String customAreaStart() {
+ return customAreaStart;
+ }
+
+ public String customAreaEnd() {
+ return customAreaEnd;
+ }
+ }
+
public interface CodeWriterFile {
String readString() throws IOException;
Writer openWriter() throws IOException;
@@ -50,26 +76,26 @@ public class CodeWriter implements AutoCloseable {
}
public record CustomAreas(
- Map<String, List<String>> existing,
- String customAreaStart,
- String customAreaEnd
+ SequencedMap<String, List<String>> existing,
+ CodeWriterConfig config
) {
public static CustomAreas read(
String existingString,
- String customAreaStart,
- String customAreaEnd
+ CodeWriterConfig config
) {
- var existing = new HashMap<String, List<String>>();
+ var existing = new LinkedHashMap<String, List<String>>();
Iterable<String> lines = () -> existingString.lines().iterator();
Optional<String> name = Optional.empty();
var customAreaLines = new ArrayList<String>();
for (var line : lines) {
var trimmedLine = line.trim();
- if (trimmedLine.startsWith(customAreaStart)) {
- name = Optional.of(trimmedLine.substring(customAreaStart.length()));
- } else if (name.isPresent() && trimmedLine.startsWith(customAreaEnd + name.get())) {
- existing.put(name.get(), customAreaLines);
+ if (trimmedLine.startsWith(config.customAreaStart)) {
+ name = Optional.of(trimmedLine.substring(config.customAreaStart.length()));
+ } else if (name.isPresent() && trimmedLine.startsWith(config.customAreaEnd + name.get())) {
+ if (!customAreaLines.isEmpty()) {
+ existing.put(name.get(), customAreaLines);
+ }
customAreaLines = new ArrayList<>();
name = Optional.empty();
} else if (name.isPresent()) {
@@ -77,14 +103,19 @@ public class CodeWriter implements AutoCloseable {
}
}
- return new CustomAreas(existing, customAreaStart, customAreaEnd);
+ return new CustomAreas(existing, config);
}
- public static CustomAreas empty(
- String customAreaStart,
- String customAreaEnd
- ) {
- return new CustomAreas(Map.of(), customAreaStart, customAreaEnd);
+ public static CustomAreas empty(CodeWriterConfig config) {
+ return new CustomAreas(new LinkedHashMap<>(), config);
+ }
+
+ public String customAreaStart() {
+ return this.config.customAreaStart;
+ }
+
+ public String customAreaEnd() {
+ return this.config.customAreaEnd;
}
public Iterable<String> lines(String name) {
@@ -103,7 +134,7 @@ public class CodeWriter implements AutoCloseable {
public static void writeTo(
Path path,
- String lineCommentStart,
+ CodeWriterConfig config,
Write write
) throws IOException {
writeTo(
@@ -119,43 +150,104 @@ public class CodeWriter implements AutoCloseable {
return new FileWriter(path.toFile());
}
},
- lineCommentStart,
+ config,
write
);
}
public static void writeTo(
CodeWriterFile file,
- String lineCommentStart,
+ CodeWriterConfig config,
Write write
) throws IOException {
var originalContents = readFile(file);
- var header = lineCommentStart + " Generated by hobgoblin.\n\n";
- if (originalContents.isPresent() && !originalContents.get().startsWith(header)) {
+ if (originalContents.isPresent() && !isGeneratedFile(originalContents.get(), config)) {
return;
}
- var customAreaStart = lineCommentStart + " Custom area start: ";
- var customAreaEnd = lineCommentStart + " Custom area end: ";
-
- var customAreas = readCustomAreas(file, customAreaStart, customAreaEnd);
+ var customAreas = readCustomAreas(file, config);
try (var writer = file.openWriter()) {
// TODO: warn if custom areas are unused?
- write.write(new CodeWriter(writer, header, customAreas));
+ write.write(new CodeWriter(writer, config.header, customAreas));
+ }
+ }
+
+ private static boolean isGeneratedFile(String contents, CodeWriterConfig config) {
+ return contents.startsWith(config.header);
+ }
+
+ public static Stripper stripper(
+ Path outputPath,
+ CodeWriterConfig config
+ ) {
+ return new Stripper(outputPath, config);
+ }
+
+ public static void strip(Path outputPath, CodeWriterConfig config) throws IOException {
+ try (var filesStream = Files.walk(outputPath)) {
+ var filesIterator = filesStream.iterator();
+ while (filesIterator.hasNext()) {
+ var path = filesIterator.next();
+ if (path.toFile().isFile()) {
+ // TODO: filter by extension?
+ // TODO: don't read entire string if not necessary.
+ var contents = Files.readString(path);
+ switch (stripFileContents(contents, config)) {
+ case StripResult.Delete _ -> {
+ Files.delete(path);
+ }
+ case StripResult.NewContent newContent -> {
+ Files.writeString(path, newContent.newContents);
+ }
+ case StripResult.Unchanged _ -> {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sealed interface StripResult {
+ record Unchanged() implements StripResult {}
+ record Delete() implements StripResult {}
+ record NewContent(String newContents) implements StripResult {}
+ }
+
+ static StripResult stripFileContents(String contents, CodeWriterConfig config) {
+ if (!isGeneratedFile(contents, config)) {
+ return new StripResult.Unchanged();
+ }
+
+ var stringWriter = new StringWriter();
+ var customAreas = CustomAreas.read(contents, config);
+ if (customAreas.existing.isEmpty()) {
+ return new StripResult.Delete();
+ }
+
+ var writer = new CodeWriter(stringWriter, config.header, customAreas);
+ try {
+ writer.writeHeader();
+ for (var customAreaName : customAreas.existing.keySet()) {
+ writer.writeCustomArea(customAreaName);
+ }
+ return new StripResult.NewContent(stringWriter.toString());
+ } catch (IOException exception) {
+ // In theory, writing to a StringWriter will always succeed, so
+ // we don't need to handle this especially well.
+ throw new RuntimeException(exception);
}
}
private static CustomAreas readCustomAreas(
CodeWriterFile file,
- String customAreaStart,
- String customAreaEnd
+ CodeWriterConfig config
) throws IOException {
try {
var contents = file.readString();
- return CustomAreas.read(contents, customAreaStart, customAreaEnd);
+ return CustomAreas.read(contents, config);
} catch (NoSuchFileException exception) {
- return CustomAreas.empty(customAreaStart, customAreaEnd);
+ return CustomAreas.empty(config);
}
}
@@ -210,7 +302,7 @@ public class CodeWriter implements AutoCloseable {
}
public void writeCustomArea(String name) throws IOException {
- this.write(this.customAreas.customAreaStart);
+ this.write(this.customAreas.customAreaStart());
this.write(name);
for (var line : this.customAreas.lines(name)) {
@@ -219,7 +311,7 @@ public class CodeWriter implements AutoCloseable {
}
this.newLine();
- this.write(this.customAreas.customAreaEnd);
+ this.write(this.customAreas.customAreaEnd());
this.write(name);
this.newLine();
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/Generator.java
index 4a73000..dd8f46d 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/Generator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/Generator.java
@@ -8,4 +8,5 @@ import java.util.List;
public interface Generator {
void generate(List<TypedNamespaceNode> namespaces, TypesInfo typesInfo) throws IOException;
+ List<Stripper> strippers();
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/Stripper.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/Stripper.java
new file mode 100644
index 0000000..27241eb
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/Stripper.java
@@ -0,0 +1,12 @@
+package org.zwobble.hobgoblin.compiler.output.generators;
+
+import org.zwobble.hobgoblin.compiler.output.CodeWriter;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public record Stripper(Path path, CodeWriter.CodeWriterConfig codeWriterConfig) {
+ public void strip() throws IOException {
+ CodeWriter.strip(path, codeWriterConfig);
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java
index 61fc237..f202f61 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java
@@ -1,6 +1,7 @@
package org.zwobble.hobgoblin.compiler.output.generators.java;
import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.lang.java.JavaWriter;
import org.zwobble.hobgoblin.compiler.output.lang.java.ast.*;
import org.zwobble.hobgoblin.compiler.types.*;
@@ -40,6 +41,10 @@ public class JavaGenerator {
}
}
+ public List<Stripper> strippers(Path sourceRootDirectory) {
+ return List.of(JavaWriter.stripper(sourceRootDirectory));
+ }
+
public JavaPackageName namespaceToJavaPackageName(NamespaceName namespaceName) {
var ancestorNamespaceName = namespaceName;
var remainingNamespaceNameParts = new ArrayList<String>();
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java
index 1ae368e..9b751d0 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java
@@ -5,6 +5,7 @@ import org.zwobble.hobgoblin.compiler.ast.typed.*;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.generators.GeneratorDefinition;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGenerator;
import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGeneratorConfig;
import org.zwobble.hobgoblin.compiler.output.lang.java.ast.*;
@@ -80,6 +81,11 @@ public class JavaPreciselyMatchersGenerator implements Generator {
}
}
+ @Override
+ public List<Stripper> strippers() {
+ return this.javaGenerator.strippers(this.sourceRootDirectory);
+ }
+
private List<JavaCompilationUnit> generateNamespace(TypedNamespaceNode namespace, Context context) {
var javaCompilationUnits = new ArrayList<JavaCompilationUnit>();
@@ -94,6 +100,9 @@ public class JavaPreciselyMatchersGenerator implements Generator {
case TypedNativeTypeDefinitionNode _ -> {
}
+ case TypedQueryDefinitionNode _ -> {
+ }
+
case TypedStructDefinitionNode structDefinition -> {
var javaCompilationUnit = new JavaCompilationUnit(
generateStructDefinition(structDefinition, context)
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java
index 38bf9b6..0220ba9 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java
@@ -6,6 +6,7 @@ import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.generators.GeneratorDefinition;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGenerator;
import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGeneratorConfig;
import org.zwobble.hobgoblin.compiler.output.generators.transient0.Transient0TypeLevelValuesUnsupported;
@@ -96,6 +97,11 @@ public class JavaTransient0Generator implements Generator {
}
}
+ @Override
+ public List<Stripper> strippers() {
+ return this.javaGenerator.strippers(this.sourceRootDirectory);
+ }
+
private void write(List<JavaCompilationUnit> javaCompilationUnits) throws IOException {
JavaGenerator.write(this.sourceRootDirectory, javaCompilationUnits);
}
@@ -662,6 +668,10 @@ public class JavaTransient0Generator implements Generator {
yield List.of();
}
+ case TypedQueryDefinitionNode _ -> {
+ yield List.of();
+ }
+
case TypedStructDefinitionNode structDefinition -> {
yield List.of(
generateEncodeStructMethod(structDefinition, context),
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 e3f54cf..17065e0 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
@@ -7,6 +7,7 @@ import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.generators.GeneratorDefinition;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGenerator;
import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGeneratorConfig;
import org.zwobble.hobgoblin.compiler.output.generators.java.JavaNativeTypeConfig;
@@ -90,6 +91,11 @@ public class JavaTypesGenerator implements Generator {
}
}
+ @Override
+ public List<Stripper> strippers() {
+ return this.javaGenerator.strippers(this.sourceRootDirectory);
+ }
+
private List<JavaCompilationUnit> generateNamespace(TypedNamespaceNode namespace, Context context) {
var javaCompilationUnits = new ArrayList<JavaCompilationUnit>();
@@ -109,6 +115,9 @@ public class JavaTypesGenerator implements Generator {
case TypedNativeTypeDefinitionNode nativeTypeDefinition -> {
}
+ case TypedQueryDefinitionNode _ -> {
+ }
+
case TypedStructDefinitionNode structDefinition -> {
var javaCompilationUnit = new JavaCompilationUnit(
generateStructDefinition(structDefinition, context)
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java
index fae9066..1fd342f 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java
@@ -1,5 +1,6 @@
package org.zwobble.hobgoblin.compiler.output.generators.rust;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.lang.rust.RustWriter;
import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.*;
import org.zwobble.hobgoblin.compiler.types.*;
@@ -32,6 +33,10 @@ public class RustGenerator {
});
}
+ public List<Stripper> strippers() {
+ return List.of(RustWriter.stripper(this.outputPath));
+ }
+
public RustPath generateRustTypeExpression(Type type) {
return switch (type) {
case ConstructedType constructedType -> {
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java
index 8ecc7cc..8f2f4ad 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java
@@ -5,6 +5,7 @@ import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.generators.GeneratorDefinition;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.generators.rust.RustGenerator;
import org.zwobble.hobgoblin.compiler.output.generators.rust.RustGeneratorConfig;
import org.zwobble.hobgoblin.compiler.output.generators.transient0.Transient0TypeLevelValuesUnsupported;
@@ -90,6 +91,11 @@ public class RustTransient0Generator implements Generator {
}
}
+ @Override
+ public List<Stripper> strippers() {
+ return this.rustGenerator.strippers();
+ }
+
private void generateBuiltins() throws IOException {
var rustModuleName = builtinsModuleName();
var rustModule = new RustModule(
@@ -417,6 +423,10 @@ public class RustTransient0Generator implements Generator {
yield Stream.of();
}
+ case TypedQueryDefinitionNode _ -> {
+ yield Stream.of();
+ }
+
case TypedStructDefinitionNode structDefinition -> {
yield Stream.of(
generateEncodeStructFunction(structDefinition),
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java
index f01e143..f57ec33 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java
@@ -4,6 +4,7 @@ import org.zwobble.hobgoblin.compiler.ast.typed.*;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.generators.GeneratorDefinition;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.generators.rust.RustGenerator;
import org.zwobble.hobgoblin.compiler.output.generators.rust.RustGeneratorConfig;
import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.*;
@@ -76,6 +77,11 @@ public class RustTypesGenerator implements Generator {
}
}
+ @Override
+ public List<Stripper> strippers() {
+ return this.rustGenerator.strippers();
+ }
+
private RustModule generateNamespace(TypedNamespaceNode namespace, TypesInfo typesInfo) {
var rustModuleName = this.rustGenerator.namespaceNameToRustCrateModulePath(namespace.namespaceName());
@@ -103,6 +109,10 @@ public class RustTypesGenerator implements Generator {
yield List.of();
}
+ case TypedQueryDefinitionNode _ -> {
+ yield List.of();
+ }
+
case TypedStructDefinitionNode structDefinition -> {
yield generateStructDefinition(structDefinition);
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java
index be847d5..4a23fa1 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java
@@ -1,7 +1,11 @@
package org.zwobble.hobgoblin.compiler.output.generators.sql;
+import org.zwobble.hobgoblin.compiler.ast.typed.Relation;
+import org.zwobble.hobgoblin.compiler.ast.typed.RelationTable;
+import org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode;
import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
+import org.zwobble.hobgoblin.compiler.errors.InternalError;
import org.zwobble.hobgoblin.compiler.output.lang.sql.ast.*;
import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo;
import org.zwobble.hobgoblin.compiler.types.SimpleStructType;
@@ -50,6 +54,55 @@ public class SqlGenerator {
}
}
+ public SqlStatement generateQueryDefinition(
+ TypedQueryDefinitionNode queryDefinition,
+ TypesInfo typesInfo
+ ) {
+ return generateRelation(queryDefinition.relation(), typesInfo);
+ }
+
+ SqlSelectStatement generateRelation(Relation relation, TypesInfo typesInfo) {
+ switch (relation) {
+ case RelationTable relationTable -> {
+ var table = relationTable.table();
+ var schemaInfo = typesInfo.databaseSchemaInfo(table.databaseSchema());
+ var tableInfo = schemaInfo.tables().get(table.name());
+
+ var fields = typesInfo.fieldsOf(tableInfo.rowType())
+ .orElse(List.of());
+
+ // The type-checker should have verified that the row type has
+ // fields, so don't try to handle gracefully here.
+ if (fields.isEmpty()) {
+ throw new InternalError("row type has no fields");
+ }
+
+ var columns = fields.stream()
+ .map(field -> {
+ var columnName = generateColumnName(field.name());
+ return new SqlResultColumn(
+ new SqlRef(columnName),
+ columnName
+ );
+ })
+ .toList();
+
+ // Order by the primary key to ensure stable ordering.
+ var orderBy = List.of(
+ new SqlOrderingTerm(new SqlRef(
+ generateColumnName(tableInfo.primaryKey().name())
+ ))
+ );
+
+ return new SqlSelectStatement(
+ columns,
+ generateTableName(table.name()),
+ orderBy
+ );
+ }
+ }
+ }
+
private SqlIdentifier generateColumnName(String fieldName) {
return new SqlIdentifier(Casing.lowerCamelCaseToSnakeCase(fieldName));
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sqlscripts/SqlScriptsGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sqlscripts/SqlScriptsGenerator.java
index 60daf40..f34a629 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sqlscripts/SqlScriptsGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sqlscripts/SqlScriptsGenerator.java
@@ -1,12 +1,10 @@
package org.zwobble.hobgoblin.compiler.output.generators.sqlscripts;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceNode;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode;
+import org.zwobble.hobgoblin.compiler.ast.typed.*;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.generators.GeneratorDefinition;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.generators.sql.SqlGenerator;
import org.zwobble.hobgoblin.compiler.output.lang.sql.SqlWriter;
import org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlScript;
@@ -69,17 +67,55 @@ public class SqlScriptsGenerator implements Generator {
) throws IOException {
for (var namespace : namespaces) {
for (var namespaceStatement : namespace.body()) {
- if (namespaceStatement instanceof TypedDatabaseSchemaDefinitionNode databaseSchemaDefinition) {
- generateDatabaseSchemaDefinition(
- databaseSchemaDefinition,
- namespace.namespaceName(),
- typesInfo
- );
- }
+ generateNamespaceStatement(
+ namespaceStatement,
+ namespace.namespaceName(),
+ typesInfo
+ );
}
}
}
+ private void generateNamespaceStatement(
+ TypedNamespaceStatementNode namespaceStatement,
+ NamespaceName namespaceName,
+ TypesInfo typesInfo
+ ) throws IOException {
+ switch (namespaceStatement) {
+ case TypedDatabaseSchemaDefinitionNode databaseSchemaDefinition ->
+ generateDatabaseSchemaDefinition(
+ databaseSchemaDefinition,
+ namespaceName,
+ typesInfo
+ );
+
+ case TypedEnumDefinitionNode _ -> {
+ }
+
+ case TypedNativeTypeDefinitionNode _ -> {
+ }
+
+ case TypedQueryDefinitionNode queryDefinition -> {
+ generateQueryDefinition(
+ queryDefinition,
+ namespaceName,
+ typesInfo
+ );
+ }
+
+ case TypedStructDefinitionNode _ -> {
+ }
+
+ case TypedSumDefinitionNode _ -> {
+ }
+ }
+ }
+
+ @Override
+ public List<Stripper> strippers() {
+ return List.of(SqlWriter.stripper(this.outputPath));
+ }
+
private void generateDatabaseSchemaDefinition(
TypedDatabaseSchemaDefinitionNode databaseSchemaDefinition,
NamespaceName namespaceName,
@@ -104,6 +140,17 @@ public class SqlScriptsGenerator implements Generator {
};
}
+ private void generateQueryDefinition(
+ TypedQueryDefinitionNode queryDefinition,
+ NamespaceName namespaceName,
+ TypesInfo typesInfo
+ ) throws IOException {
+ var sqlQuery = this.sqlGenerator.generateQueryDefinition(queryDefinition, typesInfo);
+ var sqlScript = new SqlScript(List.of(sqlQuery));
+
+ write(namespaceName, queryDefinition.name(), sqlScript);
+ }
+
private void write(
NamespaceName namespaceName,
String schemaName,
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java
index 68d1610..a16d1f3 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java
@@ -1,6 +1,7 @@
package org.zwobble.hobgoblin.compiler.output.generators.typescript;
import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.lang.typescript.TypescriptTypes;
import org.zwobble.hobgoblin.compiler.output.lang.typescript.TypescriptWriter;
import org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.*;
@@ -33,6 +34,10 @@ public class TypescriptGenerator {
TypescriptWriter.writeTo(path, writer -> writer.writeModule(module));
}
+ public List<Stripper> strippers() {
+ return List.of(TypescriptWriter.stripper(this.outputPath));
+ }
+
public record RequiredType(SimpleType type, TypescriptIdentifier importName) {}
public static class Context {
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java
index 6dd8592..cbdf016 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java
@@ -4,6 +4,7 @@ import org.zwobble.hobgoblin.compiler.ast.typed.*;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.generators.GeneratorDefinition;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.generators.typescript.TypescriptGenerator;
import org.zwobble.hobgoblin.compiler.output.generators.typescript.TypescriptGeneratorConfig;
import org.zwobble.hobgoblin.compiler.output.lang.typescript.TypescriptTypes;
@@ -78,6 +79,11 @@ public class TypescriptTypesGenerator implements Generator {
}
}
+ @Override
+ public List<Stripper> strippers() {
+ return this.typescriptGenerator.strippers();
+ }
+
private TypescriptModule generateNamespace(
TypedNamespaceNode namespace,
TypesInfo typesInfo
@@ -148,6 +154,10 @@ public class TypescriptTypesGenerator implements Generator {
return List.of();
}
+ case TypedQueryDefinitionNode _ -> {
+ return List.of();
+ }
+
case TypedStructDefinitionNode structDefinition -> {
return generateStructDefinition(structDefinition, context);
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java
index d2f46ad..2d17085 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/JavaWriter.java
@@ -2,6 +2,7 @@ package org.zwobble.hobgoblin.compiler.output.lang.java;
import org.zwobble.hobgoblin.compiler.ast.DocComment;
import org.zwobble.hobgoblin.compiler.output.CodeWriter;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.lang.java.ast.*;
import java.io.IOException;
@@ -14,6 +15,8 @@ import static org.zwobble.hobgoblin.compiler.output.CodeWriter.writeWithSeparato
public class JavaWriter implements AutoCloseable {
private static final String LINE_COMMENT_START = "//";
+ private static final CodeWriter.CodeWriterConfig CONFIG =
+ new CodeWriter.CodeWriterConfig(LINE_COMMENT_START);
public interface Write {
void write(JavaWriter writer) throws IOException;
@@ -22,7 +25,7 @@ public class JavaWriter implements AutoCloseable {
public static void writeTo(Path path, Write write) throws IOException {
CodeWriter.writeTo(
path,
- LINE_COMMENT_START,
+ CONFIG,
writer -> write.write(new JavaWriter(writer))
);
}
@@ -30,11 +33,15 @@ public class JavaWriter implements AutoCloseable {
public static void writeTo(CodeWriter.CodeWriterFile file, Write write) throws IOException {
CodeWriter.writeTo(
file,
- LINE_COMMENT_START,
+ CONFIG,
writer -> write.write(new JavaWriter(writer))
);
}
+ public static Stripper stripper(Path sourceRootDirectory) {
+ return CodeWriter.stripper(sourceRootDirectory, CONFIG);
+ }
+
private final CodeWriter writer;
public JavaWriter(CodeWriter writer) {
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java
index df8aa8c..076e150 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java
@@ -2,6 +2,7 @@ package org.zwobble.hobgoblin.compiler.output.lang.rust;
import org.zwobble.hobgoblin.compiler.ast.DocComment;
import org.zwobble.hobgoblin.compiler.output.CodeWriter;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.*;
import java.io.IOException;
@@ -14,6 +15,8 @@ import static org.zwobble.hobgoblin.compiler.output.CodeWriter.writeWithSeparato
public class RustWriter implements AutoCloseable {
private static final String LINE_COMMENT_START = "//";
+ private static final CodeWriter.CodeWriterConfig CONFIG =
+ new CodeWriter.CodeWriterConfig(LINE_COMMENT_START);
public interface Write {
void write(RustWriter writer) throws IOException;
@@ -22,7 +25,7 @@ public class RustWriter implements AutoCloseable {
public static void writeTo(Path path, Write write) throws IOException {
CodeWriter.writeTo(
path,
- LINE_COMMENT_START,
+ CONFIG,
writer -> write.write(new RustWriter(writer))
);
}
@@ -30,11 +33,15 @@ public class RustWriter implements AutoCloseable {
public static void writeTo(CodeWriter.CodeWriterFile file, Write write) throws IOException {
CodeWriter.writeTo(
file,
- LINE_COMMENT_START,
+ CONFIG,
writer -> write.write(new RustWriter(writer))
);
}
+ public static Stripper stripper(Path outputPath) {
+ return CodeWriter.stripper(outputPath, CONFIG);
+ }
+
private final CodeWriter writer;
public RustWriter(CodeWriter writer) {
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/SqlWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/SqlWriter.java
index b6edc1b..7f0c17a 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/SqlWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/SqlWriter.java
@@ -1,6 +1,7 @@
package org.zwobble.hobgoblin.compiler.output.lang.sql;
import org.zwobble.hobgoblin.compiler.output.CodeWriter;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.lang.sql.ast.*;
import java.io.IOException;
@@ -10,6 +11,8 @@ import static org.zwobble.hobgoblin.compiler.output.CodeWriter.writeWithSeparato
public class SqlWriter {
private static final String LINE_COMMENT_START = "--";
+ private static final CodeWriter.CodeWriterConfig CONFIG =
+ new CodeWriter.CodeWriterConfig(LINE_COMMENT_START);
public interface Write {
void write(SqlWriter writer) throws IOException;
@@ -18,7 +21,7 @@ public class SqlWriter {
public static void writeTo(Path path, Write write) throws IOException {
CodeWriter.writeTo(
path,
- LINE_COMMENT_START,
+ CONFIG,
writer -> write.write(new SqlWriter(writer))
);
}
@@ -26,11 +29,15 @@ public class SqlWriter {
public static void writeTo(CodeWriter.CodeWriterFile file, Write write) throws IOException {
CodeWriter.writeTo(
file,
- LINE_COMMENT_START,
+ CONFIG,
writer -> write.write(new SqlWriter(writer))
);
}
+ public static Stripper stripper(Path outputPath) {
+ return CodeWriter.stripper(outputPath, CONFIG);
+ }
+
private final CodeWriter writer;
public SqlWriter(CodeWriter writer) {
@@ -61,6 +68,10 @@ public class SqlWriter {
case SqlCreateTableStatement createTableStatement -> {
writeCreateTableStatement(createTableStatement);
}
+
+ case SqlSelectStatement selectStatement -> {
+ writeSelectStatement(selectStatement);
+ }
}
}
@@ -97,6 +108,43 @@ public class SqlWriter {
this.writeIdentifier(column.typeName());
}
+ private void writeSelectStatement(SqlSelectStatement selectStatement) throws IOException {
+ this.writer.write("SELECT");
+ this.writer.newLine();
+ this.writer.indent();
+
+ writeWithSeparator(
+ selectStatement.columns(),
+ column -> {
+ this.writeExpression(column.expression());
+ this.writer.write(" AS ");
+ this.writeIdentifier(column.alias());
+ },
+ () -> {
+ this.writer.write(",");
+ this.writer.newLine();
+ }
+ );
+
+ this.writer.newLine();
+ this.writer.dedent();
+ this.writer.write("FROM ");
+ this.writeIdentifier(selectStatement.from());
+
+ if (!selectStatement.orderBy().isEmpty()) {
+ this.writer.newLine();
+ this.writer.write("ORDER BY ");
+
+ writeWithSeparator(
+ selectStatement.orderBy(),
+ orderingTerm -> this.writeExpression(orderingTerm.expression()),
+ () -> this.writer.write(", ")
+ );
+ }
+
+ this.writer.write(";");
+ }
+
// == Table constraints ==
void writeTableConstraint(SqlTableConstraint tableConstraint) throws IOException {
@@ -117,6 +165,28 @@ public class SqlWriter {
this.writer.write(")");
}
+ // == Expressions ==
+
+ void writeExpression(SqlExpression expression) throws IOException {
+ switch (expression) {
+ case SqlIntLiteral intLiteral -> {
+ this.writeIntLiteral(intLiteral);
+ }
+
+ case SqlRef ref -> {
+ this.writeRef(ref);
+ }
+ }
+ }
+
+ private void writeIntLiteral(SqlIntLiteral intLiteral) throws IOException {
+ this.writer.write(Long.toString(intLiteral.value()));
+ }
+
+ private void writeRef(SqlRef ref) throws IOException {
+ this.writeIdentifier(ref.name());
+ }
+
// == Identifiers ==
private void writeIdentifier(SqlIdentifier name) throws IOException {
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlExpression.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlExpression.java
new file mode 100644
index 0000000..8479160
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlExpression.java
@@ -0,0 +1,18 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.sql.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression imports
+
+public sealed interface SqlExpression permits org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral, org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef {
+ public interface Builder {
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression build();
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlIntLiteral.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlIntLiteral.java
new file mode 100644
index 0000000..8a6c3a4
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlIntLiteral.java
@@ -0,0 +1,32 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.sql.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral imports
+
+public record SqlIntLiteral(
+ long value
+) implements org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression {
+ public static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral.Builder(0);
+ }
+
+ public record Builder(
+ long value
+ ) implements org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression.Builder {
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral(value);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral.Builder withValue(long value) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral.Builder(value);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlOrderingTerm.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlOrderingTerm.java
new file mode 100644
index 0000000..80ca2e6
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlOrderingTerm.java
@@ -0,0 +1,36 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.sql.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm imports
+
+public record SqlOrderingTerm(
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression expression
+) {
+ public static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.Builder(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral.arbitrary().build());
+ }
+
+ public record Builder(
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression expression
+ ) {
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm(expression);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.Builder withExpression(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression expression) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.Builder(expression);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.Builder withExpression(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression.Builder expression) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.Builder(expression.build());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlRef.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlRef.java
new file mode 100644
index 0000000..156e6ab
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlRef.java
@@ -0,0 +1,36 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.sql.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef imports
+
+public record SqlRef(
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier name
+) implements org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression {
+ public static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef.Builder(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier.arbitrary().build());
+ }
+
+ public record Builder(
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier name
+ ) implements org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression.Builder {
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef(name);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef.Builder(name);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef.Builder withName(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier.Builder name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef.Builder(name.build());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRef body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlResultColumn.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlResultColumn.java
new file mode 100644
index 0000000..26516b0
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlResultColumn.java
@@ -0,0 +1,46 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.sql.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn imports
+
+public record SqlResultColumn(
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression expression,
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier alias
+) {
+ public static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIntLiteral.arbitrary().build(), org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier.arbitrary().build());
+ }
+
+ public record Builder(
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression expression,
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier alias
+ ) {
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn(expression, alias);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder withExpression(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression expression) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder(expression, alias);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder withExpression(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlExpression.Builder expression) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder(expression.build(), alias);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder withAlias(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier alias) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder(expression, alias);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder withAlias(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier.Builder alias) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder(expression, alias.build());
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlSelectStatement.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlSelectStatement.java
new file mode 100644
index 0000000..8bd29a2
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlSelectStatement.java
@@ -0,0 +1,72 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.sql.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement imports
+
+public record SqlSelectStatement(
+ java.util.List<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn> columns,
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier from,
+ java.util.List<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm> orderBy
+) implements org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlStatement {
+ public static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder(java.util.List.of(), org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier.arbitrary().build(), java.util.List.of());
+ }
+
+ public record Builder(
+ java.util.List<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn> columns,
+ org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier from,
+ java.util.List<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm> orderBy
+ ) implements org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlStatement.Builder {
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement(columns, from, orderBy);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder withColumns(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn> columns) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder(columns, from, orderBy);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder addColumn(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn column) {
+ var columns = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn>(this.columns);
+ columns.add(column);
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder(columns, from, orderBy);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder addColumn(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn.Builder column) {
+ var columns = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumn>(this.columns);
+ columns.add(column.build());
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder(columns, from, orderBy);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder withFrom(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier from) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder(columns, from, orderBy);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder withFrom(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier.Builder from) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder(columns, from.build(), orderBy);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder withOrderBy(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm> orderBy) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder(columns, from, orderBy);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder addOrderByElement(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm orderByElement) {
+ var orderBy = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm>(this.orderBy);
+ orderBy.add(orderByElement);
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder(columns, from, orderBy);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder addOrderByElement(org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm.Builder orderByElement) {
+ var orderBy = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTerm>(this.orderBy);
+ orderBy.add(orderByElement.build());
+ return new org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder(columns, from, orderBy);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlStatement.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlStatement.java
index 0f90dc1..a6d4ab2 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlStatement.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/sql/ast/SqlStatement.java
@@ -5,7 +5,7 @@ package org.zwobble.hobgoblin.compiler.output.lang.sql.ast;
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlStatement imports
// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlStatement imports
-public sealed interface SqlStatement permits org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlCreateTableStatement {
+public sealed interface SqlStatement permits org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlCreateTableStatement, org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatement {
public interface Builder {
public org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlStatement build();
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java
index 3d5d99f..72e9cf5 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java
@@ -2,6 +2,7 @@ package org.zwobble.hobgoblin.compiler.output.lang.typescript;
import org.zwobble.hobgoblin.compiler.ast.DocComment;
import org.zwobble.hobgoblin.compiler.output.CodeWriter;
+import org.zwobble.hobgoblin.compiler.output.generators.Stripper;
import org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.*;
import java.io.IOException;
@@ -11,6 +12,8 @@ import static org.zwobble.hobgoblin.compiler.output.CodeWriter.writeWithSeparato
public class TypescriptWriter implements AutoCloseable {
private static final String LINE_COMMENT_START = "//";
+ private static final CodeWriter.CodeWriterConfig CONFIG =
+ new CodeWriter.CodeWriterConfig(LINE_COMMENT_START);
public interface Write {
void write(TypescriptWriter writer) throws IOException;
@@ -19,7 +22,7 @@ public class TypescriptWriter implements AutoCloseable {
public static void writeTo(Path path, Write write) throws IOException {
CodeWriter.writeTo(
path,
- LINE_COMMENT_START,
+ CONFIG,
writer -> write.write(new TypescriptWriter(writer))
);
}
@@ -27,11 +30,15 @@ public class TypescriptWriter implements AutoCloseable {
public static void writeTo(CodeWriter.CodeWriterFile file, Write write) throws IOException {
CodeWriter.writeTo(
file,
- LINE_COMMENT_START,
+ CONFIG,
writer -> write.write(new TypescriptWriter(writer))
);
}
+ public static Stripper stripper(Path outputPath) {
+ return CodeWriter.stripper(outputPath, CONFIG);
+ }
+
private final CodeWriter writer;
public TypescriptWriter(CodeWriter writer) {
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/parser/OperationParser.java b/src/main/java/org/zwobble/hobgoblin/compiler/parser/OperationParser.java
new file mode 100644
index 0000000..27c2740
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/parser/OperationParser.java
@@ -0,0 +1,15 @@
+package org.zwobble.hobgoblin.compiler.parser;
+
+import org.zwobble.sourcetext.SourcePosition;
+
+import java.util.List;
+
+interface OperationParser<TOperatorPrecedence, TNode> {
+ TOperatorPrecedence precedence();
+ List<TokenType> operatorTokenTypes();
+ TNode parse(
+ SourcePosition start,
+ TNode left,
+ TokenIterator tokens
+ );
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/parser/OperatorPrecedence.java b/src/main/java/org/zwobble/hobgoblin/compiler/parser/OperatorPrecedence.java
new file mode 100644
index 0000000..13c38db
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/parser/OperatorPrecedence.java
@@ -0,0 +1,6 @@
+package org.zwobble.hobgoblin.compiler.parser;
+
+enum OperatorPrecedence {
+ CALL,
+ COMPARE,
+}
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 3563d0a..b4bb07d 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/parser/Parser.java
@@ -9,11 +9,15 @@ import org.zwobble.hobgoblin.compiler.types.QualifiedTypeName;
import org.zwobble.sourcetext.SourcePosition;
import org.zwobble.sourcetext.SourceText;
+import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
public class Parser {
private Parser() {
@@ -71,7 +75,7 @@ public class Parser {
);
tokens.skip(TokenType.SYMBOL_BRACE_CLOSE);
- tokens.skip(TokenType.KEYWORD_FROM);
+ tokens.skip(TokenType.IDENTIFIER, "from");
var isSibling = tokens.trySkip(TokenType.SYMBOL_DOT);
@@ -113,6 +117,8 @@ public class Parser {
return parseEnumDefinition(tokens, docComment);
} else if (tokens.isNext(TokenType.KEYWORD_NATIVE)) {
return parseNativeTypeDefinition(tokens, docComment);
+ } else if (tokens.isNext(TokenType.IDENTIFIER, "query")) {
+ return parseQueryDefinition(tokens, docComment);
} else if (tokens.isNext(TokenType.KEYWORD_STRUCT)) {
return parseStructDefinition(tokens, docComment);
} else if (tokens.isNext(TokenType.KEYWORD_SUM)) {
@@ -239,6 +245,39 @@ public class Parser {
return new DocComment(docComment.toString());
}
+ private static UntypedQueryDefinitionNode parseQueryDefinition(
+ TokenIterator tokens,
+ DocComment docComment
+ ) {
+ var start = tokens.startPosition();
+
+ tokens.skip(TokenType.IDENTIFIER, "query");
+ var name = parseIdentifier(tokens);
+
+ tokens.skip(TokenType.SYMBOL_PAREN_OPEN);
+ tokens.skip(TokenType.SYMBOL_PAREN_CLOSE);
+
+ tokens.skip(TokenType.SYMBOL_BRACE_OPEN);
+
+ var statements = parseMany(
+ () -> tokens.isNext(TokenType.SYMBOL_BRACE_CLOSE),
+ () -> parseStatement(tokens),
+ () -> true
+ );
+
+ tokens.skip(TokenType.SYMBOL_BRACE_CLOSE);
+
+ var end = tokens.endPosition();
+ var source = createSource(start, end);
+
+ return new UntypedQueryDefinitionNode(
+ name,
+ statements,
+ docComment,
+ source
+ );
+ }
+
private static UntypedStructDefinitionNode parseStructDefinition(
TokenIterator tokens,
DocComment docComment
@@ -371,7 +410,7 @@ public class Parser {
tokens.skip(TokenType.SYMBOL_SEMICOLON);
tokens.skip(TokenType.IDENTIFIER, "primaryKey");
- var primaryKey = parseIdentifier(tokens);
+ var primaryKey = parseTypeLevelReference(tokens);
tokens.skip(TokenType.SYMBOL_SEMICOLON);
tokens.skip(TokenType.SYMBOL_BRACE_CLOSE);
@@ -415,6 +454,19 @@ public class Parser {
return Optional.of(typeParams);
}
+ // == Params ==
+
+ private static UntypedParamNode parseParam(TokenIterator tokens) {
+ var start = tokens.startPosition();
+
+ var name = parseIdentifier(tokens);
+
+ var end = tokens.endPosition();
+ var source = createSource(start, end);
+
+ return new UntypedParamNode(name, source);
+ }
+
// == Type-level expressions ==
static UntypedTypeLevelExpressionNode parseTypeLevelExpression(
@@ -442,6 +494,10 @@ public class Parser {
}
private static UntypedTypeLevelReferenceNode parsePrimaryTypeLevelExpression(TokenIterator tokens) {
+ return parseTypeLevelReference(tokens);
+ }
+
+ private static UntypedTypeLevelReferenceNode parseTypeLevelReference(TokenIterator tokens) {
var start = tokens.startPosition();
var name = parseIdentifier(tokens);
@@ -455,6 +511,235 @@ public class Parser {
);
}
+ // == Statements ==
+
+ static UntypedStatementNode parseStatement(TokenIterator tokens) {
+ if (tokens.isNext(TokenType.IDENTIFIER, "return")) {
+ return parseReturn(tokens);
+ } else {
+ throw new UnsupportedOperationException("TODO");
+ }
+ }
+
+ private static UntypedReturnNode parseReturn(TokenIterator tokens) {
+ var start = tokens.startPosition();
+
+ tokens.skip(TokenType.IDENTIFIER, "return");
+ var expression = parseTopLevelExpression(tokens);
+ tokens.skip(TokenType.SYMBOL_SEMICOLON);
+
+ var end = tokens.endPosition();
+ var source = createSource(start, end);
+
+ return new UntypedReturnNode(expression, source);
+ }
+
+ // == Expressions ==
+
+ static UntypedExpressionNode parseTopLevelExpression(TokenIterator tokens) {
+ return parseExpression(tokens, Optional.empty());
+ }
+
+ private static UntypedExpressionNode parseExpression(
+ TokenIterator tokens,
+ Optional<OperatorPrecedence> parentPrecedence
+ ) {
+ var start = tokens.startPosition();
+ var left = parsePrimaryExpression(tokens);
+
+ while (true) {
+ var operationParser = OPERATION_PARSERS.get(tokens.peek().tokenType());
+ if (operationParser == null || parentPrecedence.isPresent() && operationParser.precedence().ordinal() <= parentPrecedence.get().ordinal()) {
+ return left;
+ }
+ left = operationParser.parse(start, left, tokens);
+ }
+ }
+
+ private static UntypedExpressionNode parsePrimaryExpression(
+ TokenIterator tokens
+ ) {
+ if (tokens.isNext(TokenType.SYMBOL_DOLLAR)) {
+ return parseFunctionExpression(tokens);
+ } else if (tokens.isNext(TokenType.NUMBER)) {
+ return parseNumberLiteral(tokens);
+ } else if (tokens.isNext(TokenType.IDENTIFIER)) {
+ return parseReference(tokens);
+ } else {
+ throw new UnsupportedOperationException("TODO");
+ }
+ }
+
+ private static UntypedFunctionExpressionNode parseFunctionExpression(TokenIterator tokens) {
+ var start = tokens.startPosition();
+
+ tokens.skip(TokenType.SYMBOL_DOLLAR);
+ tokens.skip(TokenType.SYMBOL_PAREN_OPEN);
+
+ var params = parseMany(
+ () -> tokens.isNext(TokenType.SYMBOL_PAREN_CLOSE),
+ () -> parseParam(tokens),
+ () -> tokens.trySkip(TokenType.SYMBOL_COMMA)
+ );
+
+ tokens.skip(TokenType.SYMBOL_PAREN_CLOSE);
+ tokens.skip(TokenType.SYMBOL_FAT_ARROW);
+
+ var body = parseTopLevelExpression(tokens);
+
+ var end = tokens.endPosition();
+ var source = createSource(start, end);
+
+ return new UntypedFunctionExpressionNode(
+ params,
+ body,
+ source
+ );
+ }
+
+ private static UntypedNumberLiteralNode parseNumberLiteral(TokenIterator tokens) {
+ var start = tokens.startPosition();
+
+ var valueToken = tokens.next(TokenType.NUMBER);
+ var value = new BigDecimal(valueToken.charSequence().toString());
+
+ var end = tokens.endPosition();
+ var source = createSource(start, end);
+
+ return new UntypedNumberLiteralNode(value, source);
+ }
+
+ private static UntypedReferenceNode parseReference(TokenIterator tokens) {
+ var start = tokens.startPosition();
+
+ var name = parseIdentifier(tokens);
+
+ var end = tokens.endPosition();
+ var source = createSource(start, end);
+
+ return new UntypedReferenceNode(name, source);
+ }
+
+ private static class BinaryOperationParser implements OperationParser<OperatorPrecedence, UntypedExpressionNode> {
+ private final UntypedBinaryOperator operator;
+ private final OperatorPrecedence precedence;
+ private final TokenType operatorTokenType;
+
+ public BinaryOperationParser(
+ UntypedBinaryOperator operator,
+ OperatorPrecedence precedence,
+ TokenType operatorTokenType
+ ) {
+ this.operator = operator;
+ this.precedence = precedence;
+ this.operatorTokenType = operatorTokenType;
+ }
+
+ @Override
+ public OperatorPrecedence precedence() {
+ return precedence;
+ }
+
+ @Override
+ public List<TokenType> operatorTokenTypes() {
+ return List.of(operatorTokenType);
+ }
+
+ @Override
+ public UntypedExpressionNode parse(SourcePosition start, UntypedExpressionNode left, TokenIterator tokens) {
+ tokens.skip(operatorTokenType);
+
+ var right = parseExpression(tokens, Optional.of(precedence));
+
+ var end = tokens.endPosition();
+ var source = createSource(start, end);
+
+ return new UntypedBinaryOperationNode(operator, left, right, source);
+ }
+ }
+
+ private static final OperationParser<OperatorPrecedence, UntypedExpressionNode> CALL_PARSER = new OperationParser<>() {
+ @Override
+ public OperatorPrecedence precedence() {
+ return OperatorPrecedence.CALL;
+ }
+
+ @Override
+ public List<TokenType> operatorTokenTypes() {
+ return List.of(TokenType.SYMBOL_PAREN_OPEN);
+ }
+
+ @Override
+ public UntypedExpressionNode parse(
+ SourcePosition start,
+ UntypedExpressionNode left,
+ TokenIterator tokens
+ ) {
+ tokens.skip(TokenType.SYMBOL_PAREN_OPEN);
+
+ var args = parseMany(
+ () -> tokens.isNext(TokenType.SYMBOL_PAREN_CLOSE),
+ () -> parseTopLevelExpression(tokens),
+ () -> tokens.trySkip(TokenType.SYMBOL_COMMA)
+ );
+
+ tokens.skip(TokenType.SYMBOL_PAREN_CLOSE);
+
+ var end = tokens.endPosition();
+ var source = createSource(start, end);
+
+ return new UntypedCallNode(left, args, source);
+ }
+ };
+
+ private static final OperationParser<OperatorPrecedence, UntypedExpressionNode> MEMBER_ACCESS_PARSER = new OperationParser<>() {
+ @Override
+ public OperatorPrecedence precedence() {
+ return OperatorPrecedence.CALL;
+ }
+
+ @Override
+ public List<TokenType> operatorTokenTypes() {
+ return List.of(TokenType.SYMBOL_DOT);
+ }
+
+ @Override
+ public UntypedExpressionNode parse(
+ SourcePosition start,
+ UntypedExpressionNode left,
+ TokenIterator tokens
+ ) {
+ tokens.skip(TokenType.SYMBOL_DOT);
+ var fieldName = parseIdentifier(tokens);
+
+ var end = tokens.endPosition();
+ var source = createSource(start, end);
+
+ return new UntypedMemberAccessNode(left, fieldName, source);
+ }
+ };
+
+ private static final BinaryOperationParser EQUALS_OPERATION_PARSER = new BinaryOperationParser(
+ UntypedBinaryOperator.EQUALS,
+ OperatorPrecedence.COMPARE,
+ TokenType.SYMBOL_EQUALS_EQUALS
+ );
+
+ private static final Map<TokenType, OperationParser<OperatorPrecedence, UntypedExpressionNode>> OPERATION_PARSERS = Stream.of(
+ CALL_PARSER,
+ EQUALS_OPERATION_PARSER,
+ MEMBER_ACCESS_PARSER
+ )
+ .flatMap(parser ->
+ parser.operatorTokenTypes().stream().map(tokenType -> Map.entry(tokenType, parser))
+ )
+ .collect(Collectors.toMap(
+ x -> x.getKey(),
+ x -> x.getValue()
+ ));
+
+ // == Qualified type names ==
+
public static QualifiedTypeName parseQualifiedTypeName(SourceText sourceText) {
var tokens = Tokenizer.tokenize(sourceText);
var tokenIterator = tokens.iterator();
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/parser/TokenType.java b/src/main/java/org/zwobble/hobgoblin/compiler/parser/TokenType.java
index 2a85072..5896d6f 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/parser/TokenType.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/parser/TokenType.java
@@ -4,11 +4,11 @@ enum TokenType {
DOC_COMMENT,
END,
IDENTIFIER,
+ NUMBER,
WHITESPACE,
KEYWORD_ENUM,
KEYWORD_FIELD,
- KEYWORD_FROM,
KEYWORD_IMPORT,
KEYWORD_NATIVE,
KEYWORD_STRUCT,
@@ -19,8 +19,11 @@ enum TokenType {
SYMBOL_BRACE_CLOSE,
SYMBOL_COLON,
SYMBOL_COMMA,
+ SYMBOL_DOLLAR,
SYMBOL_DOT,
SYMBOL_DOT_DOT,
+ SYMBOL_EQUALS_EQUALS,
+ SYMBOL_FAT_ARROW,
SYMBOL_FORWARD_SLASH,
SYMBOL_PAREN_OPEN,
SYMBOL_PAREN_CLOSE,
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/parser/Tokenizer.java b/src/main/java/org/zwobble/hobgoblin/compiler/parser/Tokenizer.java
index 1a775b0..b36ca12 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/parser/Tokenizer.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/parser/Tokenizer.java
@@ -55,6 +55,11 @@ class Tokenizer {
return identifierOrKeyword;
}
+ var number = tokenizeNumber(iterator);
+ if (number.isPresent()) {
+ return number;
+ }
+
var docComment = tokenizeDocComment(iterator);
if (docComment.isPresent()) {
return docComment;
@@ -126,8 +131,6 @@ class Tokenizer {
tokenType = TokenType.KEYWORD_ENUM;
} else if (CharSequence.compare(sourceRange.charSequence(), "field") == 0) {
tokenType = TokenType.KEYWORD_FIELD;
- } else if (CharSequence.compare(sourceRange.charSequence(), "from") == 0) {
- tokenType = TokenType.KEYWORD_FROM;
} else if (CharSequence.compare(sourceRange.charSequence(), "import") == 0) {
tokenType = TokenType.KEYWORD_IMPORT;
} else if (CharSequence.compare(sourceRange.charSequence(), "native") == 0) {
@@ -146,6 +149,30 @@ class Tokenizer {
return Optional.of(token);
}
+ private static Optional<Token> tokenizeNumber(CharacterIterator iterator) {
+ var firstChar = iterator.peek();
+ if (!(firstChar >= '1' && firstChar <= '9')) {
+ return Optional.empty();
+ }
+
+ var start = iterator.position();
+
+ while (true) {
+ var nextChar = iterator.peek();
+ if (!(nextChar >= '0' && nextChar <= '9')) {
+ if (Character.isAlphabetic(nextChar)) {
+ throw new ParseError("number must contain only digits", iterator.characterSourceRange());
+ }
+
+ var end = iterator.position();
+ var token = new Token(TokenType.NUMBER, start.to(end));
+ return Optional.of(token);
+ }
+
+ iterator.skip();
+ }
+ }
+
private static Optional<Token> tokenizeSymbol(CharacterIterator iterator) {
TokenType tokenType;
var start = iterator.position();
@@ -154,6 +181,14 @@ class Tokenizer {
tokenType = TokenType.SYMBOL_DOT_DOT;
iterator.skip();
iterator.skip();
+ } else if ("=>".contentEquals(iterator.peekSequence(2))) {
+ tokenType = TokenType.SYMBOL_FAT_ARROW;
+ iterator.skip();
+ iterator.skip();
+ } else if ("==".contentEquals(iterator.peekSequence(2))) {
+ tokenType = TokenType.SYMBOL_EQUALS_EQUALS;
+ iterator.skip();
+ iterator.skip();
} else {
switch (iterator.peek()) {
case '{':
@@ -176,6 +211,11 @@ class Tokenizer {
iterator.skip();
break;
+ case '$':
+ tokenType = TokenType.SYMBOL_DOLLAR;
+ iterator.skip();
+ break;
+
case '.':
tokenType = TokenType.SYMBOL_DOT;
iterator.skip();
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
index c8dfc05..c3f664c 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
@@ -9,6 +9,7 @@ import org.zwobble.hobgoblin.compiler.typechecker.errors.NoSuchFieldError;
import org.zwobble.hobgoblin.compiler.types.*;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -21,6 +22,8 @@ public class TypeChecker {
private TypeChecker() {
}
+ // == Namespaces ==
+
public static List<TypedNamespaceNode> typeCheckNamespaces(
List<UntypedNamespaceNode> untypedNamespaces,
TypeCheckerGlobalContext context
@@ -89,13 +92,18 @@ public class TypeChecker {
return typedNamespaceNodes;
}
+ // == Namespace statements ==
+
static Optional<Type> declareNamespaceStatement(
UntypedNamespaceStatementNode untyped,
TypeCheckerNamespaceContext context
) {
return switch (untyped) {
- case UntypedDatabaseSchemaDefinitionNode _ ->
- Optional.empty();
+ case UntypedDatabaseSchemaDefinitionNode untypedDatabaseSchemaDefinition ->
+ Optional.of(declareDatabaseSchemaDefinition(
+ untypedDatabaseSchemaDefinition,
+ context
+ ));
case UntypedEnumDefinitionNode untypedEnumDefinitionNode ->
Optional.of(declareEnumDefinitionNode(untyped, context));
@@ -103,6 +111,9 @@ public class TypeChecker {
case UntypedNativeTypeDefinitionNode untypedNativeTypeDefinition ->
Optional.of(declareNativeTypeDefinition(untypedNativeTypeDefinition, context));
+ case UntypedQueryDefinitionNode _ ->
+ Optional.empty();
+
case UntypedStructDefinitionNode untypedStructDefinition ->
Optional.of(declareStructDefinition(untypedStructDefinition, context));
@@ -125,6 +136,9 @@ public class TypeChecker {
case UntypedNativeTypeDefinitionNode untypedNativeTypeDefinition ->
defineNativeTypeDefinition(untypedNativeTypeDefinition, context);
+ case UntypedQueryDefinitionNode untypedQueryDefinition ->
+ defineQueryDefinition(untypedQueryDefinition, context);
+
case UntypedStructDefinitionNode untypedStructDefinition ->
defineStructDefinition(untypedStructDefinition, context);
@@ -133,15 +147,39 @@ public class TypeChecker {
};
}
+ private static Type declareDatabaseSchemaDefinition(
+ UntypedDatabaseSchemaDefinitionNode untyped,
+ TypeCheckerNamespaceContext context
+ ) {
+ var databaseSchema = new DatabaseSchema(context.namespaceName(), untyped.name());
+ var type = Types.databaseSchema(databaseSchema);
+
+ context.declare(untyped.name(), type, untyped.source());
+
+ return type;
+ }
+
private static TypedNamespaceStatementNode defineDatabaseSchemaDefinition(
UntypedDatabaseSchemaDefinitionNode untyped,
TypeCheckerNamespaceContext context
) {
+ var databaseSchema = new DatabaseSchema(context.namespaceName(), untyped.name());
+ var databaseSchemaInfo = new DatabaseSchemaInfo(new LinkedHashMap<>());
+
+ var typedBody = untyped.body().stream()
+ .map(statement -> typeCheckDatabaseSchemaStatement(
+ statement,
+ databaseSchema,
+ databaseSchemaInfo,
+ context
+ ))
+ .toList();
+
+ context.defineDatabaseSchema(databaseSchema, databaseSchemaInfo);
+
return new TypedDatabaseSchemaDefinitionNode(
untyped.name(),
- untyped.body().stream()
- .map(statement -> typeCheckDatabaseSchemaStatement(statement, context))
- .toList(),
+ typedBody,
untyped.docComment(),
untyped.source()
);
@@ -247,6 +285,21 @@ public class TypeChecker {
return metaType;
}
+ private static TypedQueryDefinitionNode defineQueryDefinition(
+ UntypedQueryDefinitionNode untyped,
+ TypeCheckerNamespaceContext context
+ ) {
+ var value = evalStatements(untyped.statements(), context);
+ var table = (Table) value;
+
+ return new TypedQueryDefinitionNode(
+ untyped.name(),
+ new RelationTable(table),
+ untyped.docComment(),
+ untyped.source()
+ );
+ }
+
private static TypedStructDefinitionNode defineStructDefinition(
UntypedStructDefinitionNode untyped,
TypeCheckerNamespaceContext context
@@ -455,18 +508,29 @@ public class TypeChecker {
}
}
+ // == Database schema statements ==
+
static TypedDatabaseSchemaStatementNode typeCheckDatabaseSchemaStatement(
UntypedDatabaseSchemaStatementNode statement,
+ DatabaseSchema databaseSchema,
+ DatabaseSchemaInfo databaseSchemaInfo,
TypeCheckerNamespaceContext context
) {
return switch (statement) {
case UntypedTableDefinitionNode untypedTableDefinition ->
- typeCheckTableDefinition(untypedTableDefinition, context);
+ typeCheckTableDefinition(
+ untypedTableDefinition,
+ databaseSchema,
+ databaseSchemaInfo,
+ context
+ );
};
}
private static TypedTableDefinitionNode typeCheckTableDefinition(
UntypedTableDefinitionNode untyped,
+ DatabaseSchema databaseSchema,
+ DatabaseSchemaInfo databaseSchemaInfo,
TypeCheckerNamespaceContext context
) {
var rowTypeTypedNode = typeCheckMetaType(untyped.rowType(), context);
@@ -479,15 +543,26 @@ public class TypeChecker {
);
}
+ // In principle, we should check that fields is non-empty. In practice,
+ // we implicitly check this by requiring a primary key.
var fields = context.fieldsOf(rowType).orElse(List.of());
+
var primaryKeyField = fields.stream()
- .filter(field -> field.name().equals(untyped.primaryKey()))
+ .filter(field -> field.name().equals(untyped.primaryKey().name()))
.findFirst();
if (primaryKeyField.isEmpty()) {
- // TODO: more precise source.
- throw new NoSuchFieldError(rowType, untyped.primaryKey(), untyped.source());
+ throw new NoSuchFieldError(
+ rowType,
+ untyped.primaryKey().name(),
+ untyped.primaryKey().source()
+ );
}
+ var table = new Table(databaseSchema, untyped.name());
+ var tableInfo = new TableInfo(table, rowType, primaryKeyField.get());
+
+ databaseSchemaInfo.tables().put(untyped.name(), tableInfo);
+
return new TypedTableDefinitionNode(
untyped.name(),
rowType,
@@ -497,6 +572,8 @@ public class TypeChecker {
);
}
+ // == Type-level expressions ==
+
static TypedTypeLevelExpressionNode<? extends TypeLevelValue> typeCheckTypeLevelExpression(
UntypedTypeLevelExpressionNode untyped,
TypeCheckerNamespaceContext context
@@ -582,7 +659,7 @@ public class TypeChecker {
// TODO: handle not a type-level value
if (!(type instanceof TypeLevelValueType(TypeLevelValue value))) {
- throw new UnexpectedTypeError(new TypeSet.MetaType(), type, source);
+ throw new UnexpectedTypeError(new TypeSet.TypeLevelValue(), type, source);
}
return value;
@@ -602,4 +679,91 @@ public class TypeChecker {
);
}
}
+
+ // == Statements ==
+
+ private static TypeLevelValue evalStatements(
+ List<UntypedStatementNode> statements,
+ TypeCheckerNamespaceContext context
+ ) {
+ for (var statement : statements) {
+ switch (statement) {
+ case UntypedReturnNode untypedReturn -> {
+ // TODO: test multiple returns.
+ return evalExpression(untypedReturn.expression(), context);
+ }
+ }
+ }
+
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ // == Expressions ==
+
+ static TypeLevelValue evalExpression(
+ UntypedExpressionNode expression,
+ TypeCheckerNamespaceContext context
+ ) {
+ switch (expression) {
+ case UntypedBinaryOperationNode _ -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+ case UntypedCallNode _ -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+ case UntypedFunctionExpressionNode _ -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+ case UntypedMemberAccessNode memberAccess -> {
+ return evalMemberAccess(memberAccess, context);
+ }
+ case UntypedNumberLiteralNode numberLiteral -> {
+ return evalNumberLiteral(numberLiteral);
+ }
+ case UntypedReferenceNode reference -> {
+ return lookupTypeLevelValue(reference.name(), reference.source(), context);
+ }
+ }
+ }
+
+ private static TypeLevelValue evalMemberAccess(
+ UntypedMemberAccessNode memberAccess,
+ TypeCheckerNamespaceContext context
+ ) {
+ var receiver = evalExpression(memberAccess.receiver(), context);
+ switch (receiver) {
+ case DatabaseSchema databaseSchema -> {
+ var schemaInfo = context.databaseSchemaInfo(databaseSchema);
+ var tableInfo = schemaInfo.tables().get(memberAccess.memberName());
+ if (tableInfo != null) {
+ return tableInfo.table();
+ }
+ }
+
+ case Table table -> {
+ switch (memberAccess.memberName()) {
+ case "where":
+ return new RelationMethod(new RelationTable(table), "where");
+
+ default:
+ break;
+ }
+ }
+
+ case ConstantNumber _, Type _, TypeConstructor<?> _, RelationMethod _ -> {
+ }
+ }
+
+ throw new NoSuchMemberError(
+ new TypeLevelValueType(receiver),
+ memberAccess.memberName(),
+ memberAccess.source()
+ );
+ }
+
+ private static TypeLevelValue evalNumberLiteral(
+ UntypedNumberLiteralNode numberLiteral
+ ) {
+ return new ConstantNumber(numberLiteral.value());
+ }
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
index ce7153f..4a82c05 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
@@ -57,6 +57,17 @@ public class TypeCheckerNamespaceContext {
return Optional.ofNullable(this.variables.get(name));
}
+ public void defineDatabaseSchema(
+ DatabaseSchema databaseSchema,
+ DatabaseSchemaInfo databaseSchemaInfo
+ ) {
+ this.typesInfo.defineDatabaseSchema(databaseSchema, databaseSchemaInfo);
+ }
+
+ public DatabaseSchemaInfo databaseSchemaInfo(DatabaseSchema databaseSchema) {
+ return this.typesInfo.databaseSchemaInfo(databaseSchema);
+ }
+
public void defineEnumType(EnumType enumType, List<EnumVariant> enumVariants) {
this.typesInfo.defineEnumType(enumType, enumVariants);
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java
index d13d2c6..e05ddc3 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java
@@ -8,6 +8,8 @@ import java.util.Optional;
public interface TypesInfo {
TypesInfo EMPTY = TypesInfoInMemory.empty();
+ DatabaseSchemaInfo databaseSchemaInfo(DatabaseSchema databaseSchema);
+
boolean isDefined(SimpleStructType type);
Optional<List<Field>> fieldsOf(SimpleStructType structType);
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfoInMemory.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfoInMemory.java
index 67d5c3b..011b7e5 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfoInMemory.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfoInMemory.java
@@ -11,10 +11,13 @@ public class TypesInfoInMemory implements TypesInfo {
new HashMap<>(),
new HashMap<>(),
new HashMap<>(),
+ new HashMap<>(),
new HashMap<>()
);
}
+ private final Map<DatabaseSchema, DatabaseSchemaInfo> databaseSchemaInfo;
+
private final Map<EnumType, List<EnumVariant>> enumVariants;
private final Map<Type, Optional<List<Field>>> structFields;
@@ -23,17 +26,37 @@ public class TypesInfoInMemory implements TypesInfo {
private final Map<SimpleStructType, List<SumType>> variantToSums;
private TypesInfoInMemory(
+ Map<DatabaseSchema, DatabaseSchemaInfo> databaseSchemaInfo,
Map<EnumType, List<EnumVariant>> enumVariants,
Map<Type, Optional<List<Field>>> structFields,
Map<SumType, SumTypeInfo> sumTypeInfos,
Map<SimpleStructType, List<SumType>> variantToSums
) {
+ this.databaseSchemaInfo = databaseSchemaInfo;
this.enumVariants = enumVariants;
this.structFields = structFields;
this.sumTypeInfos = sumTypeInfos;
this.variantToSums = variantToSums;
}
+ public void defineDatabaseSchema(
+ DatabaseSchema databaseSchema,
+ DatabaseSchemaInfo databaseSchemaInfo
+ ) {
+ this.databaseSchemaInfo.put(databaseSchema, databaseSchemaInfo);
+ }
+
+ @Override
+ public DatabaseSchemaInfo databaseSchemaInfo(DatabaseSchema databaseSchema) {
+ var info = this.databaseSchemaInfo.get(databaseSchema);
+ if (info == null) {
+ // TODO: better error
+ throw new UnsupportedOperationException("TODO");
+ } else {
+ return info;
+ }
+ }
+
public void defineEnumType(EnumType enumType, List<EnumVariant> enumVariants) {
this.enumVariants.put(enumType, enumVariants);
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchMemberError.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchMemberError.java
new file mode 100644
index 0000000..b2b1d55
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchMemberError.java
@@ -0,0 +1,24 @@
+package org.zwobble.hobgoblin.compiler.typechecker.errors;
+
+import org.zwobble.hobgoblin.compiler.errors.SourceError;
+import org.zwobble.hobgoblin.compiler.sources.Source;
+import org.zwobble.hobgoblin.compiler.types.Type;
+
+public class NoSuchMemberError extends SourceError {
+ private final Type type;
+ private final String memberName;
+
+ public NoSuchMemberError(Type type, String memberName, Source source) {
+ super(type.describe() + " does not have a member named " + memberName, source);
+ this.type = type;
+ this.memberName = memberName;
+ }
+
+ public Type type() {
+ return type;
+ }
+
+ public String memberName() {
+ return memberName;
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstantNumber.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstantNumber.java
new file mode 100644
index 0000000..bd16d81
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstantNumber.java
@@ -0,0 +1,12 @@
+package org.zwobble.hobgoblin.compiler.types;
+
+import java.math.BigDecimal;
+
+public record ConstantNumber(
+ BigDecimal value
+) implements TypeLevelValue {
+ @Override
+ public String describe() {
+ return value.toString();
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/DatabaseSchema.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/DatabaseSchema.java
new file mode 100644
index 0000000..e57d587
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/DatabaseSchema.java
@@ -0,0 +1,8 @@
+package org.zwobble.hobgoblin.compiler.types;
+
+public record DatabaseSchema(NamespaceName namespaceName, String name) implements TypeLevelValue {
+ @Override
+ public String describe() {
+ return namespaceName.toString() + "." + name;
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/DatabaseSchemaInfo.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/DatabaseSchemaInfo.java
new file mode 100644
index 0000000..5ba5712
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/DatabaseSchemaInfo.java
@@ -0,0 +1,6 @@
+package org.zwobble.hobgoblin.compiler.types;
+
+import java.util.SequencedMap;
+
+public record DatabaseSchemaInfo(SequencedMap<String, TableInfo> tables) {
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java
index 96efbd2..186557e 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java
@@ -40,4 +40,12 @@ public class HobgoblinNativeTypes {
public static Field arbitraryField() {
return new Field("", arbitraryType(), NullSource.INSTANCE);
}
+
+ public static DatabaseSchema arbitraryDatabaseSchema() {
+ return new DatabaseSchema(arbitraryNamespaceName(), "");
+ }
+
+ public static Table arbitraryTable() {
+ return new Table(arbitraryDatabaseSchema(), "");
+ }
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/RelationMethod.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/RelationMethod.java
new file mode 100644
index 0000000..87ba7fa
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/RelationMethod.java
@@ -0,0 +1,10 @@
+package org.zwobble.hobgoblin.compiler.types;
+
+import org.zwobble.hobgoblin.compiler.ast.typed.Relation;
+
+public record RelationMethod(Relation relation, String name) implements TypeLevelValue {
+ @Override
+ public String describe() {
+ return name;
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/Table.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/Table.java
new file mode 100644
index 0000000..a33e226
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/Table.java
@@ -0,0 +1,8 @@
+package org.zwobble.hobgoblin.compiler.types;
+
+public record Table(DatabaseSchema databaseSchema, String name) implements TypeLevelValue {
+ @Override
+ public String describe() {
+ return databaseSchema.describe() + "." + name;
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TableInfo.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TableInfo.java
new file mode 100644
index 0000000..b991b54
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TableInfo.java
@@ -0,0 +1,8 @@
+package org.zwobble.hobgoblin.compiler.types;
+
+public record TableInfo(
+ Table table,
+ SimpleStructType rowType,
+ Field primaryKey
+) {
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValue.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValue.java
index cf62eb1..e0f7042 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValue.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValue.java
@@ -1,5 +1,5 @@
package org.zwobble.hobgoblin.compiler.types;
-public sealed interface TypeLevelValue permits Type, TypeConstructor {
+public sealed interface TypeLevelValue permits ConstantNumber, DatabaseSchema, RelationMethod, Table, Type, TypeConstructor {
String describe();
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java
index c3896d9..3a64b85 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java
@@ -23,4 +23,11 @@ public sealed interface TypeSet {
return "type constructor";
}
}
+
+ record TypeLevelValue() implements TypeSet {
+ @Override
+ public String describe() {
+ return "type-level value";
+ }
+ }
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/Types.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/Types.java
index cfbb5ba..756f3bf 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/Types.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/Types.java
@@ -26,4 +26,16 @@ public class Types {
public static Type metaType(TypeConstructor<?> constructor) {
return new TypeLevelValueType(constructor);
}
+
+ public static Type databaseSchema(DatabaseSchema databaseSchema) {
+ return new TypeLevelValueType(databaseSchema);
+ }
+
+ public static Type relationMethod(RelationMethod method) {
+ return new TypeLevelValueType(method);
+ }
+
+ public static Type table(Table table) {
+ return new TypeLevelValueType(table);
+ }
}