aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-12-13 23:34:49 +0000
committerMichael Williamson <mike@zwobble.org>2023-12-13 23:34:49 +0000
commit7c6fc48c7ab8a23f8568a2f0c57c66e77a5aa69c (patch)
treed202daa047112c06868bf15b7b0d8a511db7b039 /src/main/java
parent86b4a6cdb0e2c311bdcbdcb109e77d04b094a86f (diff)
Use Shid bound variables to generate Patio variables
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/BoundVariable.java20
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java4
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java4
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedTryHandlerMethodNode.java4
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java209
-rw-r--r--src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java46
-rw-r--r--src/main/java/org/shedlang/compiler/shid/ShidSerializer.java22
-rw-r--r--src/main/java/org/shedlang/compiler/shid/instructions/ShidBlock.java2
-rw-r--r--src/main/java/org/shedlang/compiler/shid/instructions/ShidVariable.java13
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/DeclaredVariable.java9
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java5
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java6
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/VariableType.java12
13 files changed, 157 insertions, 199 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/BoundVariable.java b/src/main/java/org/shedlang/compiler/ast/typed/BoundVariable.java
index f2c76c06..20ed0785 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/BoundVariable.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/BoundVariable.java
@@ -1,11 +1,21 @@
package org.shedlang.compiler.ast.typed;
-public record BoundVariable(String name, boolean isMutable) {
- public static BoundVariable immutable(String name) {
- return new BoundVariable(name, false);
+public record BoundVariable(String name, Variant variant) {
+ public enum Variant {
+ PARAM,
+ VAL,
+ VAR
}
- public static BoundVariable mutable(String name) {
- return new BoundVariable(name, true);
+ public static BoundVariable param(String name) {
+ return new BoundVariable(name, Variant.PARAM);
+ }
+
+ public static BoundVariable val(String name) {
+ return new BoundVariable(name, Variant.VAL);
+ }
+
+ public static BoundVariable var(String name) {
+ return new BoundVariable(name, Variant.VAR);
}
}
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 cae0c93c..5e19816c 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNode.java
@@ -69,7 +69,7 @@ public record TypedFunctionDefinitionNode(
this.boundVariables,
this.body,
this.type
- ).addBoundVariable(BoundVariable.immutable(name));
+ ).addBoundVariable(BoundVariable.param(name));
}
public TypedFunctionDefinitionNode.Builder addNamedParam(String name, TypedTypeLevelExpressionNode<Type> type) {
@@ -80,7 +80,7 @@ public record TypedFunctionDefinitionNode(
this.boundVariables,
this.body,
this.type
- ).addBoundVariable(BoundVariable.immutable(name));
+ ).addBoundVariable(BoundVariable.param(name));
}
public TypedFunctionDefinitionNode.Builder withEffect(TypedTypeLevelExpressionNode<Effect> effect) {
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java
index 40168641..765f0891 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java
@@ -53,7 +53,7 @@ public record TypedFunctionExpressionNode(
this.boundVariables,
this.body,
this.type
- ).addBoundVariable(BoundVariable.immutable(name));
+ ).addBoundVariable(BoundVariable.param(name));
}
public Builder addNamedParam(String name, TypedTypeLevelExpressionNode<Type> type) {
@@ -63,7 +63,7 @@ public record TypedFunctionExpressionNode(
this.boundVariables,
this.body,
this.type
- ).addBoundVariable(BoundVariable.immutable(name));
+ ).addBoundVariable(BoundVariable.param(name));
}
public Builder withEffect(TypedTypeLevelExpressionNode<Effect> effect) {
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedTryHandlerMethodNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedTryHandlerMethodNode.java
index e1f1351d..209c0942 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedTryHandlerMethodNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedTryHandlerMethodNode.java
@@ -76,7 +76,7 @@ public record TypedTryHandlerMethodNode(
this.body,
this.type,
this.breakType
- ).addBoundVariable(BoundVariable.immutable(name));
+ ).addBoundVariable(BoundVariable.param(name));
}
public TypedTryHandlerMethodNode.Builder addNamedParam(String name, TypedTypeLevelExpressionNode<Type> type) {
@@ -88,7 +88,7 @@ public record TypedTryHandlerMethodNode(
this.body,
this.type,
this.breakType
- ).addBoundVariable(BoundVariable.immutable(name));
+ ).addBoundVariable(BoundVariable.param(name));
}
public Builder addFreeVariable(String freeVariable) {
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
index 45a96ef5..a059b723 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
@@ -1,8 +1,5 @@
package org.shedlang.compiler.patio;
-import org.pcollections.OrderedPSet;
-import org.shedlang.compiler.ast.typed.BoundVariable;
-import org.shedlang.compiler.ast.typed.FreeVariables;
import org.shedlang.compiler.patio.ast.PatioCompilationUnit;
import org.shedlang.compiler.patio.ast.PatioVisibility;
import org.shedlang.compiler.patio.ast.instructions.*;
@@ -11,16 +8,14 @@ import org.shedlang.compiler.patio.ast.operands.PatioLocalRef;
import org.shedlang.compiler.patio.ast.operands.PatioOperand;
import org.shedlang.compiler.patio.ast.types.PatioDataLayouts;
import org.shedlang.compiler.patio.ast.types.PatioTypes;
-import org.shedlang.compiler.sources.Source;
-import org.shedlang.compiler.sources.Sources;
import org.shedlang.compiler.shid.ShidNamespace;
import org.shedlang.compiler.shid.instructions.*;
+import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.sources.Sources;
import org.shedlang.compiler.types.NamespaceName;
-import org.shedlang.compiler.util.P;
import java.util.*;
import java.util.function.Function;
-import java.util.stream.Collectors;
public class PatioCodeGen {
private PatioCodeGen() {}
@@ -106,15 +101,8 @@ public class PatioCodeGen {
) {
context = PatioCodeGenNamespaces.define(
shidNamespace.namespaceName(),
- initContext -> {
- initContext = declareShidLocals(
- shidNamespace.body(),
- FreeVariables.empty(),
- initContext
- );
-
- return generateInstructions(shidNamespace.body(), initContext);
- },
+ initContext ->
+ generateBlockInstructions(shidNamespace.body(), initContext),
context
);
@@ -123,13 +111,6 @@ public class PatioCodeGen {
}
public static PatioCodeGenContext generateInstructions(
- ShidBlock block,
- PatioCodeGenContext context
- ) {
- return generateInstructions(block.instructions(), context);
- }
-
- public static PatioCodeGenContext generateInstructions(
List<ShidInstruction> shidInstructions,
PatioCodeGenContext context
) {
@@ -146,7 +127,7 @@ public class PatioCodeGen {
) {
return switch (shidInstruction) {
case ShidBlock block -> {
- context = generateInstructions(block, context);
+ context = generateBlockInstructions(block, context);
yield context;
}
@@ -250,14 +231,7 @@ public class PatioCodeGen {
Function<PatioCodeGenContext, PatioCodeGenContext> generateBody = functionContext -> {
// TODO: explicitly store locals on a function?
-
- functionContext = declareShidLocals(
- defineFunction.body(),
- defineFunction.freeVariables(),
- functionContext
- );
-
- return generateInstructions(defineFunction.body(), functionContext);
+ return generateBlockInstructions(defineFunction.body(), functionContext);
};
context = switch (defineFunction.variant()) {
@@ -509,7 +483,7 @@ public class PatioCodeGen {
case ShidLoop loop -> {
context = context.enterBlock();
- context = generateInstructions(loop.body(), context);
+ context = generateBlockInstructions(loop.body(), context);
var bodyInstructionsResult = context.exitBlock();
var bodyInstructions = bodyInstructionsResult.value();
@@ -871,6 +845,8 @@ public class PatioCodeGen {
).temporaryPush(target);
}
+
+
private static PatioCodeGenResult<PatioBlock> generateBlock(
int resultCount,
ShidBlock shidBlock,
@@ -878,7 +854,7 @@ public class PatioCodeGen {
PatioCodeGenContext context
) {
context = context.enterBlock();
- context = generateInstructions(shidBlock, context);
+ context = generateBlockInstructions(shidBlock, context);
var targets = new ArrayList<PatioOperand>();
for (var i = 0; i < resultCount; i++) {
@@ -901,6 +877,20 @@ public class PatioCodeGen {
));
}
+ // TODO: distinguish the two types of block we've apparently ended up with in Shid.
+ private static PatioCodeGenContext generateBlockInstructions(
+ ShidBlock block,
+ PatioCodeGenContext context
+ ) {
+ context = declareShidVariables(block, context);
+
+ for (var shidInstruction : block.instructions()) {
+ context = generateInstruction(shidInstruction, context);
+ }
+
+ return context;
+ }
+
private static PatioCodeGenResult<PatioLocalRef> generateCondition(
Source source,
PatioCodeGenContext context
@@ -932,136 +922,41 @@ public class PatioCodeGen {
return context.toResult(conditionBool);
}
- private static PatioCodeGenContext declareShidLocals(
+ private static PatioCodeGenContext declareShidVariables(
ShidBlock body,
- FreeVariables freeVariables,
PatioCodeGenContext context
) {
- var freeVariableNames = freeVariables.stream()
- .map(freeVariable -> freeVariable.name())
- .collect(Collectors.toSet());
-
- var boundVariables = findAssignedVariables(body, P.orderedSet());
-
- for (var boundVariable : boundVariables) {
- if (freeVariableNames.contains(boundVariable.name())) {
- // This is a terrible hack. Another reason to collect variables up-front.
- } else if (boundVariable.isMutable()) {
- var patioLocalResult = context.declareShidVal(
- boundVariable.name(),
- PatioTypes.DATA_POINTER
- );
- var patioLocal = patioLocalResult.value();
- context = patioLocalResult.context();
-
- // TODO: proper source (probably by storing variables on the function/namespace)
- context = context.addInstruction(new PatioAllocStack(
- patioLocal,
- PatioDataLayouts.fromType(PatioCodeGenTypes.VALUE_TYPE),
- Sources.NULL
- ));
-
- context = context.initShidLocal(boundVariable.name());
- } else {
- context = context.declareShidVal(
- boundVariable.name(),
- PatioCodeGenTypes.VALUE_TYPE
- ).context();
- }
- }
- return context;
- }
-
- private static OrderedPSet<BoundVariable> findAssignedVariables(
- ShidBlock body,
- OrderedPSet<BoundVariable> boundVariables
- ) {
- for (var bodyInstruction : body.instructions()) {
- switch (bodyInstruction) {
- case ShidBlock blockInstruction -> {
- boundVariables = findAssignedVariables(blockInstruction, boundVariables);
- }
- case ShidCall callInstruction -> {
- }
- case ShidDefineEffect defineEffectInstruction -> {
- }
- case ShidDefineFunction defineFunctionInstruction -> {
- }
- case ShidDefineStruct defineStructInstruction -> {
- }
- case ShidDiscard discardInstruction -> {
- }
- case ShidDuplicate duplicateInstruction -> {
- }
- case ShedEffectHandlerBreak breakInstruction -> {
- }
- case ShidFieldLoad fieldLoadInstruction -> {
- }
- case ShidIf ifInstruction -> {
- boundVariables = findAssignedVariables(ifInstruction.trueBody(), boundVariables);
- boundVariables = findAssignedVariables(ifInstruction.falseBody(), boundVariables);
- }
- case ShidIntAdd intAddInstruction -> {
- }
- case ShidIntEquals intEqualsInstruction -> {
- }
- case ShidIntNotEqual intNotEqualInstruction -> {
- }
- case ShidIntSub intSubInstruction -> {
- }
- case ShidLocalDrop localDropInstruction -> {
- }
- case ShidLocalLoad localLoadInstruction -> {
- }
- case ShidLocalStore localStoreInstruction -> {
- boundVariables = boundVariables.plus(BoundVariable.immutable(localStoreInstruction.name()));
- }
- case ShidLoopBreak loopBreakInstruction -> {
- }
- case ShidLoopContinue loopContinueInstruction -> {
- }
- case ShidLoop loopInstruction -> {
- boundVariables = findAssignedVariables(loopInstruction.body(), boundVariables);
- }
- case ShidNamespaceFieldStore namespaceFieldStoreInstruction -> {
- }
- case ShidNamespaceImport namespaceImportInstruction -> {
- }
- case ShidPushBool pushBoolInstruction -> {
- }
- case ShidPushInt pushIntInstruction -> {
- }
- case ShidPushString pushStringInstruction -> {
- }
- case ShidPushUnit pushUnitInstruction -> {
- }
- case ShidResume resumeInstruction -> {
- }
- case ShidReturn returnInstruction -> {
- }
- case ShidStringAdd stringAddInstruction -> {
- }
- case ShidSwitch switchInstruction -> {
- for (var switchCase : switchInstruction.cases()) {
- boundVariables = findAssignedVariables(switchCase.body(), boundVariables);
- }
- }
- case ShidTry tryInstruction -> {
- boundVariables = findAssignedVariables(tryInstruction.body(), boundVariables);
- }
- case ShidTupleCreate tupleCreateInstruction -> {
- }
- case ShidTupleGet tupleGetInstruction -> {
- }
- case ShidVarLoad varLoadInstruction -> {
+ for (var boundVariable : body.boundVariables()) {
+ switch (boundVariable.variant()) {
+ case PARAM -> {
+ // Params should be defined by the containing function.
+ }
+ case VAL -> {
+ context = context.declareShidVal(
+ boundVariable.name(),
+ PatioCodeGenTypes.VALUE_TYPE
+ ).context();
}
- case ShidVarStore varStoreInstruction -> {
- boundVariables = boundVariables.plus(BoundVariable.mutable(varStoreInstruction.name()));
+ case VAR -> {
+ var patioLocalResult = context.declareShidVal(
+ boundVariable.name(),
+ PatioTypes.DATA_POINTER
+ );
+ var patioLocal = patioLocalResult.value();
+ context = patioLocalResult.context();
+
+ // TODO: proper source (probably by storing variables on the function/namespace)
+ context = context.addInstruction(new PatioAllocStack(
+ patioLocal,
+ PatioDataLayouts.fromType(PatioCodeGenTypes.VALUE_TYPE),
+ Sources.NULL
+ ));
+
+ context = context.initShidLocal(boundVariable.name());
}
}
}
-
- return boundVariables;
+ return context;
}
private static PatioCodeGenContext pushValue(int value, Source source, PatioCodeGenContext context) {
diff --git a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java
index a16ae895..fee218db 100644
--- a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java
@@ -507,16 +507,16 @@ public class ShidCodeGen {
}
private static Context compileReference(TypedReferenceNode node, Context context) {
- var shedVariable = context.shedVariable(node.name());
+ var shidVariable = context.shedVariableToShidVariable(node.name());
- if (shedVariable.isVar) {
+ if (shidVariable.isVar()) {
return context.addInstruction(new ShidVarLoad(
- shedVariable.shidLocalName,
+ shidVariable.name(),
node.source()
));
} else {
return context.addInstruction(new ShidLocalLoad(
- shedVariable.shidLocalName,
+ shidVariable.name(),
node.source()
));
}
@@ -767,37 +767,37 @@ public class ShidCodeGen {
);
private final PVector<ShidInstruction> instructions;
- private final PMap<String, ShedVariable> shedVariablesByName;
- private final PVector<String> boundLocals;
+ private final PMap<String, ShidVariable> shedVariablesByName;
+ private final PVector<ShidVariable> boundVariables;
private final Source source;
public BlockContext(
PVector<ShidInstruction> instructions,
- PMap<String, ShedVariable> shedVariablesByName,
- PVector<String> boundLocals,
+ PMap<String, ShidVariable> shedVariablesByName,
+ PVector<ShidVariable> boundVariables,
Source source
) {
this.instructions = instructions;
this.shedVariablesByName = shedVariablesByName;
- this.boundLocals = boundLocals;
+ this.boundVariables = boundVariables;
this.source = source;
}
public ShidBlock toBlock() {
// TODO: test collection of bound locals
- return new ShidBlock(this.boundLocals, this.instructions, this.source);
+ return new ShidBlock(this.boundVariables, this.instructions, this.source);
}
public BlockContext addInstruction(ShidInstruction instruction) {
return new BlockContext(
this.instructions.plus(instruction),
this.shedVariablesByName,
- this.boundLocals,
+ this.boundVariables,
this.source
);
}
- public ShedVariable shedVariable(String variableName) {
+ public ShidVariable shedVariable(String variableName) {
var shedVariable = this.shedVariablesByName.get(variableName);
if (shedVariable == null) {
@@ -807,11 +807,11 @@ public class ShidCodeGen {
return shedVariable;
}
- public BlockContext addShedVariable(String name, ShedVariable variable) {
+ public BlockContext addShedVariable(String shedName, ShidVariable shidVariable) {
return new BlockContext(
this.instructions,
- this.shedVariablesByName.plus(name, variable),
- this.boundLocals.plus(variable.shidLocalName),
+ this.shedVariablesByName.plus(shedName, shidVariable),
+ this.boundVariables.plus(shidVariable),
this.source
);
}
@@ -875,16 +875,16 @@ public class ShidCodeGen {
}
public String shedVariableToLocal(String variableName) {
- return shedVariable(variableName).shidLocalName;
+ return shedVariableToShidVariable(variableName).name();
}
- public ShedVariable shedVariable(String variableName) {
+ public ShidVariable shedVariableToShidVariable(String variableName) {
return this.block.shedVariable(variableName);
}
// TODO: make private / remove? Variables should be declared using enterBlock().
public Context addShedVal(String variableName) {
- return addShedVariable(BoundVariable.immutable(variableName));
+ return addShedVariable(BoundVariable.val(variableName));
}
// TODO: make private? Variables should be declared using enterBlock().
@@ -893,7 +893,14 @@ public class ShidCodeGen {
return new Context(
this.blockStack,
- this.block.addShedVariable(boundVariable.name(), new ShedVariable(localName, boundVariable.isMutable())),
+ this.block.addShedVariable(
+ boundVariable.name(),
+ new ShidVariable(localName, switch (boundVariable.variant()) {
+ case PARAM -> ShidVariable.Variant.PARAM;
+ case VAL -> ShidVariable.Variant.VAL;
+ case VAR -> ShidVariable.Variant.VAR;
+ })
+ ),
this.localNames.plus(localName)
);
}
@@ -921,5 +928,4 @@ public class ShidCodeGen {
public record Result<T>(T value, Context context) {}
}
- private record ShedVariable(String shidLocalName, boolean isVar) {}
}
diff --git a/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java b/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java
index e764edca..66f6e049 100644
--- a/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java
+++ b/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java
@@ -25,7 +25,22 @@ public class ShidSerializer {
}
private static Tree blockToTree(ShidBlock block) {
- return instructionsToTree(block.instructions());
+ return treeListIndented(
+ treeIdentifier("block"),
+ treeListIndented(
+ block.boundVariables().stream()
+ .map(variable -> treeList(
+ treeIdentifier(switch (variable.variant()) {
+ case PARAM -> "param";
+ case VAL -> "val";
+ case VAR -> "var";
+ }),
+ treeString(variable.name())
+ ))
+ .toList()
+ ),
+ instructionsToTree(block.instructions())
+ );
}
private static Tree instructionsToTree(List<? extends ShidInstruction> instructions) {
@@ -39,10 +54,7 @@ public class ShidSerializer {
private static Tree instructionToTree(ShidInstruction instruction) {
return switch (instruction) {
case ShidBlock blockInstruction ->
- treeListIndented(
- treeIdentifier("block"),
- instructionsToTree(blockInstruction.instructions())
- );
+ blockToTree(blockInstruction);
case ShidCall callInstruction ->
treeList(
diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidBlock.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidBlock.java
index 9bf17b3f..d8eaca5c 100644
--- a/src/main/java/org/shedlang/compiler/shid/instructions/ShidBlock.java
+++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidBlock.java
@@ -5,7 +5,7 @@ import org.shedlang.compiler.sources.Source;
import java.util.List;
public record ShidBlock(
- List<String> boundLocals,
+ List<ShidVariable> boundVariables,
List<ShidInstruction> instructions,
Source source
) implements ShidInstruction {
diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidVariable.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidVariable.java
new file mode 100644
index 00000000..a183c955
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidVariable.java
@@ -0,0 +1,13 @@
+package org.shedlang.compiler.shid.instructions;
+
+public record ShidVariable(String name, Variant variant) {
+ public boolean isVar() {
+ return this.variant == Variant.VAR;
+ }
+
+ public enum Variant {
+ PARAM,
+ VAL,
+ VAR
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/DeclaredVariable.java b/src/main/java/org/shedlang/compiler/typechecker/DeclaredVariable.java
index 8258208d..735335d8 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/DeclaredVariable.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/DeclaredVariable.java
@@ -1,5 +1,6 @@
package org.shedlang.compiler.typechecker;
+import org.shedlang.compiler.ast.typed.BoundVariable;
import org.shedlang.compiler.ast.untyped.UntypedVariableDeclarationNode;
import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.types.Visibility;
@@ -25,4 +26,12 @@ public record DeclaredVariable(
public boolean isMutable() {
return variableType().isMutable();
}
+
+ // TODO: is there a meaningful distinction between DeclaredVariable and BoundVariable?
+ public BoundVariable toBoundVariable() {
+ return new BoundVariable(
+ this.name,
+ this.variableType.toBoundVariableVariant()
+ );
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java b/src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java
index 6a5e32a2..ea425793 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java
@@ -49,7 +49,10 @@ public class EnvironmentBuilder {
public List<BoundVariable> toBoundVariables() {
return environment.entrySet().stream()
- .map(entry -> new BoundVariable(entry.getKey(), entry.getValue().isMutable()))
+ .map(entry -> new BoundVariable(
+ entry.getKey(),
+ entry.getValue().variableType().toBoundVariableVariant()
+ ))
.toList();
}
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index 65046b42..f083913f 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -1147,6 +1147,7 @@ public class TypeChecker {
var typedImportNodes = new ArrayList<TypedImportNode>();
for (var import_ : untyped.imports()) {
+ // TODO: reuse DeclaredVariables to add import to environment?
namespaceEnvironment = namespaceEnvironment.add(
import_.name(),
Variable.defined(new NamespaceType(import_.namespaceName()), VariableType.IMPORT),
@@ -1280,10 +1281,7 @@ public class TypeChecker {
typedImportNodes,
typedBody,
declaredVariables.stream()
- .map(boundVariable -> new BoundVariable(
- boundVariable.name(),
- boundVariable.isMutable()
- ))
+ .map(boundVariable -> boundVariable.toBoundVariable())
.toList(),
fieldNames,
untyped.source()
diff --git a/src/main/java/org/shedlang/compiler/typechecker/VariableType.java b/src/main/java/org/shedlang/compiler/typechecker/VariableType.java
index a6cd12df..1c2b9bff 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/VariableType.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/VariableType.java
@@ -1,5 +1,7 @@
package org.shedlang.compiler.typechecker;
+import org.shedlang.compiler.ast.typed.BoundVariable;
+
public enum VariableType {
CONSTANT,
IMPORT,
@@ -16,4 +18,14 @@ public enum VariableType {
case VAR -> true;
};
}
+
+ public BoundVariable.Variant toBoundVariableVariant() {
+ return switch (this) {
+ case CONSTANT -> BoundVariable.Variant.VAL;
+ case IMPORT -> BoundVariable.Variant.VAL;
+ case PARAM -> BoundVariable.Variant.PARAM;
+ case VAL -> BoundVariable.Variant.VAL;
+ case VAR -> BoundVariable.Variant.VAR;
+ };
+ }
}