mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-02 03:02:31 +00:00
Add a more number parsers to the scanf macro (#6985)
This commit is contained in:
committed by
Andreas Rumpf
parent
6cf8a72d49
commit
6ca563dd2e
@@ -87,6 +87,23 @@ proc parseOct*(s: string, number: var int, start = 0): int {.
|
||||
inc(i)
|
||||
if foundDigit: result = i-start
|
||||
|
||||
proc parseBin*(s: string, number: var int, start = 0): int {.
|
||||
rtl, extern: "npuParseBin", noSideEffect.} =
|
||||
## parses an binary number and stores its value in ``number``. Returns
|
||||
## the number of the parsed characters or 0 in case of an error.
|
||||
var i = start
|
||||
var foundDigit = false
|
||||
if s[i] == '0' and (s[i+1] == 'b' or s[i+1] == 'B'): inc(i, 2)
|
||||
while true:
|
||||
case s[i]
|
||||
of '_': discard
|
||||
of '0'..'1':
|
||||
number = number shl 1 or (ord(s[i]) - ord('0'))
|
||||
foundDigit = true
|
||||
else: break
|
||||
inc(i)
|
||||
if foundDigit: result = i-start
|
||||
|
||||
proc parseIdent*(s: string, ident: var string, start = 0): int =
|
||||
## parses an identifier and stores it in ``ident``. Returns
|
||||
## the number of the parsed characters or 0 in case of an error.
|
||||
|
||||
@@ -31,7 +31,10 @@ As can be seen from the examples, strings are matched verbatim except for
|
||||
substrings starting with ``$``. These constructions are available:
|
||||
|
||||
================= ========================================================
|
||||
``$i`` Matches an integer. This uses ``parseutils.parseInt``.
|
||||
``$b`` Matches an decimal integer. This uses ``parseutils.parseBin``.
|
||||
``$o`` Matches an octal integer. This uses ``parseutils.parseOct``.
|
||||
``$i`` Matches an decimal integer. This uses ``parseutils.parseInt``.
|
||||
``$h`` Matches an hex integer. This uses ``parseutils.parseHex``.
|
||||
``$f`` Matches a floating pointer number. Uses ``parseFloat``.
|
||||
``$w`` Matches an ASCII identifier: ``[A-Z-a-z_][A-Za-z_0-9]*``.
|
||||
``$s`` Skips optional whitespace.
|
||||
@@ -335,11 +338,29 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
|
||||
else:
|
||||
error("no string var given for $w")
|
||||
inc i
|
||||
of 'b':
|
||||
if i < results.len or getType(results[i]).typeKind != ntyInt:
|
||||
matchBind "parseBin"
|
||||
else:
|
||||
error("no int var given for $b")
|
||||
inc i
|
||||
of 'o':
|
||||
if i < results.len or getType(results[i]).typeKind != ntyInt:
|
||||
matchBind "parseOct"
|
||||
else:
|
||||
error("no int var given for $o")
|
||||
inc i
|
||||
of 'i':
|
||||
if i < results.len or getType(results[i]).typeKind != ntyInt:
|
||||
matchBind "parseInt"
|
||||
else:
|
||||
error("no int var given for $d")
|
||||
error("no int var given for $i")
|
||||
inc i
|
||||
of 'h':
|
||||
if i < results.len or getType(results[i]).typeKind != ntyInt:
|
||||
matchBind "parseHex"
|
||||
else:
|
||||
error("no int var given for $h")
|
||||
inc i
|
||||
of 'f':
|
||||
if i < results.len or getType(results[i]).typeKind != ntyFloat:
|
||||
@@ -645,6 +666,14 @@ when isMainModule:
|
||||
doAssert intval == 89
|
||||
doAssert floatVal == 33.25
|
||||
|
||||
var binval: int
|
||||
var octval: int
|
||||
var hexval: int
|
||||
doAssert scanf("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binval, octval, hexval)
|
||||
doAssert binval == 0b0101
|
||||
doAssert octval == 0o1234
|
||||
doAssert hexval == 0xabcd
|
||||
|
||||
let xx = scanf("$abc", "$$$i", intval)
|
||||
doAssert xx == false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user