strings.split; strings.index; eprint* over print*_err;

This commit is contained in:
gingerBill
2019-10-06 18:13:15 +01:00
parent e1b711b3b3
commit 4e8a801b35
8 changed files with 183 additions and 17 deletions

View File

@@ -59,12 +59,18 @@ fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
// print* procedures return the number of bytes written
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_err :: proc(args: ..any) -> int { return fprintln(context.stderr, ..args); }
printf :: proc(fmt: string, args: ..any) -> int { return fprintf(context.stdout, fmt, ..args); }
printf_err :: proc(fmt: string, args: ..any) -> int { return fprintf(context.stderr, fmt, ..args); }
print :: proc(args: ..any) -> int { return fprint(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); }
eprint :: proc(args: ..any) -> int { return fprint(context.stderr, ..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

View File

@@ -304,10 +304,8 @@ write_type :: proc(buf: ^strings.Builder, ti: ^rt.Type_Info) {
write_byte(buf, info.signed ? 'i' : 'u');
write_i64(buf, i64(8*ti.size), 10);
switch info.endianness {
case rt.Type_Info_Endianness.Little:
write_string(buf, "le");
case rt.Type_Info_Endianness.Big:
write_string(buf, "be");
case .Little: write_string(buf, "le");
case .Big: write_string(buf, "be");
}
}
case rt.Type_Info_Rune:

View File

@@ -40,7 +40,7 @@ Type_Info_Enum_Value :: union {
u8, u16, u32, u64, uint, uintptr,
};
Type_Info_Endianness :: enum u8 {
Platform_Endianness :: enum u8 {
Platform = 0,
Little = 1,
Big = 2,
@@ -48,7 +48,7 @@ Type_Info_Endianness :: enum u8 {
// Variant Types
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_Float :: struct {};
Type_Info_Complex :: struct {};

View File

@@ -205,7 +205,11 @@ itoa :: proc(buf: []byte, i: int) -> string {
atoi :: proc(s: string) -> int {
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 {
return string(generic_ftoa(buf, f, fmt, prec, bit_size));
}

View File

@@ -21,6 +21,10 @@ grow_builder :: proc(b: ^Builder, cap: int) {
reserve(&b.buf, cap);
}
reset_builder :: proc(b: ^Builder) {
clear(&b.buf);
}
builder_from_slice :: proc(backing: []byte) -> Builder {
s := transmute(mem.Raw_Slice)backing;
d := mem.Raw_Dynamic_Array{

View File

@@ -155,6 +155,73 @@ concatenate :: proc(a: []string, allocator := context.allocator) -> string {
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 {
for i := 0; i < len(s); i += 1 {
if s[i] == c do return i;
@@ -170,7 +237,25 @@ last_index_byte :: proc(s: string, c: byte) -> int {
return -1;
}
@private PRIME_RABIN_KARP :: 16777619;
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);
switch {
case n == 0:
@@ -186,9 +271,68 @@ index :: proc(s, substr: string) -> int {
return -1;
}
for i := 0; i < len(s)-n+1; i += 1 {
x := s[i:i+n];
if x == substr {
hash, pow := hash_str_rabin_karp(substr);
h: u32;
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;
}
}

View File

@@ -4,6 +4,7 @@ import "core:fmt"
import "core:mem"
import "core:os"
import "core:reflect"
import "core:strings"
import "intrinsics"
when os.OS == "windows" {
@@ -1189,7 +1190,15 @@ where_clauses :: 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();
union_type();
parametric_polymorphism();
@@ -1212,3 +1221,4 @@ main :: proc() {
where_clauses();
}
}

View File

@@ -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");