1// This file is part of SmallBASIC
2//
3// bc module. Bytecode manipulation routines (bytecode segments API)
4//
5// This program is distributed under the terms of the GPL v2.0 or later
6// Download the GNU Public License (GPL) from www.gnu.org
7//
8// Copyright(C) 2000 Nicholas Christopoulos
9
10#if !defined(_bc_h)
11#define _bc_h
12
13#include "common/sys.h"
14#include "common/kw.h"
15
16#define BC_ALLOC_INCR 1024
17#define V_QUOTE '\1'
18#define V_LINE '\2'
19#define V_JOIN_LINE '\3'
20
21/**
22 * @ingroup scan
23 * @typedef bc_t
24 *
25 * byte-code segment
26 */
27typedef struct {
28 code_t *ptr; /**< pointer to byte-code */
29 bcip_t cp; /**< current position (used by readers not writers) */
30 bcip_t size; /**< allocation size (optimization) */
31 bcip_t count; /**< current size (used by writers as the current position) */
32 bcip_t eoc_position; /**< position of most recent kwTYPE_EOC or kwTYPE_LINE*/
33 bcip_t line_position; /**< position of most recent kwTYPE_LINE */
34} bc_t;
35
36/**
37 * @ingroup scan
38 *
39 * raise compiler error
40 *
41 * @param fmt the printf's format
42 * @param ... format's parameters
43 */
44void sc_raise(const char *fmt, ...);
45
46/**
47 * @ingroup scan
48 *
49 * create a byte-code segment
50 *
51 * @param bc the bc structure
52 */
53void bc_create(bc_t *bc);
54
55/**
56 * @ingroup scan
57 *
58 * destroy a byte-code segment
59 *
60 * @param bc the bc structure
61 */
62void bc_destroy(bc_t *bc);
63
64/**
65 * @ingroup scan
66 *
67 * resize a byte-code segment
68 *
69 * @param bc the bc structure
70 * @param newsize the new size
71 */
72void bc_resize(bc_t *bc, uint32_t newsize);
73
74/**
75 * @ingroup scan
76 *
77 * add 1 byte to segment
78 *
79 * @param bc the bc structure
80 * @param code the byte
81 */
82void bc_add1(bc_t *bc, char code);
83
84/**
85 * @ingroup scan
86 *
87 * add 1 uint32_t (4-bytes) to segment
88 *
89 * @param bc the bc structure
90 * @param code the uint32_t
91 */
92void bc_add_dword(bc_t *bc, uint32_t code);
93
94/**
95 * @ingroup scan
96 *
97 * adds a string of the given length
98 */
99void bc_add_strn(bc_t *bc, const char *str, int len);
100
101/**
102 * @ingroup scan
103 *
104 * strores a string in the segment
105 *
106 * @param bc the bc structure
107 * @param str the raw-string. the string must starts with \". the string must also contains the ending \".
108 * @return a pointer of src to the next character after the second \"
109 */
110char *bc_store_string(bc_t *bc, char *src);
111
112/**
113 * @ingroup scan
114 *
115 * adds an EOC (end-of-command) mark to segment
116 *
117 * @param bc the bc structure
118 */
119void bc_eoc(bc_t *bc);
120
121/**
122 * @ingroup scan
123 *
124 * pops any EOC mark at the current position
125 *
126 * @param bc the bc segment
127 * @return whether kwTYPE_EOC was popped
128 */
129int bc_pop_eoc(bc_t *bc);
130
131/**
132 * @ingroup scan
133 *
134 * joins two bc segments
135 *
136 * @param dest the destination
137 * @param src the code to be appended to dest
138 */
139void bc_append(bc_t *dest, bc_t *src);
140
141/**
142 * @ingroup scan
143 *
144 * joins two bc segments
145 *
146 * @param dest the destination
147 * @param src the code to be appended to dest
148 * @param n the size of the src to be copied
149 */
150void bc_add_n(bc_t *dest, byte *src, uint32_t n);
151
152/**
153 * @ingroup scan
154 * add a code
155 */
156#define bc_add_code(d,i) bc_add1((d),(i))
157
158/**
159 * @ingroup scan
160 *
161 * add a buildin function
162 *
163 * @param dest the bc segment
164 * @param idx the index of the function
165 */
166void bc_add_fcode(bc_t *dest, bid_t idx);
167
168/**
169 * @ingroup scan
170 *
171 * add a buildin procedure
172 *
173 * @param dest the bc segment
174 * @param idx the index of the procedure
175 */
176void bc_add_pcode(bc_t *dest, bid_t idx);
177
178/**
179 * @ingroup scan
180 *
181 * add an external function
182 *
183 * @param dest the bc segment
184 * @param lib the index of the library
185 * @param idx the index of the function
186 */
187void bc_add_extfcode(bc_t *dest, uint32_t lib, uint32_t idx);
188
189/**
190 * @ingroup scan
191 *
192 * add an external procedure
193 *
194 * @param dest the bc segment
195 * @param lib the index of the library
196 * @param idx the index of the procedure
197 */
198void bc_add_extpcode(bc_t *dest, uint32_t lib, uint32_t idx);
199
200/**
201 * @ingroup scan
202 *
203 * add an address
204 *
205 * @param bc the bc segment
206 * @param idx the address
207 */
208void bc_add_addr(bc_t *bc, bcip_t idx);
209
210/**
211 * @ingroup scan
212 *
213 * add a control-code (if, repeat, while)
214 *
215 * @param bc the bc segment
216 * @param code the control's index
217 * @param true_ip the jump-address when on true
218 * @param false_ip the jump-address when on false
219 */
220void bc_add_ctrl(bc_t *bc, code_t code, bcip_t true_ip, bcip_t false_ip);
221
222/**
223 * @ingroup scan
224 *
225 * add a real number
226 *
227 * @param bc the bc segment
228 * @param v the number
229 */
230void bc_add_creal(bc_t *bc, var_num_t v);
231
232/**
233 * @ingroup scan
234 *
235 * add an integer number
236 *
237 * @param bc the bc segment
238 * @param v the number
239 */
240void bc_add_cint(bc_t *bc, var_int_t v);
241
242#endif
243