1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-05-05 18:34:03 +02:00

Support binary numbers in vimscript

Also supports octal with an `0o` or `0O` prefix.
This commit is contained in:
Matt Ellis 2025-02-18 18:26:31 +00:00 committed by Alex Pláte
parent 23329cc522
commit 1bd7a7596b
4 changed files with 32 additions and 9 deletions
src/test/java/org/jetbrains/plugins/ideavim/ex
implementation/functions/bitwiseFunctions
parser/expressions
vim-engine/src/main
antlr
kotlin/com/maddyhome/idea/vim/vimscript/model/datatypes

View File

@ -22,8 +22,7 @@ class InvertFunctionTest : VimTestCase() {
@Test
fun `test invert function inverts bits`() {
// assertCommandOutput("echo invert(0b1010)", "-11")
assertCommandOutput("echo invert(10)", "-11")
assertCommandOutput("echo invert(0b1010)", "-11")
}
@Test

View File

@ -11,11 +11,12 @@ package org.jetbrains.plugins.ideavim.ex.parser.expressions
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFloat
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
import com.maddyhome.idea.vim.vimscript.parser.VimscriptParser
import org.jetbrains.plugins.ideavim.VimTestCase
import org.jetbrains.plugins.ideavim.ex.evaluate
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
class NumberParsingTests {
class NumberParsingTests : VimTestCase() {
@Test
fun `one digit decimal number`() {
@ -77,6 +78,26 @@ class NumberParsingTests {
assertEquals(VimInt(-24), VimscriptParser.parseExpression("-030")!!.evaluate())
}
@Test
fun `octal number with lowercase prefix`() {
assertEquals(VimInt(15), VimscriptParser.parseExpression("0o17")!!.evaluate())
}
@Test
fun `octal number with uppercase prefix`() {
assertEquals(VimInt(15), VimscriptParser.parseExpression("0O17")!!.evaluate())
}
@Test
fun `binary number with lowercase prefix`() {
assertEquals(VimInt(15), VimscriptParser.parseExpression("0b1111")!!.evaluate())
}
@Test
fun `binary number with uppercase prefix`() {
assertEquals(VimInt(15), VimscriptParser.parseExpression("0B1111")!!.evaluate())
}
@Test
fun `float number`() {
assertEquals(VimFloat(4.0), VimscriptParser.parseExpression("4.0")!!.evaluate())

View File

@ -718,6 +718,8 @@ TABMOVE: 'tabm' | 'tabmo' | 'tabmov' | 'tabmove';
// Types
DIGIT: [0-9];
INT: [0-9]+
| '0'[bB][0-1]+
| '0'[oO][0-7]+
| '0'[xX][0-9a-fA-F]+;
FLOAT: [0-9]+'.'[0-9]+
| [0-9]+'.'[0-9]+'e'[+-]?[0-9]+

View File

@ -12,7 +12,7 @@ import java.util.*
data class VimInt(val value: Int) : VimDataType() {
constructor(octalDecimalOrHexNumber: String) : this(parseNumber(octalDecimalOrHexNumber) ?: 0)
constructor(binaryOctalDecimalOrHexNumber: String) : this(parseNumber(binaryOctalDecimalOrHexNumber) ?: 0)
override fun asDouble(): Double {
return value.toDouble()
@ -49,12 +49,13 @@ data class VimInt(val value: Int) : VimDataType() {
}
}
fun parseNumber(octalDecimalOrHexNumber: String): Int? {
val n = octalDecimalOrHexNumber.lowercase(Locale.getDefault())
fun parseNumber(binaryOctalDecimalOrHexNumber: String): Int? {
val n = binaryOctalDecimalOrHexNumber.lowercase(Locale.getDefault())
return when {
n.matches(Regex("[-]?0[x][0-9a-f]+")) -> n.replaceFirst("0x", "").toInt(16)
n.matches(Regex("[-]?[0][0-7]+")) -> n.toInt(8)
n.matches(Regex("[-]?[0-9]+")) -> n.toInt()
n.matches(Regex("-?0x[0-9a-f]+")) -> n.replaceFirst("0x", "").toInt(16)
n.matches(Regex("-?0o?[0-7]+")) -> n.replaceFirst("0o", "").toInt(8)
n.matches(Regex("-?0b[0-1]+")) -> n.replaceFirst("0b", "").toInt(2)
n.matches(Regex("-?[0-9]+")) -> n.toInt()
else -> null
}
}