From f150d4c6d22e6f92cd5a3fb3a8ed8c921407f53f Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 23 Apr 2017 16:16:17 +0800 Subject: [PATCH] add big decimal parsing --- .../kotlin/org/lice/compiler/parse/Number.kt | 43 +++++++++++-------- src/main/kotlin/org/lice/repl/Constants.kt | 2 +- src/test/kotlin/org/lice/FeatureTest.kt | 25 ++++++++++- .../org/lice/compiler/parse/NumberKtTest.kt | 23 +++++++++- 4 files changed, 72 insertions(+), 21 deletions(-) diff --git a/src/main/kotlin/org/lice/compiler/parse/Number.kt b/src/main/kotlin/org/lice/compiler/parse/Number.kt index 2c38eb6..ccfbf4c 100644 --- a/src/main/kotlin/org/lice/compiler/parse/Number.kt +++ b/src/main/kotlin/org/lice/compiler/parse/Number.kt @@ -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() }) @@ -32,21 +32,21 @@ 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() @@ -54,21 +54,33 @@ fun String.isBigInt(isNegative: Boolean = false): Boolean { } } +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() } } } @@ -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 } @@ -113,7 +123,6 @@ fun String.toOctInt(): Int { (1..length - 1).forEach { ret = ret shl 3 ret += this[it] - '0' -// ret *= 8 } return ret } diff --git a/src/main/kotlin/org/lice/repl/Constants.kt b/src/main/kotlin/org/lice/repl/Constants.kt index 4213e77..f5a7bff 100644 --- a/src/main/kotlin/org/lice/repl/Constants.kt +++ b/src/main/kotlin/org/lice/repl/Constants.kt @@ -6,4 +6,4 @@ */ package org.lice.repl -val VERSION_CODE = "v3.0-SNAPSHOT" +val VERSION_CODE = "v3.0.4-SNAPSHOT" diff --git a/src/test/kotlin/org/lice/FeatureTest.kt b/src/test/kotlin/org/lice/FeatureTest.kt index a30910f..5197f95 100644 --- a/src/test/kotlin/org/lice/FeatureTest.kt +++ b/src/test/kotlin/org/lice/FeatureTest.kt @@ -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.* @@ -32,7 +34,7 @@ class FeatureTest { } /** - * test for int literals + * test for primitives literals */ @Test(timeout = 1000) fun test2() { @@ -40,15 +42,33 @@ class FeatureTest { (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)) """)) } @@ -60,6 +80,7 @@ class FeatureTest { assertEquals(BigInteger("10000000000000000000000000000233"), Lice.run(""" (+ 10000000000000000000000000000000N 233) """)) + assertEquals(BigInteger(0xDBE.toString()), Lice.run("0xDBEN")) } /** diff --git a/src/test/kotlin/org/lice/compiler/parse/NumberKtTest.kt b/src/test/kotlin/org/lice/compiler/parse/NumberKtTest.kt index 72e725e..cc30b3d 100644 --- a/src/test/kotlin/org/lice/compiler/parse/NumberKtTest.kt +++ b/src/test/kotlin/org/lice/compiler/parse/NumberKtTest.kt @@ -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 /** @@ -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()) + } } \ No newline at end of file