package minijava.lexer object Tokens { sealed trait TokenClass { self => def tokenClass: self.type = self } case object IDCLASS extends TokenClass { override def toString: String = "identifier" } case object NUMLITCLASS extends TokenClass { override def toString: String = "integer literal" } case object STRLITCLASS extends TokenClass { override def toString: String = "string literal" }} sealed trait TokenInfo { def tokenClass: TokenClass } case object BAD extends TokenInfo with TokenClass // represents incorrect tokens. case object EOF extends TokenInfo with TokenClass case object SEMICOLON extends TokenInfo with TokenClass // ; /* etc. */ // Identifiers case class ID(value: String) extends TokenInfo { override def toString: String = value def tokenClass: TokenClass = IDCLASS } /* etc. */ // A Token is a positional wrapper around a TokenInfo class Token(val info: TokenInfo) extends Positional { override def toString: String = info.toString def tokenClass: TokenClass = info.tokenClass } object Token { def apply(info: TokenInfo): Token = new Token(info) def unapply(token: Token): Option[TokenInfo] = Some(token.info) } }