aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-02 12:19:46 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-02 12:19:46 +0100
commit71a8ca11b03331a92bb271cbd1fbcb877e587300 (patch)
tree3a73642a3285bca6b0049656ba8d421f548c4bfb /src/main/java
parent1f86ef817b64e5e78ed92dd767fa38306c7662b5 (diff)
Check call to function with effect is marked with effects
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ShedCompiler.java2
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java1
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java4
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/errors/CallIsMissingEffectsError.java18
-rw-r--r--src/main/java/org/shedlang/compiler/types/Effect.java2
-rw-r--r--src/main/java/org/shedlang/compiler/types/Effects.java2
-rw-r--r--src/main/java/org/shedlang/compiler/types/FunctionType.java16
-rw-r--r--src/main/java/org/shedlang/compiler/types/NoneEffect.java10
8 files changed, 49 insertions, 6 deletions
diff --git a/src/main/java/org/shedlang/compiler/ShedCompiler.java b/src/main/java/org/shedlang/compiler/ShedCompiler.java
index bf26436e..d727aea5 100644
--- a/src/main/java/org/shedlang/compiler/ShedCompiler.java
+++ b/src/main/java/org/shedlang/compiler/ShedCompiler.java
@@ -42,6 +42,7 @@ public class ShedCompiler {
Map.entry("print", new FunctionType(
List.of(Types.STRING),
List.of(),
+ Effects.IO,
Types.UNIT
))
))
@@ -52,6 +53,7 @@ public class ShedCompiler {
Map.entry("print", new FunctionType(
List.of(Types.STRING),
List.of(),
+ Effects.IO,
Types.UNIT
))
));
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java
index 417b9ad6..42783224 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java
@@ -42,6 +42,7 @@ public record TypedFunctionDefinitionNode(
params.named().stream()
.map(param -> new NamedParam(param.name(), param.type().value()))
.toList(),
+ effect.map(e -> e.value()).orElse(Effects.NONE),
returnType.value()
),
source
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index 770b7063..4d2b7326 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -142,6 +142,10 @@ public class TypeChecker {
var typedArgs = argsResult.value();
context = argsResult.context();
+ if (!receiverType.effect().equals(Effects.NONE) && !untyped.hasEffects()) {
+ throw new CallIsMissingEffectsError(receiverType.effect(), untyped.source());
+ }
+
return context.toResult(new TypedCallNode(
typedReceiver,
typedArgs,
diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/CallIsMissingEffectsError.java b/src/main/java/org/shedlang/compiler/typechecker/errors/CallIsMissingEffectsError.java
new file mode 100644
index 00000000..083d9a03
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/errors/CallIsMissingEffectsError.java
@@ -0,0 +1,18 @@
+package org.shedlang.compiler.typechecker.errors;
+
+import org.shedlang.compiler.errors.SourceError;
+import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.types.Effect;
+
+public class CallIsMissingEffectsError extends SourceError {
+ private final Effect effect;
+
+ public CallIsMissingEffectsError(Effect effect, Source source) {
+ super("Function has effect, but call is missing effect: " + effect.describe(), source);
+ this.effect = effect;
+ }
+
+ public Effect effect() {
+ return effect;
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/types/Effect.java b/src/main/java/org/shedlang/compiler/types/Effect.java
index 257a3847..7e8bc203 100644
--- a/src/main/java/org/shedlang/compiler/types/Effect.java
+++ b/src/main/java/org/shedlang/compiler/types/Effect.java
@@ -1,4 +1,4 @@
package org.shedlang.compiler.types;
-public sealed interface Effect extends TypeLevelValue permits IoEffect {
+public sealed interface Effect extends TypeLevelValue permits IoEffect, NoneEffect {
}
diff --git a/src/main/java/org/shedlang/compiler/types/Effects.java b/src/main/java/org/shedlang/compiler/types/Effects.java
index 820d31c5..c894a58b 100644
--- a/src/main/java/org/shedlang/compiler/types/Effects.java
+++ b/src/main/java/org/shedlang/compiler/types/Effects.java
@@ -4,5 +4,7 @@ public class Effects {
private Effects() {
}
+ public static final Effect NONE = NoneEffect.INSTANCE;
+
public static final Effect IO = IoEffect.INSTANCE;
}
diff --git a/src/main/java/org/shedlang/compiler/types/FunctionType.java b/src/main/java/org/shedlang/compiler/types/FunctionType.java
index 22d3487b..e40439f7 100644
--- a/src/main/java/org/shedlang/compiler/types/FunctionType.java
+++ b/src/main/java/org/shedlang/compiler/types/FunctionType.java
@@ -8,10 +8,11 @@ import java.util.List;
public record FunctionType(
List<Type> positionalParams,
List<NamedParam> namedParams,
+ Effect effect,
Type returnType
) implements Type {
public static Builder builder() {
- return new Builder(Empty.vector(), Empty.vector(), Types.UNIT);
+ return new Builder(Empty.vector(), Empty.vector(), Effects.NONE, Types.UNIT);
}
@Override
@@ -23,23 +24,28 @@ public record FunctionType(
public record Builder(
PVector<Type> positionalParams,
PVector<NamedParam> namedParams,
+ Effect effect,
Type returnType
) {
public FunctionType build() {
- return new FunctionType(positionalParams, namedParams, returnType);
+ return new FunctionType(positionalParams, namedParams, effect, returnType);
}
public Builder addNamedParam(String name, Type type) {
var namedParam = new NamedParam(name, type);
- return new Builder(positionalParams, namedParams.plus(namedParam), returnType);
+ return new Builder(positionalParams, namedParams.plus(namedParam), effect, returnType);
}
public Builder addPositionalParam(Type type) {
- return new Builder(positionalParams.plus(type), namedParams, returnType);
+ return new Builder(positionalParams.plus(type), namedParams, effect, returnType);
+ }
+
+ public Builder withEffect(Effect effect) {
+ return new Builder(positionalParams, namedParams, effect, returnType);
}
public Builder withReturnType(Type returnType) {
- return new Builder(positionalParams, namedParams, returnType);
+ return new Builder(positionalParams, namedParams, effect, returnType);
}
}
}
diff --git a/src/main/java/org/shedlang/compiler/types/NoneEffect.java b/src/main/java/org/shedlang/compiler/types/NoneEffect.java
new file mode 100644
index 00000000..e6fe5f95
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/types/NoneEffect.java
@@ -0,0 +1,10 @@
+package org.shedlang.compiler.types;
+
+public record NoneEffect() implements Effect {
+ static final NoneEffect INSTANCE = new NoneEffect();
+
+ @Override
+ public String describe() {
+ return "None";
+ }
+}