aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-09 18:15:27 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-09 18:15:27 +0100
commit92bcb4b11954348daa759eb967d2b15c12744dc5 (patch)
tree99c02a547451d45bc46a9494e0de00913ecafc18 /src/main/java
parentf8174b842a7b2fdab34146c543dade8f92e45b1d (diff)
Type check references
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedExpressionNode.java2
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedReferenceNode.java11
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java31
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java24
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/UnknownVariableError.java17
-rw-r--r--src/main/java/org/shedlang/compiler/util/P.java20
6 files changed, 101 insertions, 4 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedExpressionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedExpressionNode.java
index f7ce02dc..73ad8991 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedExpressionNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedExpressionNode.java
@@ -3,7 +3,7 @@ package org.shedlang.compiler.ast.typed;
import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.types.Type;
-public sealed interface TypedExpressionNode permits TypedStringLiteralNode {
+public sealed interface TypedExpressionNode permits TypedReferenceNode, TypedStringLiteralNode {
Source source();
Type type();
}
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedReferenceNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedReferenceNode.java
new file mode 100644
index 00000000..767cf814
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedReferenceNode.java
@@ -0,0 +1,11 @@
+package org.shedlang.compiler.ast.typed;
+
+import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.types.Type;
+
+public record TypedReferenceNode(
+ String name,
+ Type type,
+ Source source
+) implements TypedExpressionNode {
+}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index d37eb347..a030f117 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -1,6 +1,7 @@
package org.shedlang.compiler.typechecker;
import org.shedlang.compiler.ast.typed.TypedExpressionNode;
+import org.shedlang.compiler.ast.typed.TypedReferenceNode;
import org.shedlang.compiler.ast.typed.TypedStringLiteralNode;
import org.shedlang.compiler.ast.untyped.UntypedCallNode;
import org.shedlang.compiler.ast.untyped.UntypedExpressionNode;
@@ -17,13 +18,39 @@ public class TypeChecker {
) {
return switch (untyped) {
case UntypedStringLiteralNode untypedStringLiteral ->
- new TypedStringLiteralNode(untypedStringLiteral.value(), untypedStringLiteral.source());
+ typeCheckStringLiteral(untypedStringLiteral);
case UntypedCallNode untypedCall ->
throw new UnsupportedOperationException("TODO");
case UntypedReferenceNode untypedReference ->
- throw new UnsupportedOperationException("TODO");
+ typeCheckReference(untypedReference, context);
};
}
+
+ private static TypedReferenceNode typeCheckReference(
+ UntypedReferenceNode untyped,
+ TypeCheckerContext context
+ ) {
+ var type = context.environment(untyped.name());
+
+ if (type.isEmpty()) {
+ throw new UnknownVariableError(untyped.name(), untyped.source());
+ }
+
+ return new TypedReferenceNode(
+ untyped.name(),
+ type.get(),
+ untyped.source()
+ );
+ }
+
+ private static TypedStringLiteralNode typeCheckStringLiteral(
+ UntypedStringLiteralNode untypedStringLiteral
+ ) {
+ return new TypedStringLiteralNode(
+ untypedStringLiteral.value(),
+ untypedStringLiteral.source()
+ );
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
index 261e3e95..c130b0d3 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
@@ -1,5 +1,27 @@
package org.shedlang.compiler.typechecker;
+import org.pcollections.Empty;
+import org.pcollections.PMap;
+import org.shedlang.compiler.types.Type;
+
+import java.util.Optional;
+
public class TypeCheckerContext {
- public static final TypeCheckerContext EMPTY = new TypeCheckerContext();
+ public static final TypeCheckerContext EMPTY = new TypeCheckerContext(
+ Empty.map()
+ );
+
+ private final PMap<String, Type> environment;
+
+ public TypeCheckerContext(PMap<String, Type> environment) {
+ this.environment = environment;
+ }
+
+ public TypeCheckerContext enter(PMap<String, Type> environment) {
+ return new TypeCheckerContext(this.environment.plusAll(environment));
+ }
+
+ public Optional<Type> environment(String name) {
+ return Optional.ofNullable(environment.get(name));
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/UnknownVariableError.java b/src/main/java/org/shedlang/compiler/typechecker/UnknownVariableError.java
new file mode 100644
index 00000000..91ab3fae
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/UnknownVariableError.java
@@ -0,0 +1,17 @@
+package org.shedlang.compiler.typechecker;
+
+import org.shedlang.compiler.errors.SourceError;
+import org.shedlang.compiler.sources.Source;
+
+public class UnknownVariableError extends SourceError {
+ private final String variableName;
+
+ public UnknownVariableError(String variableName, Source source) {
+ super("Unknown variable: " + variableName, source);
+ this.variableName = variableName;
+ }
+
+ public String variableName() {
+ return variableName;
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/util/P.java b/src/main/java/org/shedlang/compiler/util/P.java
new file mode 100644
index 00000000..7ce8232c
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/util/P.java
@@ -0,0 +1,20 @@
+package org.shedlang.compiler.util;
+
+import org.pcollections.HashTreePMap;
+import org.pcollections.PMap;
+
+import java.util.Map;
+
+public class P {
+ private P() {
+ }
+
+ @SafeVarargs
+ public static <K, V> PMap<K, V> map(Map.Entry<K, V>... entries) {
+ var map = HashTreePMap.<K, V>empty();
+ for (var entry : entries) {
+ map = map.plus(entry.getKey(), entry.getValue());
+ }
+ return map;
+ }
+}