Add core:unicode/utf8/utf8string to examples/all

This commit is contained in:
gingerBill
2022-03-18 23:32:37 +00:00
parent a68f0b2d72
commit ae6441182d
2 changed files with 62 additions and 60 deletions
+60 -60
View File
@@ -16,140 +16,140 @@ String :: struct {
} }
@(private) @(private)
_len :: builtin.len; // helper procedure _len :: builtin.len // helper procedure
init :: proc(s: ^String, contents: string) -> ^String { init :: proc(s: ^String, contents: string) -> ^String {
s.contents = contents; s.contents = contents
s.byte_pos = 0; s.byte_pos = 0
s.rune_pos = 0; s.rune_pos = 0
for i in 0..<_len(contents) { for i in 0..<_len(contents) {
if contents[i] >= utf8.RUNE_SELF { if contents[i] >= utf8.RUNE_SELF {
s.rune_count = utf8.rune_count_in_string(contents); s.rune_count = utf8.rune_count_in_string(contents)
_, s.width = utf8.decode_rune_in_string(contents); _, s.width = utf8.decode_rune_in_string(contents)
s.non_ascii = i; s.non_ascii = i
return s; return s
} }
} }
s.rune_count = _len(contents); s.rune_count = _len(contents)
s.width = 0; s.width = 0
s.non_ascii = _len(contents); s.non_ascii = _len(contents)
return s; return s
} }
to_string :: proc(s: ^String) -> string { to_string :: proc(s: ^String) -> string {
return s.contents; return s.contents
} }
len :: proc(s: ^String) -> int { len :: proc(s: ^String) -> int {
return s.rune_count; return s.rune_count
} }
is_ascii :: proc(s: ^String) -> bool { is_ascii :: proc(s: ^String) -> bool {
return s.width == 0; return s.width == 0
} }
at :: proc(s: ^String, i: int, loc := #caller_location) -> (r: rune) { at :: proc(s: ^String, i: int, loc := #caller_location) -> (r: rune) {
runtime.bounds_check_error_loc(loc, i, s.rune_count); runtime.bounds_check_error_loc(loc, i, s.rune_count)
if i < s.non_ascii { if i < s.non_ascii {
return rune(s.contents[i]); return rune(s.contents[i])
} }
switch i { switch i {
case 0: case 0:
r, s.width = utf8.decode_rune_in_string(s.contents); r, s.width = utf8.decode_rune_in_string(s.contents)
s.rune_pos = 0; s.rune_pos = 0
s.byte_pos = 0; s.byte_pos = 0
return; return
case s.rune_count-1: case s.rune_count-1:
r, s.width = utf8.decode_rune_in_string(s.contents); r, s.width = utf8.decode_rune_in_string(s.contents)
s.rune_pos = i; s.rune_pos = i
s.byte_pos = _len(s.contents) - s.width; s.byte_pos = _len(s.contents) - s.width
return; return
case s.rune_pos-1: case s.rune_pos-1:
r, s.width = utf8.decode_rune_in_string(s.contents[0:s.byte_pos]); r, s.width = utf8.decode_rune_in_string(s.contents[0:s.byte_pos])
s.rune_pos = i; s.rune_pos = i
s.byte_pos -= s.width; s.byte_pos -= s.width
return; return
case s.rune_pos+1: case s.rune_pos+1:
s.rune_pos = i; s.rune_pos = i
s.byte_pos += s.width; s.byte_pos += s.width
fallthrough; fallthrough
case s.rune_pos: case s.rune_pos:
r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]); r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:])
return; return
} }
// Linear scan // Linear scan
scan_forward := true; scan_forward := true
if i < s.rune_pos { if i < s.rune_pos {
if i < (s.rune_pos-s.non_ascii)/2 { if i < (s.rune_pos-s.non_ascii)/2 {
s.byte_pos, s.rune_pos = s.non_ascii, s.non_ascii; s.byte_pos, s.rune_pos = s.non_ascii, s.non_ascii
} else { } else {
scan_forward = false; scan_forward = false
} }
} else if i-s.rune_pos < (s.rune_count-s.rune_pos)/2 { } else if i-s.rune_pos < (s.rune_count-s.rune_pos)/2 {
// scan_forward = true; // scan_forward = true
} else { } else {
s.byte_pos, s.rune_pos = _len(s.contents), s.rune_count; s.byte_pos, s.rune_pos = _len(s.contents), s.rune_count
scan_forward = false; scan_forward = false
} }
if scan_forward { if scan_forward {
for { for {
r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]); r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:])
if s.rune_pos == i { if s.rune_pos == i {
return; return
} }
s.rune_pos += 1; s.rune_pos += 1
s.byte_pos += s.width; s.byte_pos += s.width
} }
} else { } else {
for { for {
r, s.width = utf8.decode_last_rune_in_string(s.contents[:s.byte_pos]); r, s.width = utf8.decode_last_rune_in_string(s.contents[:s.byte_pos])
s.rune_pos -= 1; s.rune_pos -= 1
s.byte_pos -= s.width; s.byte_pos -= s.width
if s.rune_pos == i { if s.rune_pos == i {
return; return
} }
} }
} }
} }
slice :: proc(s: ^String, i, j: int, loc := #caller_location) -> string { slice :: proc(s: ^String, i, j: int, loc := #caller_location) -> string {
runtime.slice_expr_error_lo_hi_loc(loc, i, j, s.rune_count); runtime.slice_expr_error_lo_hi_loc(loc, i, j, s.rune_count)
if j < s.non_ascii { if j < s.non_ascii {
return s.contents[i:j]; return s.contents[i:j]
} }
if i == j { if i == j {
return ""; return ""
} }
lo, hi: int; lo, hi: int
if i < s.non_ascii { if i < s.non_ascii {
lo = i; lo = i
} else if i == s.rune_count { } else if i == s.rune_count {
lo = _len(s.contents); lo = _len(s.contents)
} else { } else {
at(s, i, loc); at(s, i, loc)
lo = s.byte_pos; lo = s.byte_pos
} }
if j == s.rune_count { if j == s.rune_count {
hi = _len(s.contents); hi = _len(s.contents)
} else { } else {
at(s, j, loc); at(s, j, loc)
hi = s.byte_pos; hi = s.byte_pos
} }
return s.contents[lo:hi]; return s.contents[lo:hi]
} }
+2
View File
@@ -104,6 +104,7 @@ import time "core:time"
import unicode "core:unicode" import unicode "core:unicode"
import utf8 "core:unicode/utf8" import utf8 "core:unicode/utf8"
import utf8string "core:unicode/utf8/utf8string"
import utf16 "core:unicode/utf16" import utf16 "core:unicode/utf16"
main :: proc(){} main :: proc(){}
@@ -193,4 +194,5 @@ _ :: thread
_ :: time _ :: time
_ :: unicode _ :: unicode
_ :: utf8 _ :: utf8
_ :: utf8string
_ :: utf16 _ :: utf16