Skip to content

Commit

Permalink
Updated Cradle, Ktlint
Browse files Browse the repository at this point in the history
  • Loading branch information
Venkateswaran committed Jul 16, 2024
1 parent ed9628e commit 2e20424
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 66 deletions.
108 changes: 108 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 240
tab_width = 4
ij_continuation_indent_size = 8
ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = false
ij_smart_tabs = false
ij_visual_guides = none
ij_wrap_on_typing = false

[.editorconfig]
ij_any_space_after_comma = false

[{*.kt,*.kts}]
ij_continuation_indent_size = 4
ij_kotlin_align_in_columns_case_branch = false
ij_kotlin_align_multiline_binary_operation = false
ij_kotlin_align_multiline_extends_list = false
ij_kotlin_align_multiline_method_parentheses = false
ij_kotlin_align_multiline_parameters = true
ij_kotlin_align_multiline_parameters_in_calls = false
ij_kotlin_allow_trailing_comma = false
ij_kotlin_allow_trailing_comma_on_call_site = false
ij_kotlin_assignment_wrap = normal
ij_kotlin_blank_lines_after_class_header = 0
ij_kotlin_blank_lines_around_block_when_branches = 0
ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1
ij_kotlin_block_comment_at_first_column = true
ij_kotlin_call_parameters_new_line_after_left_paren = true
ij_kotlin_call_parameters_right_paren_on_new_line = true
ij_kotlin_call_parameters_wrap = on_every_item
ij_kotlin_catch_on_new_line = false
ij_kotlin_class_annotation_wrap = split_into_lines
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
ij_kotlin_continuation_indent_for_chained_calls = false
ij_kotlin_continuation_indent_for_expression_bodies = false
ij_kotlin_continuation_indent_in_argument_lists = false
ij_kotlin_continuation_indent_in_elvis = false
ij_kotlin_continuation_indent_in_if_conditions = false
ij_kotlin_continuation_indent_in_parameter_lists = false
ij_kotlin_continuation_indent_in_supertype_lists = false
ij_kotlin_else_on_new_line = false
ij_kotlin_enum_constants_wrap = off
ij_kotlin_extends_list_wrap = normal
ij_kotlin_field_annotation_wrap = split_into_lines
ij_kotlin_finally_on_new_line = false
ij_kotlin_if_rparen_on_new_line = true
ij_kotlin_import_nested_classes = false
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
ij_kotlin_keep_blank_lines_before_right_brace = 2
ij_kotlin_keep_blank_lines_in_code = 2
ij_kotlin_keep_blank_lines_in_declarations = 2
ij_kotlin_keep_first_column_comment = true
ij_kotlin_keep_indents_on_empty_lines = false
ij_kotlin_keep_line_breaks = true
ij_kotlin_lbrace_on_next_line = false
ij_kotlin_line_comment_add_space = false
ij_kotlin_line_comment_at_first_column = true
ij_kotlin_method_annotation_wrap = split_into_lines
ij_kotlin_method_call_chain_wrap = normal
ij_kotlin_method_parameters_new_line_after_left_paren = true
ij_kotlin_method_parameters_right_paren_on_new_line = true
ij_kotlin_method_parameters_wrap = on_every_item
ij_kotlin_name_count_to_use_star_import = 2147483647
ij_kotlin_name_count_to_use_star_import_for_members = 2147483647
ij_kotlin_packages_to_use_import_on_demand = ""
ij_kotlin_parameter_annotation_wrap = off
ij_kotlin_space_after_comma = true
ij_kotlin_space_after_extend_colon = true
ij_kotlin_space_after_type_colon = true
ij_kotlin_space_before_catch_parentheses = true
ij_kotlin_space_before_comma = false
ij_kotlin_space_before_extend_colon = true
ij_kotlin_space_before_for_parentheses = true
ij_kotlin_space_before_if_parentheses = true
ij_kotlin_space_before_lambda_arrow = true
ij_kotlin_space_before_type_colon = false
ij_kotlin_space_before_when_parentheses = true
ij_kotlin_space_before_while_parentheses = true
ij_kotlin_spaces_around_additive_operators = true
ij_kotlin_spaces_around_assignment_operators = true
ij_kotlin_spaces_around_equality_operators = true
ij_kotlin_spaces_around_function_type_arrow = true
ij_kotlin_spaces_around_logical_operators = true
ij_kotlin_spaces_around_multiplicative_operators = true
ij_kotlin_spaces_around_range = false
ij_kotlin_spaces_around_relational_operators = true
ij_kotlin_spaces_around_unary_operator = false
ij_kotlin_spaces_around_when_arrow = true
ij_kotlin_variable_annotation_wrap = off
ij_kotlin_while_on_new_line = false
ij_kotlin_wrap_elvis_expressions = 1
ij_kotlin_wrap_expression_body_functions = 1
ij_kotlin_wrap_first_method_in_call_chain = false
ktlint_experimental = disabled
ktlint_standard_filename = disabled
ktlint_standard_discouraged-comment-location = disabled
ktlint_standard_if-else-wrapping = disabled
max_line_length = 140
10 changes: 5 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
kotlin("jvm") version "1.8.21"
id("org.jlleitschuh.gradle.ktlint") version "11.5.0"
kotlin("jvm") version "1.9.20"
id("org.jlleitschuh.gradle.ktlint") version "12.1.0"
`java-library`
}

Expand All @@ -9,7 +9,7 @@ repositories {
}

java.toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
languageVersion.set(JavaLanguageVersion.of(21))
}

val arrowVersion = "1.2.0-RC"
Expand All @@ -23,8 +23,8 @@ tasks.test {
useJUnitPlatform()
}

val kotestVersion = "5.6.2"
val arrowKotestVersion = "1.3.3"
val kotestVersion = "5.9.1"
val arrowKotestVersion = "1.4.0"
dependencies {
testImplementation("io.kotest:kotest-runner-junit5-jvm:$kotestVersion")
testImplementation("io.kotest:kotest-assertions-core-jvm:$kotestVersion")
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStorePath=wrapper/dists
13 changes: 5 additions & 8 deletions src/main/kotlin/AddingStandardParsersToTheLibrary.kt
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import arrow.core.None
import arrow.core.Some

fun parseChar(charToMatch: Char): Parser<Char> =
satisfy({ c: Char -> c == charToMatch }, "$charToMatch")
fun parseChar(charToMatch: Char): Parser<Char> = satisfy({ c: Char -> c == charToMatch }, "$charToMatch")

fun<T> choice(parsers: List<Parser<out T>>): Parser<out T> =
parsers.reduce { parseA, parseB -> parseA orElse parseB }
fun <T> choice(parsers: List<Parser<out T>>): Parser<out T> = parsers.reduce { parseA, parseB -> parseA orElse parseB }

fun anyOf(charsToMatch: List<Char>): Parser<out Char> =
charsToMatch
.map { char -> parseChar(char) }
.let { choice(it) }

fun manyChars(cp: Parser<out Char>): Parser<String> =
many(cp).mapP { it.joinToString("") }
fun manyChars(cp: Parser<out Char>): Parser<String> = many(cp).mapP { it.joinToString("") }

fun manyChars1(cp: Parser<Char>): Parser<String> =
many1(cp).mapP { it.joinToString("") }
fun manyChars1(cp: Parser<Char>): Parser<String> = many1(cp).mapP { it.joinToString("") }

fun parseString(stringToMatch: String): Parser<String> =
stringToMatch
Expand All @@ -27,6 +23,7 @@ fun parseString(stringToMatch: String): Parser<String> =
.setLabel(stringToMatch)

fun whitespaceChar(): Parser<Char> = satisfy({ c: Char -> c.isWhitespace() }, "whitespace")

val spaces = many(whitespaceChar())
val spaces1 = many1(whitespaceChar())

Expand Down
46 changes: 30 additions & 16 deletions src/main/kotlin/BuildingUsefulSetOfParserCombinators.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,30 @@ fun <T> returnP(value: T): Parser<T> {
return Parser(parserFn, "Unknown label")
}

fun <T, U> Parser<(T) -> U>.applyP(xp: Parser<T>): Parser<U> =
(this andThen xp).mapP { (f, x) -> f(x) }
fun <T, U> Parser<(T) -> U>.applyP(xp: Parser<T>): Parser<U> = (this andThen xp).mapP { (f, x) -> f(x) }

fun <T, U, C> lift2(f: (T, U) -> C): (Parser<T>, Parser<U>) -> Parser<C> =
{ parseT: Parser<T>, parseU: Parser<U> -> returnP(f.curried()).applyP(parseT).applyP(parseU) }
{ parseT: Parser<T>, parseU: Parser<U> ->
returnP(
f.curried()
).applyP(parseT).applyP(parseU)
}

// should be archived with tail recursion, but my head is spinning if I think on how to maike it :)
fun <T> List<Parser<T>>.sequence(): Parser<List<T>> {
val consP = lift2<T, List<T>, List<T>>(::cons)
return if (isEmpty()) returnP(emptyList()) else consP(first(), takeLast(size - 1).sequence())
}

fun<T> cons(head: T, tail: List<T>): List<T> = listOf(head) + tail
fun <T> cons(
head: T,
tail: List<T>
): List<T> = listOf(head) + tail

fun <T> parseZeroOrMore(parser: Parser<T>, input: InputState): Pair<List<T>, InputState> =
fun <T> parseZeroOrMore(
parser: Parser<T>,
input: InputState
): Pair<List<T>, InputState> =
when (val result = parser.runOnInput(input)) {
is Either.Left -> emptyList<T>() to input
is Either.Right -> {
Expand Down Expand Up @@ -85,25 +94,31 @@ fun buildSignedIntParser(): Parser<Int> {
}
}

fun <T, U> Parser<T>.throwLeft(other: Parser<U>): Parser<U> =
(this andThen other).mapP { (_, right) -> right }
fun <T, U> Parser<T>.throwLeft(other: Parser<U>): Parser<U> = (this andThen other).mapP { (_, right) -> right }

fun <T, U> Parser<T>.throwRight(other: Parser<U>): Parser<T> =
(this andThen other).mapP { (left, _) -> left }
fun <T, U> Parser<T>.throwRight(other: Parser<U>): Parser<T> = (this andThen other).mapP { (left, _) -> left }

fun <L, M, R> between(left: Parser<L>, middle: Parser<M>, right: Parser<R>): Parser<M> =
left.throwLeft(middle).throwRight(right)
fun <L, M, R> between(
left: Parser<L>,
middle: Parser<M>,
right: Parser<R>
): Parser<M> = left.throwLeft(middle).throwRight(right)

fun <T, U> sepBy1(listItemParser: Parser<T>, separator: Parser<U>): Parser<List<T>> {
fun <T, U> sepBy1(
listItemParser: Parser<T>,
separator: Parser<U>
): Parser<List<T>> {
val sepThenP = separator.throwLeft(listItemParser)
return (listItemParser andThen many(sepThenP))
.mapP { (firstItemInList, remainingItemsInList) ->
listOf(firstItemInList) + remainingItemsInList
}
}

fun <T, U> sepBy(listParser: Parser<T>, separator: Parser<U>): Parser<out List<T>> =
sepBy1(listParser, separator) orElse returnP(emptyList())
fun <T, U> sepBy(
listParser: Parser<T>,
separator: Parser<U>
): Parser<out List<T>> = sepBy1(listParser, separator) orElse returnP(emptyList())

fun <T, U> Parser<T>.bindP(transform: (T) -> Parser<U>): Parser<U> {
val parserFn = { input: InputState ->
Expand All @@ -118,8 +133,7 @@ fun <T, U> Parser<T>.bindP(transform: (T) -> Parser<U>): Parser<U> {
return Parser(parserFn, "unknown")
}

fun <T, U> Parser<T>.mapUsingBind(transform: (T) -> U): Parser<U> =
bindP(transform.andThen { returnP(it) })
fun <T, U> Parser<T>.mapUsingBind(transform: (T) -> U): Parser<U> = bindP(transform.andThen { returnP(it) })

val parseABC = parseString("ABC")
val manyA = many(parseA)
Expand Down
80 changes: 50 additions & 30 deletions src/main/kotlin/JsonParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,30 @@ import arrow.core.Some
import arrow.core.getOrElse

sealed class JValue {
data class JString(val value: String) : JValue()
data class JNumber(val value: Float) : JValue()
data class JBool(val value: Boolean) : JValue()
object JNull : JValue()
data class JObject(val value: Map<String, JValue>) : JValue()
data class JArray(val value: List<JValue>) : JValue()
data class JString(
val value: String
) : JValue()

data class JNumber(
val value: Float
) : JValue()

data class JBool(
val value: Boolean
) : JValue()

data object JNull : JValue()

data class JObject(
val value: Map<String, JValue>
) : JValue()

data class JArray(
val value: List<JValue>
) : JValue()
}

object JsonParser {

// jValue forward references for jArray and jObject
private var parserRef: Parser<out JValue> =
Parser(
Expand Down Expand Up @@ -45,22 +59,24 @@ object JsonParser {
"\\n" to '\n', // newline
"\\r" to '\r', // cr
"\\t" to '\t' // tab
)
.map { (toMatch, result) -> parseString(toMatch).mapP { result } }
).map { (toMatch, result) -> parseString(toMatch).mapP { result } }
.let { choice(it) }
.setLabel("escaped char")
private val backslash = parseChar('\\')
private val uChar = parseChar('u')
private val hexDigit =
anyOf(('0'..'9').toList() + ('A'..'F').toList() + ('a'..'f').toList())
private val fourHexDigits = hexDigit andThen hexDigit andThen hexDigit andThen hexDigit
val jUnicodeChar = backslash.throwLeft(uChar).throwLeft(fourHexDigits)
.mapP {
val (remainingDigits1, fourthDigit) = it
val (remainingDigits2, thirdDigit) = remainingDigits1
val (firstDigit, secondDigit) = remainingDigits2
"$firstDigit$secondDigit$thirdDigit$fourthDigit".toInt(16).toChar()
}
val jUnicodeChar =
backslash
.throwLeft(uChar)
.throwLeft(fourHexDigits)
.mapP {
val (remainingDigits1, fourthDigit) = it
val (remainingDigits2, thirdDigit) = remainingDigits1
val (firstDigit, secondDigit) = remainingDigits2
"$firstDigit$secondDigit$thirdDigit$fourthDigit".toInt(16).toChar()
}
private val quote = parseChar('\"').setLabel("quote")
private val jChar = jUnescapedChar orElse jEscapedChar orElse jUnicodeChar
private val quotedString = quote.throwLeft(manyChars(jChar)).throwRight(quote)
Expand Down Expand Up @@ -89,17 +105,18 @@ object JsonParser {
val signStr = optSign.getOrElse { "" }.toString()
val fractionPartStr =
fractionPart.getOrElse { "" }.let { digits -> ".$digits" }
val expPartStr = when (expPart) {
is None -> ""
is Some -> {
val (optSignExponent, digits) = expPart.value
"e" + optSignExponent.getOrElse { "" } + digits
val expPartStr =
when (expPart) {
is None -> ""
is Some -> {
val (optSignExponent, digits) = expPart.value
"e" + optSignExponent.getOrElse { "" } + digits
}
}
}
(signStr + intPart + fractionPartStr + expPartStr)
.toFloat().let { float -> JValue.JNumber(float) }
}
.setLabel("number")
.toFloat()
.let { float -> JValue.JNumber(float) }
}.setLabel("number")

// array
private val leftBracket = parseChar('[').throwRight(spaces)
Expand All @@ -121,10 +138,13 @@ object JsonParser {
private val keyValues = sepBy(keyValue, comma)

// set up the main parser
private val jObject = between(leftBrace, keyValues, rightBrace)
.mapP { it.toMap() }
.mapP { JValue.JObject(it) }
.setLabel("object")
private val jObject =
between(leftBrace, keyValues, rightBrace)
.mapP { it.toMap() }
.mapP { JValue.JObject(it) }
.setLabel("object")

init { parserRef = choice(listOf(jNull, jBool, jNumber, jString, jArray, jObject)) }
init {
parserRef = choice(listOf(jNull, jBool, jNumber, jString, jArray, jObject))
}
}
Loading

0 comments on commit 2e20424

Please sign in to comment.