Files
kraken/stdlib/string.krak

267 lines
7.3 KiB
Plaintext
Raw Normal View History

import vector
import util
import mem
import serialize
import io
ext fun snprintf(to_str: *char, num: ulong, format: *char, ...): int
fun to_string(in: float): string
return to_string((in) cast double)
fun to_string(in: double): string {
var how_much = snprintf(mem::null<char>(), (0) cast ulong, "%f", in)
var int_str = mem::new<char>(how_much+2)
snprintf(int_str, (how_much+1) cast ulong, "%f", in)
var to_ret = string(int_str)
mem::delete(int_str)
return to_ret
}
fun to_string(in: bool): string
if (in) return string("true")
else return string("false")
fun to_string(in: char): string
return string(in)
fun to_string(in: uchar): string
return to_string_num(in)
fun to_string(in: short): string
return to_string_num(in)
fun to_string(in: ushort): string
return to_string_num(in)
fun to_string(in: int): string
return to_string_num(in)
fun to_string(in: uint): string
return to_string_num(in)
fun to_string(in: long): string
return to_string_num(in)
fun to_string(in: ulong): string
return to_string_num(in)
fun to_string<T>(in: *T): string
return string("ptr:<") + to_string_num((in) cast ulong) + ">"
fun string_to_int(it: string): int {
var is_negative = false
if (it[0] == '-') {
is_negative = true
it = it.slice(1,-1)
}
var result = 0
var power = 1
while (it.length()) {
result += power * (it.last() - '0')
it = it.slice(0,-2)
power *= 10
}
if (is_negative)
return -result
return result
}
fun string_to_double(it: string): double {
var parts = it.split('.')
var divisor = 1
for (var i = 0; i < parts[1].length(); i++;) divisor *= 10
return string_to_int(parts[0]) + (string_to_int(parts[1])) cast double / divisor
}
fun to_string_num<T>(in: T): string {
if (in == 0)
return string("0")
var ret = string()
var pos = 0
var is_neg = false
if (in > 0) {
pos = in
} else {
pos = -in
is_neg = true
}
while (pos) {
ret = string((pos%10 + '0') cast char) + ret
pos = pos / 10
}
if (is_neg)
return string("-") + ret
return ret
}
fun operator+(first: *char, second: ref string): string {
return string(first) + second
}
fun string(in:*char):string {
var out.construct(in):string
return out
}
fun string(in:char):string {
var out.construct():string
out += in
return out
}
fun string():string {
return string("")
}
obj string (Object, Serializable) {
var data: vector::vector<char>;
fun construct(): *string {
data.construct();
return this;
}
fun construct(str: *char): *string {
2016-06-11 00:45:18 -07:00
var len = 0
while (str[len] != 0) len++
data.construct(len);
data.set_size(len);
mem::memmove((data.getBackingMemory()) cast *void, (str) cast *void, (len) cast ulong)
// no null terminator
return this;
}
fun construct(vec: ref vector::vector<char>): *string {
data.copy_construct(&vec);
return this;
}
fun construct(str: ref string): *string {
return construct(str.data);
}
fun copy_construct(old: *string): void {
data.copy_construct(&old->data)
}
fun copy_construct(old: **char): void {
construct(*old)
}
fun operator=(str: *char): void {
destruct();
construct(str)
}
fun operator=(str: ref string): void {
2016-05-05 04:51:10 -04:00
data = str.data
}
fun destruct():void {
data.destruct()
}
fun serialize(): vector::vector<char> {
return serialize::serialize(data)
}
fun unserialize(it: ref vector::vector<char>, pos: int): int {
/*construct()*/
/*util::unpack(data, pos) = serialize::unserialize<vector::vector<char>>(it, pos)*/
return data.unserialize(it, pos)
}
fun operator[](index: int): ref char { return data[index]; }
fun slice(first: int, second: int): string {
var new.construct(data.slice(first,second)): string
return new
}
fun set(index: int, toSet: char) {
data.set(index, toSet)
}
fun length():int { return data.size; }
2015-12-06 15:15:33 -05:00
fun operator!=(other: ref string): bool return !(*this ==other)
fun operator!=(other: *char): bool return !(*this==other)
fun operator==(other: ref string): bool {
// you were too good for this world
//return length() == other.length() && !util::range(length()).any_true(fun(i: int):bool { return data[i] != other[i]; } )
if (data.size != other.data.size)
return false
for (var i = 0; i < data.size; i++;)
if (data.data[i] != other.data.data[i])
return false
return true
}
2015-07-05 02:34:45 -04:00
fun operator==(other: *char): bool {
var str.construct(other) : string
return *this == str
}
fun operator+(integer: int): string return *this + to_string(integer);
2016-06-16 09:53:15 -07:00
/*fun operator+(b: bool): string return *this + to_string(b);*/
fun operator+(str: *char): string {
var newStr.construct(str):string
var ret.construct(data + newStr.data):string
return ret
}
fun operator+(str: ref string): string {
2016-05-05 04:51:10 -04:00
var ret.construct(data + str.data):string
return ret
}
fun operator+=(integer: int) *this += to_string(integer);
2016-06-16 09:53:15 -07:00
/*fun operator+=(b: bool) *this += to_string(b);*/
fun operator+=(character: char): void {
data += character
}
fun operator+=(str: *char): void {
var newStr.construct(str):string
data += newStr.data
}
fun operator+=(str: ref string): void {
//var newStr.construct(str):string
//data += newStr.data
data += str.data
}
fun toCharArray(): *char {
var out: *char = mem::new<char>(data.size+1);
for (var i: int = 0; i < data.size; i++;)
out[i] = data.get(i);
// null terminator
out[data.size] = 0
return out;
}
fun getBackingMemory(): *char return data.getBackingMemory();
fun split(delim: *char): vector::vector<string> return split(string(delim))
fun split(delim: string): vector::vector<string> {
var out.construct(): vector::vector<string>
var current = string("")
for (var i = 0; i < data.size; i++;) {
if (i < data.size-delim.length() && slice(i, i+delim.length()) == delim) {
out.add(current)
current = string("")
i += delim.length()-1
} else {
current += data[i]
}
}
out.add(current)
return out
}
fun last(): char return data.last()
fun lines(): vector::vector<string> return split('\n')
fun split(delim: char): vector::vector<string> {
var out.construct(): vector::vector<string>
var current = string("")
for (var i = 0; i < data.size; i++;) {
if (data[i] == delim) {
out.add(current)
current = string("")
} else {
current += data[i]
}
}
out.add(current)
return out
}
2016-05-05 04:51:10 -04:00
fun join(to_join: ref vector::vector<string>): string {
var to_ret = to_join.first()
for (var i = 1; i < to_join.size; i++;)
to_ret += *this + to_join[i]
return to_ret
}
fun for_each(func: fun(char):void) {
data.for_each(func)
}
};