diff --git a/src/main/scala/millfork/env/Environment.scala b/src/main/scala/millfork/env/Environment.scala index a7888e3d..66e2828a 100644 --- a/src/main/scala/millfork/env/Environment.scala +++ b/src/main/scala/millfork/env/Environment.scala @@ -694,9 +694,9 @@ class Environment(val parent: Option[Environment], val prefix: String) { } } - private def checkName[T <: Thing : Manifest](name: String, pos: Option[Position]): Unit = { + private def checkName[T <: Thing : Manifest](objType: String, name: String, pos: Option[Position]): Unit = { if (maybeGet[T](name).isEmpty) { - ErrorReporting.error(s"`$name` is not defined", pos) + ErrorReporting.error(s"$objType `$name` is not defined", pos) } } @@ -707,9 +707,10 @@ class Environment(val parent: Option[Environment], val prefix: String) { case _:DeclarationStatement => () case s:Statement => nameCheck(s.getAllExpressions) case _:LiteralExpression => () - case VariableExpression(name) => checkName[Thing](name, node.position) + case VariableExpression(name) => + checkName[VariableLikeThing]("Variable or constant", name, node.position) case IndexedExpression(name, index) => - checkName[Thing](name, node.position) + checkName[IndexableThing]("Array or pointer", name, node.position) nameCheck(index) case SeparateBytesExpression(h, l) => nameCheck(h) @@ -718,7 +719,7 @@ class Environment(val parent: Option[Environment], val prefix: String) { nameCheck(params.map(_._2)) case FunctionCallExpression(name, params) => if (name.exists(_.isLetter) && name != "not") { - checkName[MangledFunction](name, node.position) + checkName[CallableThing]("Function or type", name, node.position) } nameCheck(params) } diff --git a/src/main/scala/millfork/env/Thing.scala b/src/main/scala/millfork/env/Thing.scala index b3ca587f..bf1e3345 100644 --- a/src/main/scala/millfork/env/Thing.scala +++ b/src/main/scala/millfork/env/Thing.scala @@ -8,7 +8,13 @@ sealed trait Thing { def name: String } -sealed trait Type extends Thing { +sealed trait CallableThing extends Thing + +sealed trait VariableLikeThing extends Thing + +sealed trait IndexableThing extends Thing + +sealed trait Type extends CallableThing { def size: Int @@ -87,13 +93,13 @@ case class Label(name: String) extends ThingInMemory { override def toAddress: MemoryAddressConstant = MemoryAddressConstant(this) } -sealed trait Variable extends TypedThing +sealed trait Variable extends TypedThing with VariableLikeThing case class BlackHole(typ: Type) extends Variable { override def name = "" } -sealed trait VariableInMemory extends Variable with ThingInMemory { +sealed trait VariableInMemory extends Variable with ThingInMemory with IndexableThing { def zeropage: Boolean } @@ -144,7 +150,7 @@ case class InitializedMemoryVariable(name: String, address: Option[Constant], ty override def alloc: VariableAllocationMethod.Value = VariableAllocationMethod.Static } -trait MfArray extends ThingInMemory +trait MfArray extends ThingInMemory with IndexableThing case class UninitializedArray(name: String, sizeInBytes: Int) extends MfArray with UninitializedMemory { override def toAddress: MemoryAddressConstant = MemoryAddressConstant(this) @@ -164,8 +170,7 @@ case class RelativeVariable(name: String, address: Constant, typ: Type, zeropage override def toAddress: Constant = address } - -sealed trait MangledFunction extends Thing { +sealed trait MangledFunction extends CallableThing { def name: String def returnType: Type @@ -218,7 +223,7 @@ case class NormalFunction(name: String, override def shouldGenerate = true } -case class ConstantThing(name: String, value: Constant, typ: Type) extends TypedThing +case class ConstantThing(name: String, value: Constant, typ: Type) extends TypedThing with VariableLikeThing with IndexableThing trait ParamSignature { def types: List[Type]