import exceptions.UnknownType class Lexical { fun analyze(source: String): MutableList> { var buffer = "" var statementEnd = false val tokens = mutableListOf>() for (i in source.indices) { buffer += source[i] statementEnd = source[i] == ';' val tokenType = getTokenType(buffer, if (source.length > i + 1) source[i + 1] else ' ') if (tokenType != TokenType.Skip) { tokens += buffer to tokenType buffer = "" } } return tokens } /** * Matches the tokens to a [TokenType] */ private fun getTokenType(token: String, next: Char): TokenType { return when { token + next in keyword -> TokenType.Skip token in keyword -> TokenType.Keyword token + next in comparison -> TokenType.Skip token in assignment -> TokenType.Assignment token + next in assignment -> TokenType.Skip token in arithmetic -> TokenType.Arithmetic token + next in comparison -> TokenType.Skip token in comparison -> TokenType.Comparison token + next in comparison -> TokenType.Skip token in logical -> TokenType.Logical (token + next).matches(Regex("[a-zA-Z]*")) -> TokenType.Skip token.matches(Regex("[a-zA-Z]*")) -> TokenType.Identifier (token + next).matches(Regex("[0-9]*")) -> TokenType.Skip token.matches(Regex("[0-9]*")) -> TokenType.Constant token.contains(" ") && token.length > 1 -> throw UnknownType(token) token == " " -> TokenType.Empty token in punctuation -> TokenType.Punctuation token in brackets -> TokenType.Bracket token in classifier -> TokenType.Classifier else -> TokenType.Skip } } private val keyword = listOf("print") // TODO: DataType matching private val assignment = listOf("=", "+=", "-=", "*=", "/*") private val arithmetic = listOf("+", "-", "*", "/", "%") private val comparison = listOf("==", "!=", "<", "<=", ">", ">=") private val logical = listOf("&&", "||", "!") private val punctuation = listOf(",", ":", ".", ";") private val brackets = listOf("(", ")", "[", "]", "{", "}") // TODO: Use brackets for functions private val classifier = listOf("\"", "'") }