aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-11-04 15:12:52 +0000
committerMichael Williamson <mike@zwobble.org>2023-11-04 15:12:52 +0000
commit9993f60f036824c6c5c437591148b4cd8ef2dc50 (patch)
treecd47fc426ea6e5b27b2bde81d3be018b3c1d640f /src/main/java
parent92e60c08a8b3166fe0d3137a7b3ae20e6132b74f (diff)
Create effect type when type checking effect definition node
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedEffectDefinitionNode.java10
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java2
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedEffectDefinitionNode.java33
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/StackCompiler.java6
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java31
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineEffectOutsideOfNamespaceError.java10
-rw-r--r--src/main/java/org/shedlang/compiler/types/Effects.java7
7 files changed, 97 insertions, 2 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedEffectDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedEffectDefinitionNode.java
new file mode 100644
index 00000000..1e858885
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedEffectDefinitionNode.java
@@ -0,0 +1,10 @@
+package org.shedlang.compiler.ast.typed;
+
+import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.types.UserDefinedEffect;
+
+public record TypedEffectDefinitionNode(
+ UserDefinedEffect effect,
+ Source source
+) implements TypedNamespaceStatementNode {
+}
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java
index 654e073d..79c69548 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java
@@ -1,4 +1,4 @@
package org.shedlang.compiler.ast.typed;
-public sealed interface TypedNamespaceStatementNode extends TypedNode permits TypedAssignNode, TypedFunctionDefinitionNode, TypedStructDefinitionNode, TypedSumTypeDefinitionNode {
+public sealed interface TypedNamespaceStatementNode extends TypedNode permits TypedAssignNode, TypedEffectDefinitionNode, TypedFunctionDefinitionNode, TypedStructDefinitionNode, TypedSumTypeDefinitionNode {
}
diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedEffectDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedEffectDefinitionNode.java
index 48e6fdf0..5731aefe 100644
--- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedEffectDefinitionNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedEffectDefinitionNode.java
@@ -1,7 +1,10 @@
package org.shedlang.compiler.ast.untyped;
+import org.pcollections.PVector;
import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.sources.Sources;
import org.shedlang.compiler.types.Visibility;
+import org.shedlang.compiler.util.P;
import java.util.List;
@@ -11,4 +14,34 @@ public record UntypedEffectDefinitionNode(
List<UntypedEffectDefinitionFunctionNode> functions,
Source source
) implements UntypedNamespaceStatementNode, UntypedVariableDeclarationNode {
+ public static Builder builder() {
+ return new Builder(
+ "E",
+ Visibility.PRIVATE,
+ P.vector()
+ );
+ }
+
+ public record Builder(
+ String name,
+ Visibility visibility,
+ PVector<UntypedEffectDefinitionFunctionNode> functions
+ ) {
+ public UntypedEffectDefinitionNode build() {
+ return new UntypedEffectDefinitionNode(
+ name,
+ visibility,
+ functions,
+ Sources.NULL
+ );
+ }
+
+ public Builder withName(String name) {
+ return new Builder(
+ name,
+ this.visibility,
+ this.functions
+ );
+ }
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java b/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java
index ecb32acd..7080cde2 100644
--- a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java
+++ b/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java
@@ -407,6 +407,9 @@ public class StackCompiler {
case TypedAssignNode assign ->
1;
+ case TypedEffectDefinitionNode effectDefinition ->
+ 0;
+
case TypedFunctionDefinitionNode functionDefinition ->
1;
@@ -440,6 +443,9 @@ public class StackCompiler {
case TypedAssignNode assign ->
compileAssign(assign, context);
+ case TypedEffectDefinitionNode effectDefinition ->
+ throw new UnsupportedOperationException("TODO");
+
case TypedFunctionDefinitionNode functionDefinition ->
compileFunctionDefinition(functionDefinition, context);
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index b115f529..5c104fe1 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -388,6 +388,35 @@ public class TypeChecker {
return typeCheckTypeLevelExpression(TypeSets.EFFECT, untyped, context);
}
+ private static TypeCheckSteps<TypedEffectDefinitionNode> typeCheckStepsEffectDefinition(
+ UntypedEffectDefinitionNode untyped
+ ) {
+ return new TypeCheckSteps<TypedEffectDefinitionNode>() {
+ @Override
+ public TypeCheckerContext declareTypes(TypeCheckerContext context) {
+ var namespaceName = context.namespaceName()
+ .orElseThrow(() -> new CannotDefineEffectOutsideOfNamespaceError(untyped.source()));
+
+ var effect = new UserDefinedEffect(namespaceName, untyped.name());
+
+ return context
+ .addLexicalState(untyped.name(), effect)
+ .declareVariableType(
+ untyped.name(),
+ Types.effectType(effect),
+ untyped.source()
+ );
+ }
+
+ @Override
+ public TypeCheckerResult<TypedEffectDefinitionNode> finish(TypeCheckerContext context) {
+ var effect = context.getLexicalState(UserDefinedEffect.class, untyped.name());
+
+ return context.toResult(new TypedEffectDefinitionNode(effect, untyped.source()));
+ }
+ };
+ }
+
public static TypeCheckerResult<? extends TypedExpressionNode> typeCheckExpression(
UntypedExpressionNode untyped,
Optional<Type> hint,
@@ -1148,7 +1177,7 @@ public class TypeChecker {
typeCheckStepsAssign(assign);
case UntypedEffectDefinitionNode effectDefinition ->
- throw new UnsupportedOperationException("TODO");
+ typeCheckStepsEffectDefinition(effectDefinition);
case UntypedFunctionDefinitionNode functionDefinition ->
typeCheckStepsFunctionDefinition(functionDefinition);
diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineEffectOutsideOfNamespaceError.java b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineEffectOutsideOfNamespaceError.java
new file mode 100644
index 00000000..1777afbe
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineEffectOutsideOfNamespaceError.java
@@ -0,0 +1,10 @@
+package org.shedlang.compiler.typechecker.errors;
+
+import org.shedlang.compiler.errors.InternalCompilerError;
+import org.shedlang.compiler.sources.Source;
+
+public class CannotDefineEffectOutsideOfNamespaceError extends InternalCompilerError {
+ public CannotDefineEffectOutsideOfNamespaceError(Source source) {
+ super("Cannot define effect outside of namespace", source);
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/types/Effects.java b/src/main/java/org/shedlang/compiler/types/Effects.java
index c894a58b..206574d7 100644
--- a/src/main/java/org/shedlang/compiler/types/Effects.java
+++ b/src/main/java/org/shedlang/compiler/types/Effects.java
@@ -7,4 +7,11 @@ public class Effects {
public static final Effect NONE = NoneEffect.INSTANCE;
public static final Effect IO = IoEffect.INSTANCE;
+
+ public static UserDefinedEffect userDefined(
+ NamespaceName namespaceName,
+ String name
+ ) {
+ return new UserDefinedEffect(namespaceName, name);
+ }
}