import exceptions.* class Lexical { /** * Analyzes the given [source] and returns the tokens divided into an array of statements */ fun analyze(source: String): MutableList>> { var buffer = "" var skipStatementEnd = false var statementEnd: Boolean val statements = mutableListOf>>() val currentStatement = mutableListOf>() for (i in source.indices) { buffer += source[i] if (source[i] == '"') skipStatementEnd = !skipStatementEnd statementEnd = source[i] == ';' && !skipStatementEnd val tokenType = getTokenType(buffer, if (source.length > i + 1) source[i + 1] else ' ') if (tokenType != TokenType.Skip && !statementEnd) { currentStatement.add(buffer to tokenType) buffer = "" } else if (statementEnd) { statements.add(currentStatement.toMutableList()) currentStatement.clear() buffer = "" } } return statements } /** * 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 in emptiness && token.length > 1 -> throw UnknownType(token) token in emptiness -> 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("\"", "'") private val emptiness = listOf(" ", "\t") }