Increase MAX_STATIC_DATA
[bazic.git] / string.h
1 global string_first;
2
3 constant STRING_NEXT 0;
4 constant STRING_PTR 1;
5 constant STRING_LEN 2;
6 constant STRING_REF 3;
7 constant STRING__SIZE (4*2);
8
9 ! Initialise the string store.
10
11 [ string_init;
12         string_first = 0;
13 ];
14
15 ! Returns false if the string is constant (i.e., it points to a literal in
16 ! the byte-code itself).
17
18 [ string_isvar s;
19         return ((s < store_bottom) || (s > store_eop));
20 ];
21
22 ! Add an entry for a new string.
23
24 [ string_alloc str len  s;
25         if (string_isvar(str))
26         {
27                 ! Need to duplicate the string.
28                 s = mem_alloc(len);
29                 memcpy(s, str, len);
30                 str = s;
31         }
32         s = mem_alloc(STRING__SIZE);
33         s-->STRING_NEXT = string_first;
34         s-->STRING_PTR = str;
35         s-->STRING_LEN = len;
36         string_first = s;
37         return s;
38 ];
39
40 ! Print a string.
41
42 [ string_print s  i;
43         i = s-->STRING_LEN;
44         s = s-->STRING_PTR;
45         while (i--)
46                 print (char) (s++)->0;
47 ];
48
49 ! Compare two strings.
50
51 [ string_compare s1 s2  i;
52         i = s1-->STRING_LEN;
53         if (i ~= s2-->STRING_LEN)
54                 return -1;
55         s1 = s1-->STRING_PTR;
56         s2 = s2-->STRING_PTR;
57         while (i--)
58                 if ((s1++)->0 ~= (s2++)->0)
59                         return -1;
60         return 0;
61 ];
62
63 ! Garbage collection: clean.
64
65 [ string_clean  s;
66         s = string_first;
67         while (s)
68         {
69                 s-->STRING_REF = 0;
70                 s = s-->STRING_NEXT;
71         }
72 ];
73
74 ! Garbage collection: mark.
75
76 [ string_mark  var;
77         var = store_firstvar;
78         while (var)
79         {
80                 if (var-->VN_TYPE == TYPE_STRING)
81                         var-->VN_VALUE-->STRING_REF = 1;
82                 var = var-->VN_NEXT;
83         }
84 ];
85                         
86 #ifdef DEBUG;
87 ! Garbage collection: list status.
88
89 [ string_status  s;
90         s = string_first;
91         while (s)
92         {
93                 print s, " ", s-->STRING_NEXT, " ";
94                 string_print(s);
95                 print " ", s-->STRING_REF, "^";
96                 s = s-->STRING_NEXT;
97         }
98 ];
99 #endif;
100
101 ! Garbage collection: sweep.
102
103 [ string_sweep  s olds news;
104         olds = 0;
105         s = string_first;
106         while (s)
107         {
108                 news = s-->STRING_NEXT;
109                 if (s-->STRING_REF == 0)
110                 {
111                         if (string_isvar(s-->STRING_PTR))
112                                 mem_free(s-->STRING_PTR);
113                         if (olds)
114                                 olds-->STRING_NEXT = news;
115                         else
116                         {
117                                 ! If olds is null, then we're on the first
118                                 ! string in the list; which means we need to
119                                 ! change string_first when we remove it.
120                                 string_first = news;
121                         }
122                         mem_free(s);
123                 }
124                 else
125                         olds = s;
126                         
127                 s = news;
128         }
129 ];
130         
131 ! Garbage collector.
132
133 [ string_gc;
134         ! Phase one: clean.
135         string_clean();
136         ! Phase two: mark.
137         string_mark();
138 #ifdef DEBUG;
139         !string_status();
140 #endif;
141         ! Phase three: sweep.
142         string_sweep();
143 ];
144
145 ! Turn a string into an int.
146
147 [ string_toint s  len i neg;
148         len = s-->STRING_LEN;
149         s = s-->STRING_PTR;
150         i = 0;
151         neg = 1;
152
153         while (len && (s->0 == 32 or 9))
154         {
155                 s++;
156                 len--;
157         }
158
159         if (len == 0)
160                 return i;
161         
162         if (s->0 == '-')
163         {
164                 neg = -1;
165                 s++;
166                 len--;
167         }
168
169         if (len == 0)
170                 return i;
171         
172         while (len && (s->0 >= '0') && (s->0 <= '9'))
173         {
174                 i = i*10 + (s->0 - '0');
175                 s++;
176                 len--;
177         }
178
179         return i*neg;
180 ];