From 629382bf1172be2b0398fa1b65c1c46048c31af3 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 31 Jul 2023 23:06:58 +0100 Subject: Check assignment is to var --- .../shedlang/compiler/typechecker/TypeChecker.java | 22 ++++++++++++++-------- .../errors/CanOnlyAssignToVarError.java | 10 ++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/typechecker/errors/CanOnlyAssignToVarError.java (limited to 'src/main/java') 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 runtimeLookup(String name, Source source, TypeCheckerContext context) { + private static TypeCheckerResult 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); + } +} -- cgit v1.2.3