mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-14 23:33:15 +00:00
Merge pull request #3677 from Feoramund/parse-compquat
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
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user