226 lines
5.6 KiB
Plaintext
226 lines
5.6 KiB
Plaintext
|
|
extern fn puts(message: *char) -> i32;
|
|
extern fn free(ptr: *u8);
|
|
extern fn div(numerator: i32, denominator: i32) -> div_t;
|
|
|
|
struct String {
|
|
inner: *char,
|
|
length: u64,
|
|
max_length: u64,
|
|
must_be_freed: bool,
|
|
}
|
|
|
|
impl String {
|
|
pub fn new() -> String {
|
|
String {
|
|
inner: char::alloca(0),
|
|
length: 0,
|
|
max_length: 0,
|
|
must_be_freed: true,
|
|
}
|
|
}
|
|
|
|
pub fn from(str: *char) -> String {
|
|
let length = str_length(str) as u64;
|
|
let mut new = String::new();
|
|
let static = String {
|
|
inner: str,
|
|
length: length - 1,
|
|
max_length: length,
|
|
must_be_freed: false,
|
|
};
|
|
concat_strings(&mut new, static);
|
|
return new;
|
|
}
|
|
|
|
pub fn push(&mut self, other: String) {
|
|
for i in 0 .. (str_length(other.inner) - 1) {
|
|
add_char(self, other.inner[i]);
|
|
}
|
|
}
|
|
|
|
pub fn add_char(&mut self, c: char) {
|
|
if ((*self).length + 1) >= (*self).max_length {
|
|
let new = char::alloca((*self).max_length + 4);
|
|
copy_bits((*self).inner, new, (*self).max_length);
|
|
|
|
if (*self).must_be_freed == true {
|
|
free((*self).inner as *u8);
|
|
}
|
|
(*self).max_length = (*self).max_length + 4;
|
|
(*self).inner = new;
|
|
(*self).must_be_freed = true;
|
|
}
|
|
|
|
(*self).inner[(*self).length] = c;
|
|
(((*self).inner) as *u8)[(*self).length + 1] = 0;
|
|
(*self).length = (*self).length + 1;
|
|
}
|
|
|
|
pub fn push_num(&mut self, num: u64) {
|
|
if num >= 10 {
|
|
self.push_num(num / 10)
|
|
}
|
|
let rem = num % 10;
|
|
|
|
if rem == 0 { self.add_char('0'); }
|
|
else if rem == 1 { self.add_char('1'); }
|
|
else if rem == 2 { self.add_char('2'); }
|
|
else if rem == 3 { self.add_char('3'); }
|
|
else if rem == 4 { self.add_char('4'); }
|
|
else if rem == 5 { self.add_char('5'); }
|
|
else if rem == 6 { self.add_char('6'); }
|
|
else if rem == 7 { self.add_char('7'); }
|
|
else if rem == 8 { self.add_char('8'); }
|
|
else if rem == 9 { self.add_char('9'); }
|
|
}
|
|
|
|
pub fn concat(&mut self, other: &String) {
|
|
for i in 0 .. *other.length {
|
|
self.add_char(*other.inner[i]);
|
|
}
|
|
}
|
|
|
|
pub fn set(&mut self, c: char, position: u64) {
|
|
if position <= (*self).length {
|
|
(*self).inner[position] = c;
|
|
}
|
|
}
|
|
|
|
pub fn free(&self) {
|
|
free((*self).inner as *u8);
|
|
}
|
|
}
|
|
|
|
impl binop (lhs: String) + (rhs: *char) -> String {
|
|
let mut new = lhs;
|
|
let added = from_str(rhs);
|
|
concat_strings(&mut new, added);
|
|
free_string(&added);
|
|
return new;
|
|
}
|
|
|
|
impl binop (lhs: String) + (rhs: u64) -> String {
|
|
let mut new = lhs;
|
|
add_num_to_str(&mut new, rhs);
|
|
return new;
|
|
}
|
|
|
|
struct div_t {
|
|
quotient: i32,
|
|
remainder: i32,
|
|
}
|
|
|
|
pub fn print(message: String) {
|
|
puts(message.inner);
|
|
}
|
|
|
|
pub fn int_div(numerator: i32, denominator: i32) -> div_t {
|
|
return div(numerator, denominator);
|
|
}
|
|
|
|
pub fn new_string() -> String {
|
|
String {
|
|
inner: char::alloca(0),
|
|
length: 0,
|
|
max_length: 0,
|
|
must_be_freed: true,
|
|
}
|
|
}
|
|
|
|
pub fn from_str(str: *char) -> String {
|
|
let length = str_length(str) as u64;
|
|
let mut new = new_string();
|
|
let static = String {
|
|
inner: str,
|
|
length: length - 1,
|
|
max_length: length,
|
|
must_be_freed: false,
|
|
};
|
|
concat_strings(&mut new, static);
|
|
return new;
|
|
}
|
|
|
|
pub fn add_char(string: &mut String, c: char) {
|
|
if ((*string).length + 1) >= (*string).max_length {
|
|
let new = char::alloca((*string).max_length + 4);
|
|
copy_bits((*string).inner, new, (*string).max_length);
|
|
|
|
if (*string).must_be_freed == true {
|
|
free((*string).inner as *u8);
|
|
}
|
|
(*string).max_length = (*string).max_length + 4;
|
|
(*string).inner = new;
|
|
(*string).must_be_freed = true;
|
|
}
|
|
|
|
(*string).inner[(*string).length] = c;
|
|
(((*string).inner) as *u8)[(*string).length + 1] = 0;
|
|
(*string).length = (*string).length + 1;
|
|
}
|
|
|
|
pub fn set_char(string: &mut String, c: char, position: u64) {
|
|
if position <= (*string).length {
|
|
(*string).inner[position] = c;
|
|
}
|
|
}
|
|
|
|
pub fn free_string(string: &String) {
|
|
free((*string).inner as *u8);
|
|
}
|
|
|
|
fn copy_bits(from: *char, to: *char, length: u64) {
|
|
for i in 0 .. length {
|
|
to[i] = from[i];
|
|
}
|
|
}
|
|
|
|
fn str_length(string: *char) -> u32 {
|
|
let mut pos = 0;
|
|
while ((string[pos] == '\0') == false) {
|
|
pos = pos + 1;
|
|
}
|
|
return pos + 1;
|
|
}
|
|
|
|
pub fn add_num_to_str(string: &mut String, num: u64) {
|
|
if num >= 10 {
|
|
add_num_to_str(string, num / 10)
|
|
}
|
|
let rem = num % 10;
|
|
|
|
if rem == 0 { add_char(string, '0'); }
|
|
else if rem == 1 { add_char(string, '1'); }
|
|
else if rem == 2 { add_char(string, '2'); }
|
|
else if rem == 3 { add_char(string, '3'); }
|
|
else if rem == 4 { add_char(string, '4'); }
|
|
else if rem == 5 { add_char(string, '5'); }
|
|
else if rem == 6 { add_char(string, '6'); }
|
|
else if rem == 7 { add_char(string, '7'); }
|
|
else if rem == 8 { add_char(string, '8'); }
|
|
else if rem == 9 { add_char(string, '9'); }
|
|
}
|
|
|
|
pub fn concat_strings(destination: &mut String, source: String) {
|
|
for i in 0 .. (str_length(source.inner) - 1) {
|
|
add_char(destination, source.inner[i]);
|
|
}
|
|
}
|
|
|
|
pub fn clamp(min: f32, max: f32, value: f32) -> f32 {
|
|
if value > max {
|
|
return max;
|
|
}
|
|
if value < min {
|
|
return min;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
pub fn abs(f: f32) -> f32 {
|
|
if f < 0.0 {
|
|
return f * (0.0 - 1.0);
|
|
}
|
|
return f;
|
|
}
|