Skip to content

Commit

Permalink
add big decimal parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
ice1000 committed Apr 23, 2017
1 parent 332810c commit f150d4c
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 21 deletions.
43 changes: 26 additions & 17 deletions src/main/kotlin/org/lice/compiler/parse/Number.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import java.math.BigInteger
// get() = this >= '0' && this <= '9'

fun String.isInt(isNegative: Boolean = false): Boolean {
if (!isNegative && this[0] == '-') return substring(1).isInt(true)
if (!isNegative && '-' == this[0]) return substring(1).isInt(true)
return isNotEmpty() && fold(true, { res, char ->
res && char.isDigit()
})
Expand All @@ -32,43 +32,55 @@ fun Char.safeLower() =
}

fun String.isHexInt(isNegative: Boolean = false): Boolean {
if (!isNegative && this[0] == '-') return substring(1).isHexInt(true)
if (!isNegative && '-' == this[0]) return substring(1).isHexInt(true)
return when {
length <= 2 -> false
this[0] != '0' || this[1].safeLower() != 'x' -> false
'0' != this[0] || 'x' != this[1].safeLower() -> false
else -> (2..length - 1)
.map { this[it].toLowerCase() }
.none { !it.isDigit() && (it < 'a' || it > 'f') }
.all { it.isDigit() || it in 'a'..'f' }
}
}

fun String.isBigInt(isNegative: Boolean = false): Boolean {
if (!isNegative && this[0] == '-') return substring(1).isBigInt(true)
if (!isNegative && '-' == this[0]) return substring(1).isBigInt(true)
return when {
length <= 1 -> false
this[length - 1].safeLower() != 'n' -> false
'n' != this[length - 1].safeLower() -> false
else -> {
val a = substring(0..length - 2)
a.isInt() || a.isHexInt() || a.isBinInt() || a.isOctInt()
}
}
}

fun String.isBigDec(isNegative: Boolean = false): Boolean {
if (!isNegative && '-' == this[0]) return substring(1).isBigDec(true)
return when {
length <= 2 -> false
'm' != this[length - 1].safeLower() -> false
else -> {
val a = substring(0..length - 2)
1 >= a.count { '.' == it } && a.all { '.' == it || it.isDigit() }
}
}
}

fun String.isBinInt(isNegative: Boolean = false): Boolean {
if (!isNegative && this[0] == '-') return substring(1).isBinInt(true)
return when {
length <= 2 -> false
this[0] != '0' || this[1].safeLower() != 'b' -> false
else -> (2..length - 1).none { this[it] != '0' && this[it] != '1' }
'0' != this[0] || 'b' != this[1].safeLower() -> false
else -> (2..length - 1).none { '0' != this[it] && '1' != this[it] }
}
}

fun String.isOctInt(isNegative: Boolean = false): Boolean {
if (!isNegative && this[0] == '-') return substring(1).isOctInt(true)
if (!isNegative && '-' == this[0]) return substring(1).isOctInt(true)
return when {
length <= 1 -> false
this[0] != '0' -> false
else -> (1..length - 1).none { !this[it].isOctalInt() }
'0' != this[0] -> false
else -> (1..length - 1).all { this[it].isOctalInt() }
}
}

Expand All @@ -79,19 +91,17 @@ fun String.toHexInt(): Int {
ret = ret shl 4
val char = this[it].safeLower()
if (char.isDigit()) ret += (char - '0')
else /* if (char >= 'a' && char <= 'f') */ ret += (char - 'a' + 10)
// ret *= 16
else ret += (char - 'a' + 10)
}
return ret
}

fun String.toBinInt(): Int {
if (this[0] == '-') return -substring(1).toBinInt()
if ('-' == this[0]) return -substring(1).toBinInt()
var ret = 0
(2..length - 1).forEach {
ret = ret shl 1
if (this[it] == '1') ++ret
// ret *= 2
if ('1' == this[it]) ++ret
}
return ret
}
Expand All @@ -113,7 +123,6 @@ fun String.toOctInt(): Int {
(1..length - 1).forEach {
ret = ret shl 3
ret += this[it] - '0'
// ret *= 8
}
return ret
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/org/lice/repl/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
*/
package org.lice.repl

val VERSION_CODE = "v3.0-SNAPSHOT"
val VERSION_CODE = "v3.0.4-SNAPSHOT"
25 changes: 23 additions & 2 deletions src/test/kotlin/org/lice/FeatureTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import org.jetbrains.annotations.TestOnly
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test
import org.lice.core.SymbolList
import java.io.File
import java.math.BigDecimal
import java.math.BigInteger
import java.util.*
Expand Down Expand Up @@ -32,23 +34,41 @@ class FeatureTest {
}

/**
* test for int literals
* test for primitives literals
*/
@Test(timeout = 1000)
fun test2() {
assertEquals(233666, Lice.run("""
(print 233666)
"""))
assertEquals(233666, Lice.run("233666"))
assertEquals(233666F, Lice.run("233666.0"))
assertEquals(233666.0, Lice.run("233666.0000000000000000000000000000000"))
assertTrue(true == Lice.run("true"))
assertFalse(true == Lice.run("false"))
assertNull(Lice.run("null"))
}

/**
* test for plus
* test for plus minus times devide
*/
@Test(timeout = 1000)
fun test3() {
assertEquals(7, Lice.run("""
(+ 1 (+ 1 2 3))
"""))
assertEquals(-5, Lice.run("""
(- 1 (+ 1 2 3))
"""))
assertEquals(20, Lice.run("""
(* 4 (+ 2 3))
"""))
assertEquals(0, Lice.run("+"))
assertEquals(0, Lice.run("-"))
assertEquals(0, Lice.run("(+)"))
assertEquals(0, Lice.run("(-)"))
assertEquals(20, Lice.run("""
(* 4 (+ 2 3))
"""))
}

Expand All @@ -60,6 +80,7 @@ class FeatureTest {
assertEquals(BigInteger("10000000000000000000000000000233"), Lice.run("""
(+ 10000000000000000000000000000000N 233)
"""))
assertEquals(BigInteger(0xDBE.toString()), Lice.run("0xDBEN"))
}

/**
Expand Down
23 changes: 22 additions & 1 deletion src/test/kotlin/org/lice/compiler/parse/NumberKtTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package org.lice.compiler.parse

import org.junit.Assert.*
import org.junit.Test
import org.lice.compiler.parse.*
import java.math.BigDecimal
import java.math.BigInteger

/**
Expand Down Expand Up @@ -95,4 +95,25 @@ class NumberKtTest {
assertEquals(BigInteger("-21893219"), "-21893219n".toBigInt())
}

@Test
fun isBigDec() {
assertTrue("1273983189279m".isBigDec())
assertTrue("12739.83189279m".isBigDec())
assertTrue("1273983189279M".isBigDec())
assertTrue("127398.3189279M".isBigDec())
assertTrue("-1273983189279M".isBigDec())
assertTrue("-127398.3189279M".isBigDec())
assertFalse("-12739831dsf9M".isBigDec())
assertFalse("-127398.31dsf9M".isBigDec())
}

@Test
fun toBigDec() {
assertEquals(BigDecimal("1273983189279"), "1273983189279m".toBigDec())
assertEquals(BigDecimal("12739.83189279"), "12739.83189279m".toBigDec())
assertEquals(BigDecimal("1273983189279"), "1273983189279M".toBigDec())
assertEquals(BigDecimal("127398.3189279"), "127398.3189279M".toBigDec())
assertEquals(BigDecimal("-1273983189279"), "-1273983189279M".toBigDec())
assertEquals(BigDecimal("-127398.3189279"), "-127398.3189279M".toBigDec())
}
}

0 comments on commit f150d4c

Please sign in to comment.