1 /* |
1 #ifndef BOTC_DATABUFFER_H |
2 * botc source code |
2 #define BOTC_DATABUFFER_H |
3 * Copyright (C) 2012 Santeri `Dusk` Piippo |
|
4 * All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions are met: |
|
8 * |
|
9 * 1. Redistributions of source code must retain the above copyright notice, |
|
10 * this list of conditions and the following disclaimer. |
|
11 * 2. Redistributions in binary form must reproduce the above copyright notice, |
|
12 * this list of conditions and the following disclaimer in the documentation |
|
13 * and/or other materials provided with the distribution. |
|
14 * 3. Neither the name of the developer nor the names of its contributors may |
|
15 * be used to endorse or promote products derived from this software without |
|
16 * specific prior written permission. |
|
17 * 4. Redistributions in any form must be accompanied by information on how to |
|
18 * obtain complete source code for the software and any accompanying |
|
19 * software that uses the software. The source code must either be included |
|
20 * in the distribution or be available for no more than the cost of |
|
21 * distribution plus a nominal fee, and must be freely redistributable |
|
22 * under reasonable conditions. For an executable file, complete source |
|
23 * code means the source code for all modules it contains. It does not |
|
24 * include source code for modules or files that typically accompany the |
|
25 * major components of the operating system on which the executable file |
|
26 * runs. |
|
27 * |
|
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
38 * POSSIBILITY OF SUCH DAMAGE. |
|
39 */ |
|
40 |
|
41 #ifndef __DATABUFFER_H__ |
|
42 #define __DATABUFFER_H__ |
|
43 #include <stdio.h> |
3 #include <stdio.h> |
44 #include <string.h> |
4 #include <string.h> |
45 #include "common.h" |
5 #include "main.h" |
46 #include "stringtable.h" |
6 #include "stringtable.h" |
47 |
7 |
48 #define MAX_MARKS 512 |
8 #define MAX_MARKS 512 |
49 |
9 |
50 extern int g_NextMark; |
10 extern int g_NextMark; |
98 } |
58 } |
99 } |
59 } |
100 |
60 |
101 // ==================================================================== |
61 // ==================================================================== |
102 // Write stuff to the buffer |
62 // Write stuff to the buffer |
103 template<class T> void DoWrite (const char* func, T stuff) { |
63 template<class T> void Write (T stuff) { |
104 // printf ("DoWrite: called from %s\n", func); |
|
105 if (writesize + sizeof (T) >= allocsize) { |
64 if (writesize + sizeof (T) >= allocsize) { |
106 // We don't have enough space in the buffer to write |
65 // We don't have enough space in the buffer to write |
107 // the stuff - thus resize. First, store the old |
66 // the stuff - thus resize. First, store the old |
108 // buffer temporarily: |
67 // buffer temporarily: |
109 char* copy = new char[allocsize]; |
68 char* copy = new char[allocsize]; |
155 error ("DataBuffer: duplicate mark %d!\n"); |
114 error ("DataBuffer: duplicate mark %d!\n"); |
156 |
115 |
157 marks[u] = other->marks[u]; |
116 marks[u] = other->marks[u]; |
158 marks[u]->pos += oldsize; |
117 marks[u]->pos += oldsize; |
159 |
118 |
160 // The original mark becomes NULL so that the deconstructor |
119 // The original mark becomes null so that the deconstructor |
161 // will not delete it prematurely. (should it delete any |
120 // will not delete it prematurely. (should it delete any |
162 // marks in the first place since there is no such thing |
121 // marks in the first place since there is no such thing |
163 // as at temporary mark?) |
122 // as at temporary mark?) |
164 other->marks[u] = NULL; |
123 other->marks[u] = null; |
165 } |
124 } |
166 |
125 |
167 if (other->refs[u]) { |
126 if (other->refs[u]) { |
168 // Same for references |
127 // Same for references |
169 // TODO: add a g_NextRef system like here, akin to marks! |
128 // TODO: add a g_NextRef system like here, akin to marks! |
186 // ==================================================================== |
145 // ==================================================================== |
187 // Adds a mark to the buffer. A mark is a "pointer" to a particular |
146 // Adds a mark to the buffer. A mark is a "pointer" to a particular |
188 // position in the bytecode. The actual permanent position cannot |
147 // position in the bytecode. The actual permanent position cannot |
189 // be predicted in any way or form, thus these things will be used |
148 // be predicted in any way or form, thus these things will be used |
190 // to "mark" a position like that for future use. |
149 // to "mark" a position like that for future use. |
191 unsigned int AddMark (str name) { |
150 unsigned int AddMark (string name) { |
192 // Find a free slot for the mark |
151 // Find a free slot for the mark |
193 unsigned int u = g_NextMark++; |
152 unsigned int u = g_NextMark++; |
194 |
153 |
195 if (marks[u]) |
154 if (marks[u]) |
196 error ("DataBuffer: attempted to re-create mark %u!\n", u); |
155 error ("DataBuffer: attempted to re-create mark %u!\n", u); |
235 if (!marks[marknum]) |
194 if (!marks[marknum]) |
236 return; |
195 return; |
237 |
196 |
238 // Delete the mark |
197 // Delete the mark |
239 delete marks[marknum]; |
198 delete marks[marknum]; |
240 marks[marknum] = NULL; |
199 marks[marknum] = null; |
241 |
200 |
242 // Delete its references |
201 // Delete its references |
243 for (unsigned int u = 0; u < MAX_MARKS; u++) { |
202 for (unsigned int u = 0; u < MAX_MARKS; u++) { |
244 if (refs[u]->num == marknum) { |
203 if (refs[u]->num == marknum) { |
245 delete refs[u]; |
204 delete refs[u]; |
246 refs[u] = NULL; |
205 refs[u] = null; |
247 } |
206 } |
248 } |
207 } |
249 } |
208 } |
250 |
209 |
251 // Adjusts a mark to the current position |
210 // Adjusts a mark to the current position |
252 void MoveMark (unsigned int mark, int offset = -1) { |
211 void MoveMark (unsigned int mark) { |
253 if (!marks[mark]) |
212 if (!marks[mark]) |
254 return; |
213 return; |
|
214 |
255 marks[mark]->pos = writesize; |
215 marks[mark]->pos = writesize; |
256 } |
216 } |
257 |
217 |
258 void OffsetMark (unsigned int mark, size_t offset) { |
218 void OffsetMark (unsigned int mark, int offset) { |
259 if (!marks[mark]) |
219 if (!marks[mark]) |
260 return; |
220 return; |
|
221 |
261 marks[mark]->pos += offset; |
222 marks[mark]->pos += offset; |
262 } |
223 } |
263 |
224 |
264 // Dump the buffer (for debugging purposes) |
225 // Dump the buffer (for debugging purposes) |
265 void Dump() { |
226 void Dump() { |
282 count += !!refs[u]; |
243 count += !!refs[u]; |
283 return count; |
244 return count; |
284 } |
245 } |
285 |
246 |
286 // Write a float into the buffer |
247 // Write a float into the buffer |
287 void WriteFloat (str floatstring) { |
248 void WriteFloat (string floatstring) { |
288 // TODO: Casting float to word causes the decimal to be lost. |
249 // TODO: Casting float to word causes the decimal to be lost. |
289 // Find a way to store the number without such loss. |
250 // Find a way to store the number without such loss. |
290 float val = atof (floatstring); |
251 float val = atof (floatstring); |
291 Write (DH_PUSHNUMBER); |
252 Write (DH_PUSHNUMBER); |
292 Write (static_cast<word> ((val > 0) ? val : -val)); |
253 Write (static_cast<word> ((val > 0) ? val : -val)); |
293 if (val < 0) |
254 if (val < 0) |
294 Write (DH_UNARYMINUS); |
255 Write (DH_UNARYMINUS); |
295 } |
256 } |
296 |
257 |
297 void WriteString (str string) { |
258 void WriteString (string a) { |
298 Write (DH_PUSHSTRINGINDEX); |
259 Write (DH_PUSHSTRINGINDEX); |
299 Write (PushToStringTable (string)); |
260 Write (get_string_table_index (a)); |
300 } |
261 } |
301 }; |
262 }; |
302 |
263 |
303 #endif // __DATABUFFER_H__ |
264 #endif // BOTC_DATABUFFER_H |