aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-10 11:17:03 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-10 11:17:14 +0100
commit646c5b9673ffbbc691db246ca8a253cb3e6ea8a1 (patch)
treec8e9cab7e3c9893994f8c7bce845bf14f66b6e37 /src/main/java
parent482c93fe786d63dd8263bde262acc76467021169 (diff)
Check positional arg type matches param type
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedExpressionNode.java1
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java37
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/UnexpectedTypeError.java25
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSet.java5
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetFunction.java13
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetType.java10
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSets.java12
7 files changed, 98 insertions, 5 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 0c61b3b2..4bb9cb8e 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedExpressionNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedExpressionNode.java
@@ -3,6 +3,7 @@ package org.shedlang.compiler.ast.typed;
import org.shedlang.compiler.types.Type;
public sealed interface TypedExpressionNode
+ extends TypedNode
permits TypedBoolLiteralNode, TypedCallNode, TypedIntLiteralNode, TypedReferenceNode, TypedStringLiteralNode {
Type type();
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index d4704a4e..ebfdc0d5 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -2,18 +2,38 @@ package org.shedlang.compiler.typechecker;
import org.shedlang.compiler.ast.typed.*;
import org.shedlang.compiler.ast.untyped.*;
+import org.shedlang.compiler.typechecker.typesets.TypeSets;
import org.shedlang.compiler.types.FunctionType;
+import org.shedlang.compiler.types.Type;
public class TypeChecker {
private TypeChecker() {
}
- private static TypedArgsNode typeCheckArgs(UntypedArgsNode args, TypeCheckerContext context) {
- var typedPositional = args.positional().stream()
+ private static void checkIsSubType(TypedExpressionNode expression, Type expectedType, TypeCheckerContext context) {
+ if (!isSubType(expression.type(), expectedType, context)) {
+ throw new UnexpectedTypeError(
+ TypeSets.type(expectedType),
+ expression.type(),
+ expression.source()
+ );
+ }
+ }
+
+ private static boolean isSubType(Type subType, Type superType, TypeCheckerContext context) {
+ return subType.equals(superType);
+ }
+
+ private static TypedArgsNode typeCheckArgs(
+ UntypedArgsNode args,
+ TypeCheckerContext context,
+ FunctionType receiverType
+ ) {
+ var typedPositionalArgs = args.positional().stream()
.map(arg -> typeCheckExpression(arg, context))
.toList();
- var typedNamed = args.named().stream()
+ var typedNamedArgs = args.named().stream()
.map(arg -> new TypedNamedArgNode(
arg.name(),
typeCheckExpression(arg.expression(), context),
@@ -21,7 +41,14 @@ public class TypeChecker {
))
.toList();
- return new TypedArgsNode(typedPositional, typedNamed, args.source());
+ for (var i = 0; i < typedPositionalArgs.size(); i++) {
+ var typedArg = typedPositionalArgs.get(i);
+ var paramType = receiverType.positionalParams().get(i);
+
+ checkIsSubType(typedArg, paramType, context);
+ }
+
+ return new TypedArgsNode(typedPositionalArgs, typedNamedArgs, args.source());
}
public static TypedExpressionNode typeCheckBoolLiteral(
@@ -42,7 +69,7 @@ public class TypeChecker {
return new TypedCallNode(
typedReceiver,
- typeCheckArgs(untyped.args(), context),
+ typeCheckArgs(untyped.args(), context, receiverType),
false,
receiverType.returnType(),
untyped.source()
diff --git a/src/main/java/org/shedlang/compiler/typechecker/UnexpectedTypeError.java b/src/main/java/org/shedlang/compiler/typechecker/UnexpectedTypeError.java
new file mode 100644
index 00000000..51cc6652
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/UnexpectedTypeError.java
@@ -0,0 +1,25 @@
+package org.shedlang.compiler.typechecker;
+
+import org.shedlang.compiler.errors.SourceError;
+import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.typechecker.typesets.TypeSet;
+import org.shedlang.compiler.types.Type;
+
+public class UnexpectedTypeError extends SourceError {
+ private final TypeSet expected;
+ private final Type actual;
+
+ public UnexpectedTypeError(TypeSet expected, Type actual, Source source) {
+ super("Expected " + expected.describe() + " but was " + actual.describe(), source);
+ this.expected = expected;
+ this.actual = actual;
+ }
+
+ public TypeSet expected() {
+ return expected;
+ }
+
+ public Type actual() {
+ return actual;
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSet.java b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSet.java
new file mode 100644
index 00000000..79cb0433
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSet.java
@@ -0,0 +1,5 @@
+package org.shedlang.compiler.typechecker.typesets;
+
+public sealed interface TypeSet permits TypeSetFunction, TypeSetType {
+ String describe();
+}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetFunction.java b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetFunction.java
new file mode 100644
index 00000000..127c0e71
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetFunction.java
@@ -0,0 +1,13 @@
+package org.shedlang.compiler.typechecker.typesets;
+
+public final class TypeSetFunction implements TypeSet {
+ static final TypeSetFunction INSTANCE = new TypeSetFunction();
+
+ private TypeSetFunction() {
+ }
+
+ @Override
+ public String describe() {
+ return "function";
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetType.java b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetType.java
new file mode 100644
index 00000000..f067351a
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetType.java
@@ -0,0 +1,10 @@
+package org.shedlang.compiler.typechecker.typesets;
+
+import org.shedlang.compiler.types.Type;
+
+public record TypeSetType(Type type) implements TypeSet {
+ @Override
+ public String describe() {
+ return type.describe();
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSets.java b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSets.java
new file mode 100644
index 00000000..4f5f1848
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSets.java
@@ -0,0 +1,12 @@
+package org.shedlang.compiler.typechecker.typesets;
+
+import org.shedlang.compiler.types.Type;
+
+public class TypeSets {
+ private TypeSets() {
+ }
+
+ public static TypeSet type(Type type) {
+ return new TypeSetType(type);
+ }
+}