aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-31 23:06:58 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-31 23:06:58 +0100
commit629382bf1172be2b0398fa1b65c1c46048c31af3 (patch)
tree5d76a890e052ee9467f7e237fc09bdeece38f1e2 /src/main/java
parentab0e1c0e31158a090630070472723c34deedc83a (diff)
Check assignment is to var
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java22
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/errors/CanOnlyAssignToVarError.java10
2 files changed, 24 insertions, 8 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index 0828e59a..5a3ee7a7 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -52,14 +52,16 @@ public class TypeChecker {
.orElseThrow(() -> new ReferenceBeforeDefinitionError(name, source));
}
- private static TypeCheckerResult<Type> runtimeLookup(String name, Source source, TypeCheckerContext context) {
+ private static TypeCheckerResult<Variable> runtimeLookup(String name, Source source, TypeCheckerContext context) {
return context.runtimeLookup(name, source).map(variable -> {
if (variable.isEmpty()) {
throw new UnknownVariableError(name, source);
}
- return variable.get().type()
+ variable.get().type()
.orElseThrow(() -> new ReferenceBeforeDefinitionError(name, source));
+
+ return variable.get();
});
}
@@ -738,10 +740,10 @@ public class TypeChecker {
UntypedReferenceNode untyped,
TypeCheckerContext context
) {
- return runtimeLookup(untyped.name(), untyped.source(), context).map(type -> {
+ return runtimeLookup(untyped.name(), untyped.source(), context).map(variable -> {
return new TypedReferenceNode(
untyped.name(),
- type,
+ variable.type().orElseThrow(),
untyped.source()
);
});
@@ -850,17 +852,21 @@ public class TypeChecker {
return switch (target) {
case UntypedTargetNode.Variable variable -> {
if (variableType.isEmpty()) {
- var targetTypeResult = runtimeLookup(
+ var targetVariableResult = runtimeLookup(
variable.name(),
variable.source(),
context
);
- var targetType = targetTypeResult.value();
- context = targetTypeResult.context();
+ var targetVariable = targetVariableResult.value();
+ context = targetVariableResult.context();
+
+ if (targetVariable.variableType() != VariableType.VAR) {
+ throw new CanOnlyAssignToVarError(target.source());
+ }
checkIsSubType(
expressionType,
- targetType,
+ targetVariable.type().orElseThrow(),
target.source(),
context
);
diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/CanOnlyAssignToVarError.java b/src/main/java/org/shedlang/compiler/typechecker/errors/CanOnlyAssignToVarError.java
new file mode 100644
index 00000000..ebfbc140
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/errors/CanOnlyAssignToVarError.java
@@ -0,0 +1,10 @@
+package org.shedlang.compiler.typechecker.errors;
+
+import org.shedlang.compiler.errors.SourceError;
+import org.shedlang.compiler.sources.Source;
+
+public class CanOnlyAssignToVarError extends SourceError {
+ public CanOnlyAssignToVarError(Source source) {
+ super("Can only assign to var", source);
+ }
+}