mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Add parse_complex/quaternion* to core:strconv
This commit is contained in:
@@ -1124,6 +1124,275 @@ parse_f64_prefix :: proc(str: string) -> (value: f64, nr: int, ok: bool) {
|
|||||||
ok = !overflow
|
ok = !overflow
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Parses a 128-bit complex number from a string
|
||||||
|
|
||||||
|
**Inputs**
|
||||||
|
- str: The input string containing a 128-bit complex number.
|
||||||
|
- n: An optional pointer to an int to store the length of the parsed substring (default: nil).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strconv"
|
||||||
|
parse_complex128_example :: proc() {
|
||||||
|
n: int
|
||||||
|
c, ok := strconv.parse_complex128("3+1i", &n)
|
||||||
|
fmt.printfln("%v %i %t", c, n, ok)
|
||||||
|
|
||||||
|
c, ok = strconv.parse_complex128("5+7i hellope", &n)
|
||||||
|
fmt.printfln("%v %i %t", c, n, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
3+1i 4 true
|
||||||
|
5+7i 4 false
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
- value: The parsed 128-bit complex number.
|
||||||
|
- ok: `false` if a complex number could not be found, or if the input string contained more than just the number.
|
||||||
|
*/
|
||||||
|
parse_complex128 :: proc(str: string, n: ^int = nil) -> (value: complex128, ok: bool) {
|
||||||
|
real_value, imag_value: f64
|
||||||
|
nr_r, nr_i: int
|
||||||
|
|
||||||
|
real_value, nr_r, _ = parse_f64_prefix(str)
|
||||||
|
imag_value, nr_i, _ = parse_f64_prefix(str[nr_r:])
|
||||||
|
|
||||||
|
i_parsed := len(str) >= nr_r + nr_i + 1 && str[nr_r + nr_i] == 'i'
|
||||||
|
if !i_parsed {
|
||||||
|
// No `i` means we refuse to treat the second float we parsed as an
|
||||||
|
// imaginary value.
|
||||||
|
imag_value = 0
|
||||||
|
nr_i = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = i_parsed && len(str) == nr_r + nr_i + 1
|
||||||
|
|
||||||
|
if n != nil {
|
||||||
|
n^ = nr_r + nr_i + (1 if i_parsed else 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
value = complex(real_value, imag_value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Parses a 64-bit complex number from a string
|
||||||
|
|
||||||
|
**Inputs**
|
||||||
|
- str: The input string containing a 64-bit complex number.
|
||||||
|
- n: An optional pointer to an int to store the length of the parsed substring (default: nil).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strconv"
|
||||||
|
parse_complex64_example :: proc() {
|
||||||
|
n: int
|
||||||
|
c, ok := strconv.parse_complex64("3+1i", &n)
|
||||||
|
fmt.printfln("%v %i %t", c, n, ok)
|
||||||
|
|
||||||
|
c, ok = strconv.parse_complex64("5+7i hellope", &n)
|
||||||
|
fmt.printfln("%v %i %t", c, n, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
3+1i 4 true
|
||||||
|
5+7i 4 false
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
- value: The parsed 64-bit complex number.
|
||||||
|
- ok: `false` if a complex number could not be found, or if the input string contained more than just the number.
|
||||||
|
*/
|
||||||
|
parse_complex64 :: proc(str: string, n: ^int = nil) -> (value: complex64, ok: bool) {
|
||||||
|
v: complex128 = ---
|
||||||
|
v, ok = parse_complex128(str, n)
|
||||||
|
return cast(complex64)v, ok
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Parses a 32-bit complex number from a string
|
||||||
|
|
||||||
|
**Inputs**
|
||||||
|
- str: The input string containing a 32-bit complex number.
|
||||||
|
- n: An optional pointer to an int to store the length of the parsed substring (default: nil).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strconv"
|
||||||
|
parse_complex32_example :: proc() {
|
||||||
|
n: int
|
||||||
|
c, ok := strconv.parse_complex32("3+1i", &n)
|
||||||
|
fmt.printfln("%v %i %t", c, n, ok)
|
||||||
|
|
||||||
|
c, ok = strconv.parse_complex32("5+7i hellope", &n)
|
||||||
|
fmt.printfln("%v %i %t", c, n, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
3+1i 4 true
|
||||||
|
5+7i 4 false
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
- value: The parsed 32-bit complex number.
|
||||||
|
- ok: `false` if a complex number could not be found, or if the input string contained more than just the number.
|
||||||
|
*/
|
||||||
|
parse_complex32 :: proc(str: string, n: ^int = nil) -> (value: complex32, ok: bool) {
|
||||||
|
v: complex128 = ---
|
||||||
|
v, ok = parse_complex128(str, n)
|
||||||
|
return cast(complex32)v, ok
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Parses a 256-bit quaternion from a string
|
||||||
|
|
||||||
|
**Inputs**
|
||||||
|
- str: The input string containing a 256-bit quaternion.
|
||||||
|
- n: An optional pointer to an int to store the length of the parsed substring (default: nil).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strconv"
|
||||||
|
parse_quaternion256_example :: proc() {
|
||||||
|
n: int
|
||||||
|
q, ok := strconv.parse_quaternion256("1+2i+3j+4k", &n)
|
||||||
|
fmt.printfln("%v %i %t", q, n, ok)
|
||||||
|
|
||||||
|
q, ok = strconv.parse_quaternion256("1+2i+3j+4k hellope", &n)
|
||||||
|
fmt.printfln("%v %i %t", q, n, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
1+2i+3j+4k 10 true
|
||||||
|
1+2i+3j+4k 10 false
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
- value: The parsed 256-bit quaternion.
|
||||||
|
- ok: `false` if a quaternion could not be found, or if the input string contained more than just the quaternion.
|
||||||
|
*/
|
||||||
|
parse_quaternion256 :: proc(str: string, n: ^int = nil) -> (value: quaternion256, ok: bool) {
|
||||||
|
iterate_and_assign :: proc (iter: ^string, terminator: byte, nr_total: ^int, state: bool) -> (value: f64, ok: bool) {
|
||||||
|
if !state {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nr: int
|
||||||
|
value, nr, _ = parse_f64_prefix(iter^)
|
||||||
|
iter^ = iter[nr:]
|
||||||
|
|
||||||
|
if len(iter) > 0 && iter[0] == terminator {
|
||||||
|
iter^ = iter[1:]
|
||||||
|
nr_total^ += nr + 1
|
||||||
|
ok = true
|
||||||
|
} else {
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
real_value, imag_value, jmag_value, kmag_value: f64
|
||||||
|
nr: int
|
||||||
|
|
||||||
|
real_value, nr, _ = parse_f64_prefix(str)
|
||||||
|
iter := str[nr:]
|
||||||
|
|
||||||
|
// Need to have parsed at least something in order to get started.
|
||||||
|
ok = nr > 0
|
||||||
|
|
||||||
|
// Quaternion parsing is done this way to honour the rest of the API with
|
||||||
|
// regards to partial parsing. Otherwise, we could error out early.
|
||||||
|
imag_value, ok = iterate_and_assign(&iter, 'i', &nr, ok)
|
||||||
|
jmag_value, ok = iterate_and_assign(&iter, 'j', &nr, ok)
|
||||||
|
kmag_value, ok = iterate_and_assign(&iter, 'k', &nr, ok)
|
||||||
|
|
||||||
|
if len(iter) != 0 {
|
||||||
|
ok = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if n != nil {
|
||||||
|
n^ = nr
|
||||||
|
}
|
||||||
|
|
||||||
|
value = quaternion(
|
||||||
|
real = real_value,
|
||||||
|
imag = imag_value,
|
||||||
|
jmag = jmag_value,
|
||||||
|
kmag = kmag_value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Parses a 128-bit quaternion from a string
|
||||||
|
|
||||||
|
**Inputs**
|
||||||
|
- str: The input string containing a 128-bit quaternion.
|
||||||
|
- n: An optional pointer to an int to store the length of the parsed substring (default: nil).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strconv"
|
||||||
|
parse_quaternion128_example :: proc() {
|
||||||
|
n: int
|
||||||
|
q, ok := strconv.parse_quaternion128("1+2i+3j+4k", &n)
|
||||||
|
fmt.printfln("%v %i %t", q, n, ok)
|
||||||
|
|
||||||
|
q, ok = strconv.parse_quaternion128("1+2i+3j+4k hellope", &n)
|
||||||
|
fmt.printfln("%v %i %t", q, n, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
1+2i+3j+4k 10 true
|
||||||
|
1+2i+3j+4k 10 false
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
- value: The parsed 128-bit quaternion.
|
||||||
|
- ok: `false` if a quaternion could not be found, or if the input string contained more than just the quaternion.
|
||||||
|
*/
|
||||||
|
parse_quaternion128 :: proc(str: string, n: ^int = nil) -> (value: quaternion128, ok: bool) {
|
||||||
|
v: quaternion256 = ---
|
||||||
|
v, ok = parse_quaternion256(str, n)
|
||||||
|
return cast(quaternion128)v, ok
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Parses a 64-bit quaternion from a string
|
||||||
|
|
||||||
|
**Inputs**
|
||||||
|
- str: The input string containing a 64-bit quaternion.
|
||||||
|
- n: An optional pointer to an int to store the length of the parsed substring (default: nil).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strconv"
|
||||||
|
parse_quaternion64_example :: proc() {
|
||||||
|
n: int
|
||||||
|
q, ok := strconv.parse_quaternion64("1+2i+3j+4k", &n)
|
||||||
|
fmt.printfln("%v %i %t", q, n, ok)
|
||||||
|
|
||||||
|
q, ok = strconv.parse_quaternion64("1+2i+3j+4k hellope", &n)
|
||||||
|
fmt.printfln("%v %i %t", q, n, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
1+2i+3j+4k 10 true
|
||||||
|
1+2i+3j+4k 10 false
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
- value: The parsed 64-bit quaternion.
|
||||||
|
- ok: `false` if a quaternion could not be found, or if the input string contained more than just the quaternion.
|
||||||
|
*/
|
||||||
|
parse_quaternion64 :: proc(str: string, n: ^int = nil) -> (value: quaternion64, ok: bool) {
|
||||||
|
v: quaternion256 = ---
|
||||||
|
v, ok = parse_quaternion256(str, n)
|
||||||
|
return cast(quaternion64)v, ok
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Appends a boolean value as a string to the given buffer
|
Appends a boolean value as a string to the given buffer
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user