aboutsummaryrefslogtreecommitdiff
path: root/code/lib/string.felan
blob: 789b0fbf50f8ab46c4a44f76c5ad8a7820ced26e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
@import("operator.felan");
@import("io.felan");
@import("types.felan");
@import("memory.felan");

String :: struct {
  ptr : *u8;
  size : u64;
  capacity : u64;
};

string_new :: () -> String {
  str : String = undefined;

  str.ptr = malloc(0u64,u8);
  str.size = 0u64;
  str.capacity = 0u64;

  return str;
};

string_from :: (str:[]u8) -> String {
  result : String = undefined;

  result.ptr = malloc(str.length,u8);
  result.size = str.length;
  result.capacity = str.length;

  memcpy(result.ptr,str.ptr,str.length);

  return result;
};

append :: (this:*String, str:String) -> void {
  _grow_if_needed(this, str.size);

  memcpy(this.*.ptr+this.*.size,str.ptr,str.size);

  this.*.size += str.size;
};

append :: (this:*String, str:[]u8) -> void {
  _grow_if_needed(this, str.length);

  memcpy(this.*.ptr+this.*.size,str.ptr,str.length);

  this.*.size += str.length;
};

append :: (this:*String, char:u8) -> void {
  _grow_if_needed(this, 1u64);

  this.*[this.*.size] = char;

  this.*.size += 1u64;
};

_grow_if_needed :: (this:*String, count:u64) -> void {
  new_size := this.*.size + count;
  if new_size >= this.*.capacity {
    cap := this.*.capacity + this.*.capacity / 2u64 + 1u64;
    if new_size >= cap {
      cap = new_size;
    }
    this.*.capacity = cap;
    this.*.ptr = realloc(this.*.ptr,this.*.capacity);
  }
};

slice :: (this:String, begin:i64, end:i64) -> String {
  result:String = undefined;

  result.ptr = this.ptr + begin;
  result.size = @cast(end-begin,u64);
  result.capacity = 0u64;

  return result;
};

delete :: (this:String) -> void {
  free(this.ptr);
};

print :: (this:String) -> void {
  i := 0u64;
  while i < this.size {
    print_char(this[i]);
    i += 1u64;
  }
};

__get_item__ :: (left:*String,index:i64) -> u8 {
  return (left.*.ptr + index).*;
};

__set_item__ :: (left:*String,index:i64,item:u8) -> u8 {
  return (left.*.ptr + index).* = item;
};

__get_item_address__ :: (left:*String,index:i64) -> (*u8) {
  return (left.*.ptr + index);
};

__get_item__ :: (left:*String,index:u64) -> u8 {
  return (left.*.ptr + index).*;
};

__set_item__ :: (left:*String,index:u64,item:u8) -> u8 {
  return (left.*.ptr + index).* = item;
};

__get_item_address__ :: (left:*String,index:u64) -> (*u8) {
  return (left.*.ptr + index);
};