mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 07:08:48 +00:00
strings.split; strings.index; eprint* over print*_err;
This commit is contained in:
+12
-6
@@ -59,12 +59,18 @@ fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
|
|||||||
|
|
||||||
|
|
||||||
// print* procedures return the number of bytes written
|
// print* procedures return the number of bytes written
|
||||||
print :: proc(args: ..any) -> int { return fprint(context.stdout, ..args); }
|
print :: proc(args: ..any) -> int { return fprint(context.stdout, ..args); }
|
||||||
print_err :: proc(args: ..any) -> int { return fprint(context.stderr, ..args); }
|
println :: proc(args: ..any) -> int { return fprintln(context.stdout, ..args); }
|
||||||
println :: proc(args: ..any) -> int { return fprintln(context.stdout, ..args); }
|
printf :: proc(fmt: string, args: ..any) -> int { return fprintf(context.stdout, fmt, ..args); }
|
||||||
println_err :: proc(args: ..any) -> int { return fprintln(context.stderr, ..args); }
|
|
||||||
printf :: proc(fmt: string, args: ..any) -> int { return fprintf(context.stdout, fmt, ..args); }
|
eprint :: proc(args: ..any) -> int { return fprint(context.stderr, ..args); }
|
||||||
printf_err :: proc(fmt: string, args: ..any) -> int { return fprintf(context.stderr, fmt, ..args); }
|
eprintln :: proc(args: ..any) -> int { return fprintln(context.stderr, ..args); }
|
||||||
|
eprintf :: proc(fmt: string, args: ..any) -> int { return fprintf(context.stderr, fmt, ..args); }
|
||||||
|
|
||||||
|
|
||||||
|
@(deprecated="prefer eprint") print_err :: proc(args: ..any) -> int { return eprint(..args); }
|
||||||
|
@(deprecated="prefer eprintf") println_err :: proc(args: ..any) -> int { return eprintln(..args); }
|
||||||
|
@(deprecated="prefer eprintln") printf_err :: proc(fmt: string, args: ..any) -> int { return eprintf(fmt, ..args); }
|
||||||
|
|
||||||
|
|
||||||
// aprint* procedures return a string that was allocated with the current context
|
// aprint* procedures return a string that was allocated with the current context
|
||||||
|
|||||||
@@ -304,10 +304,8 @@ write_type :: proc(buf: ^strings.Builder, ti: ^rt.Type_Info) {
|
|||||||
write_byte(buf, info.signed ? 'i' : 'u');
|
write_byte(buf, info.signed ? 'i' : 'u');
|
||||||
write_i64(buf, i64(8*ti.size), 10);
|
write_i64(buf, i64(8*ti.size), 10);
|
||||||
switch info.endianness {
|
switch info.endianness {
|
||||||
case rt.Type_Info_Endianness.Little:
|
case .Little: write_string(buf, "le");
|
||||||
write_string(buf, "le");
|
case .Big: write_string(buf, "be");
|
||||||
case rt.Type_Info_Endianness.Big:
|
|
||||||
write_string(buf, "be");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case rt.Type_Info_Rune:
|
case rt.Type_Info_Rune:
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ Type_Info_Enum_Value :: union {
|
|||||||
u8, u16, u32, u64, uint, uintptr,
|
u8, u16, u32, u64, uint, uintptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
Type_Info_Endianness :: enum u8 {
|
Platform_Endianness :: enum u8 {
|
||||||
Platform = 0,
|
Platform = 0,
|
||||||
Little = 1,
|
Little = 1,
|
||||||
Big = 2,
|
Big = 2,
|
||||||
@@ -48,7 +48,7 @@ Type_Info_Endianness :: enum u8 {
|
|||||||
|
|
||||||
// Variant Types
|
// Variant Types
|
||||||
Type_Info_Named :: struct {name: string, base: ^Type_Info};
|
Type_Info_Named :: struct {name: string, base: ^Type_Info};
|
||||||
Type_Info_Integer :: struct {signed: bool, endianness: Type_Info_Endianness};
|
Type_Info_Integer :: struct {signed: bool, endianness: Platform_Endianness};
|
||||||
Type_Info_Rune :: struct {};
|
Type_Info_Rune :: struct {};
|
||||||
Type_Info_Float :: struct {};
|
Type_Info_Float :: struct {};
|
||||||
Type_Info_Complex :: struct {};
|
Type_Info_Complex :: struct {};
|
||||||
|
|||||||
@@ -205,7 +205,11 @@ itoa :: proc(buf: []byte, i: int) -> string {
|
|||||||
atoi :: proc(s: string) -> int {
|
atoi :: proc(s: string) -> int {
|
||||||
return parse_int(s);
|
return parse_int(s);
|
||||||
}
|
}
|
||||||
|
atof :: proc(s: string) -> f64 {
|
||||||
|
return parse_f64(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
ftoa :: append_float;
|
||||||
append_float :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> string {
|
append_float :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> string {
|
||||||
return string(generic_ftoa(buf, f, fmt, prec, bit_size));
|
return string(generic_ftoa(buf, f, fmt, prec, bit_size));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ grow_builder :: proc(b: ^Builder, cap: int) {
|
|||||||
reserve(&b.buf, cap);
|
reserve(&b.buf, cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset_builder :: proc(b: ^Builder) {
|
||||||
|
clear(&b.buf);
|
||||||
|
}
|
||||||
|
|
||||||
builder_from_slice :: proc(backing: []byte) -> Builder {
|
builder_from_slice :: proc(backing: []byte) -> Builder {
|
||||||
s := transmute(mem.Raw_Slice)backing;
|
s := transmute(mem.Raw_Slice)backing;
|
||||||
d := mem.Raw_Dynamic_Array{
|
d := mem.Raw_Dynamic_Array{
|
||||||
|
|||||||
+147
-3
@@ -155,6 +155,73 @@ concatenate :: proc(a: []string, allocator := context.allocator) -> string {
|
|||||||
return string(b);
|
return string(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@private
|
||||||
|
_split :: proc(s_, sep: string, sep_save, n_: int, allocator := context.allocator) -> []string {
|
||||||
|
s, n := s_, n_;
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if sep == "" {
|
||||||
|
l := utf8.rune_count_in_string(s);
|
||||||
|
if n < 0 || n > l {
|
||||||
|
n = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
res := make([dynamic]string, n);
|
||||||
|
for i := 0; i < n-1; i += 1 {
|
||||||
|
r, w := utf8.decode_rune_in_string(s);
|
||||||
|
res[i] = s[:w];
|
||||||
|
s = s[w:];
|
||||||
|
}
|
||||||
|
if n > 0 {
|
||||||
|
res[n-1] = s;
|
||||||
|
}
|
||||||
|
return res[:];
|
||||||
|
}
|
||||||
|
|
||||||
|
if n < 0 {
|
||||||
|
n = count(s, sep) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res := make([dynamic]string, n);
|
||||||
|
|
||||||
|
n -= 1;
|
||||||
|
|
||||||
|
i := 0;
|
||||||
|
for ; i < n; i += 1 {
|
||||||
|
m := index(s, sep);
|
||||||
|
if m < 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
res[i] = s[:m+sep_save];
|
||||||
|
s = s[m+len(sep):];
|
||||||
|
}
|
||||||
|
res[i] = s;
|
||||||
|
|
||||||
|
return res[:i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
split :: inline proc(s, sep: string, allocator := context.allocator) -> []string {
|
||||||
|
return _split(s, sep, 0, -1, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
split_n :: inline proc(s, sep: string, n: int, allocator := context.allocator) -> []string {
|
||||||
|
return _split(s, sep, 0, n, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
split_after :: inline proc(s, sep: string, allocator := context.allocator) -> []string {
|
||||||
|
return _split(s, sep, len(sep), -1, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
split_after_n :: inline proc(s, sep: string, n: int, allocator := context.allocator) -> []string {
|
||||||
|
return _split(s, sep, len(sep), n, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
index_byte :: proc(s: string, c: byte) -> int {
|
index_byte :: proc(s: string, c: byte) -> int {
|
||||||
for i := 0; i < len(s); i += 1 {
|
for i := 0; i < len(s); i += 1 {
|
||||||
if s[i] == c do return i;
|
if s[i] == c do return i;
|
||||||
@@ -170,7 +237,25 @@ last_index_byte :: proc(s: string, c: byte) -> int {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@private PRIME_RABIN_KARP :: 16777619;
|
||||||
|
|
||||||
index :: proc(s, substr: string) -> int {
|
index :: proc(s, substr: string) -> int {
|
||||||
|
hash_str_rabin_karp :: proc(s: string) -> (hash: u32 = 0, pow: u32 = 1) {
|
||||||
|
for i := 0; i < len(s); i += 1 {
|
||||||
|
hash = hash*PRIME_RABIN_KARP + u32(s[i]);
|
||||||
|
}
|
||||||
|
sq := u32(PRIME_RABIN_KARP);
|
||||||
|
for i := len(s); i > 0; i >>= 1 {
|
||||||
|
if (i & 1) != 0 {
|
||||||
|
pow *= sq;
|
||||||
|
}
|
||||||
|
sq *= sq;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
n := len(substr);
|
n := len(substr);
|
||||||
switch {
|
switch {
|
||||||
case n == 0:
|
case n == 0:
|
||||||
@@ -186,9 +271,68 @@ index :: proc(s, substr: string) -> int {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(s)-n+1; i += 1 {
|
hash, pow := hash_str_rabin_karp(substr);
|
||||||
x := s[i:i+n];
|
h: u32;
|
||||||
if x == substr {
|
for i := 0; i < n; i += 1 {
|
||||||
|
h = h*PRIME_RABIN_KARP + u32(s[i]);
|
||||||
|
}
|
||||||
|
if h == hash && s[:n] == substr {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for i := n; i < len(s); /**/ {
|
||||||
|
h *= PRIME_RABIN_KARP;
|
||||||
|
h += u32(s[i]);
|
||||||
|
h -= pow * u32(s[i-n]);
|
||||||
|
i += 1;
|
||||||
|
if h == hash && s[i-n:i] == substr {
|
||||||
|
return i - n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_index :: proc(s, substr: string) -> int {
|
||||||
|
hash_str_rabin_karp_reverse :: proc(s: string) -> (hash: u32 = 0, pow: u32 = 1) {
|
||||||
|
for i := len(s) - 1; i >= 0; i -= 1 {
|
||||||
|
hash = hash*PRIME_RABIN_KARP + u32(s[i]);
|
||||||
|
}
|
||||||
|
sq := u32(PRIME_RABIN_KARP);
|
||||||
|
for i := len(s); i > 0; i >>= 1 {
|
||||||
|
if (i & 1) != 0 {
|
||||||
|
pow *= sq;
|
||||||
|
}
|
||||||
|
sq *= sq;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n := len(substr);
|
||||||
|
switch {
|
||||||
|
case n == 0:
|
||||||
|
return len(s);
|
||||||
|
case n == 1:
|
||||||
|
return last_index_byte(s, substr[0]);
|
||||||
|
case n == len(s):
|
||||||
|
return substr == s ? 0 : -1;
|
||||||
|
case n > len(s):
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, pow := hash_str_rabin_karp_reverse(substr);
|
||||||
|
last := len(s) - n;
|
||||||
|
h: u32;
|
||||||
|
for i := len(s)-1; i >= last; i -= 1 {
|
||||||
|
h = h*PRIME_RABIN_KARP + u32(s[i]);
|
||||||
|
}
|
||||||
|
if h == hash && s[last:] == substr {
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := last-1; i >= 0; i -= 1 {
|
||||||
|
h *= PRIME_RABIN_KARP;
|
||||||
|
h += u32(s[i]);
|
||||||
|
h -= pow * u32(s[i+n]);
|
||||||
|
if h == hash && s[i:i+n] == substr {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -4,6 +4,7 @@ import "core:fmt"
|
|||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
import "core:reflect"
|
import "core:reflect"
|
||||||
|
import "core:strings"
|
||||||
import "intrinsics"
|
import "intrinsics"
|
||||||
|
|
||||||
when os.OS == "windows" {
|
when os.OS == "windows" {
|
||||||
@@ -1189,7 +1190,15 @@ where_clauses :: proc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
when true {
|
x := "foobarbaz";
|
||||||
|
i : int;
|
||||||
|
i = strings.last_index(x, "foo"); fmt.println(i);
|
||||||
|
i = strings.last_index(x, "bar"); fmt.println(i);
|
||||||
|
i = strings.last_index(x, "baz"); fmt.println(i);
|
||||||
|
i = strings.last_index(x, "asd"); fmt.println(i);
|
||||||
|
i = strings.last_index(x, "a"); fmt.println(i);
|
||||||
|
i = strings.last_index(x, "ba"); fmt.println(i);
|
||||||
|
when false {
|
||||||
general_stuff();
|
general_stuff();
|
||||||
union_type();
|
union_type();
|
||||||
parametric_polymorphism();
|
parametric_polymorphism();
|
||||||
@@ -1212,3 +1221,4 @@ main :: proc() {
|
|||||||
where_clauses();
|
where_clauses();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ TargetEndianKind target_endians[TargetArch_COUNT] = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
String const ODIN_VERSION = str_lit("0.10.1");
|
String const ODIN_VERSION = str_lit("0.10.2");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user