1 |
|
|
#include <string.h> |
2 |
|
|
#include "gwion_util.h" |
3 |
|
|
#include "gwion_ast.h" |
4 |
|
|
#include "gwion_env.h" |
5 |
|
|
#include "vm.h" |
6 |
|
|
#include "traverse.h" |
7 |
|
|
#include "template.h" |
8 |
|
|
#include "parser.h" |
9 |
|
|
#include "parse.h" |
10 |
|
|
#include "object.h" |
11 |
|
|
#include "instr.h" |
12 |
|
|
#include "operator.h" |
13 |
|
|
#include "import.h" |
14 |
|
|
|
15 |
|
1861 |
static inline void add_type(const Env env, const Nspc nspc, const Type t) { |
16 |
|
1861 |
nspc_add_type_front(nspc, insert_symbol(t->name), t); |
17 |
|
1861 |
} |
18 |
|
|
|
19 |
|
11 |
static inline void context_global(const Env env) { |
20 |
✓✗ |
11 |
if(env->context) |
21 |
|
11 |
env->context->global = 1; |
22 |
|
11 |
} |
23 |
|
|
|
24 |
|
1104 |
static inline Type scan0_type(const Env env, const m_uint xid, |
25 |
|
|
const m_str name, const Type t) { |
26 |
|
1104 |
const Type type = new_type(env->gwion->mp, xid, name, t); |
27 |
|
1104 |
type->e->ctx = env->context; |
28 |
|
1104 |
return type; |
29 |
|
|
} |
30 |
|
|
|
31 |
|
1878 |
ANN static inline m_bool scan0_defined(const Env env, const Symbol s, const loc_t pos) { |
32 |
✓✓ |
1878 |
if(nspc_lookup_type1(env->curr, s)) |
33 |
|
3 |
ERR_B(pos, _("type '%s' already defined"), s_name(s)); |
34 |
|
1875 |
return already_defined(env, s, pos); |
35 |
|
|
} |
36 |
|
|
|
37 |
|
41 |
ANN static void fptr_assign(const Env env, const Fptr_Def fptr) { |
38 |
|
41 |
const Func_Def def = fptr->type->e->d.func->def; |
39 |
✓✓ |
41 |
if(GET_FLAG(fptr->base, global)) { |
40 |
|
2 |
context_global(env); |
41 |
|
2 |
SET_FLAG(fptr->value, global); |
42 |
|
2 |
SET_FLAG(fptr->base->func, global); |
43 |
|
2 |
SET_FLAG(def->base, global); |
44 |
✓✓ |
39 |
} else if(!GET_FLAG(fptr->base, static)) { |
45 |
|
29 |
SET_FLAG(fptr->value, member); |
46 |
|
29 |
SET_FLAG(fptr->base->func, member); |
47 |
|
29 |
SET_FLAG(def->base, member); |
48 |
|
29 |
def->stack_depth += SZ_INT; |
49 |
|
|
} else { |
50 |
|
10 |
SET_FLAG(fptr->value, static); |
51 |
|
10 |
SET_FLAG(fptr->base->func, static); |
52 |
|
10 |
SET_FLAG(def->base, static); |
53 |
|
|
} |
54 |
✓✓ |
41 |
if(GET_FLAG(def->base, variadic)) |
55 |
|
1 |
def->stack_depth += SZ_INT; |
56 |
|
41 |
fptr->value->from->owner_class = env->class_def; |
57 |
|
41 |
} |
58 |
|
|
|
59 |
|
82 |
static void fptr_def(const Env env, const Fptr_Def fptr) { |
60 |
|
246 |
const Func_Def def = new_func_def(env->gwion->mp, |
61 |
|
82 |
cpy_func_base(env->gwion->mp, fptr->base), |
62 |
|
164 |
NULL, loc_cpy(env->gwion->mp, td_pos(fptr->base->td))); |
63 |
|
82 |
fptr->base->func = new_func(env->gwion->mp, s_name(fptr->base->xid), def); |
64 |
|
82 |
fptr->value->d.func_ref = fptr->base->func; |
65 |
|
82 |
fptr->base->func->value_ref = fptr->value; |
66 |
|
82 |
fptr->type->e->d.func = fptr->base->func; |
67 |
|
82 |
def->base->func = fptr->base->func; |
68 |
|
82 |
} |
69 |
|
|
|
70 |
|
86 |
ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) { |
71 |
✓✓ |
86 |
CHECK_BB(env_access(env, fptr->base->flag, td_pos(fptr->base->td))) |
72 |
✓✓ |
83 |
CHECK_BB(scan0_defined(env, fptr->base->xid, td_pos(fptr->base->td))); |
73 |
|
82 |
const m_str name = s_name(fptr->base->xid); |
74 |
|
82 |
const Type t = scan0_type(env, env->gwion->type[et_fptr]->xid, name, env->gwion->type[et_fptr]); |
75 |
✓✗ |
205 |
t->e->owner = !(!env->class_def && GET_FLAG(fptr->base, global)) ? |
76 |
✓✓ |
164 |
env->curr : env->global_nspc; |
77 |
|
82 |
t->e->owner_class = env->class_def; |
78 |
✓✓ |
82 |
if(GET_FLAG(fptr->base, global)) |
79 |
|
2 |
context_global(env); |
80 |
|
82 |
t->nspc = new_nspc(env->gwion->mp, name); |
81 |
|
82 |
t->flag = fptr->base->flag; |
82 |
|
82 |
fptr->type = t; |
83 |
|
82 |
fptr->value = mk_class(env, t); |
84 |
|
82 |
valuefrom(env, fptr->value->from); |
85 |
|
82 |
fptr_def(env, fptr); |
86 |
✓✓ |
82 |
if(env->class_def) |
87 |
|
41 |
fptr_assign(env, fptr); |
88 |
|
82 |
SET_FLAG(fptr->value, func); |
89 |
|
82 |
add_type(env, t->e->owner, t); |
90 |
|
82 |
mk_class(env, t); |
91 |
|
82 |
ADD_REF(t); |
92 |
|
82 |
return GW_OK; |
93 |
|
|
} |
94 |
|
|
|
95 |
|
1 |
static OP_CHECK(opck_implicit_similar) { |
96 |
|
1 |
const struct Implicit *imp = (struct Implicit*)data; |
97 |
|
1 |
return imp->e->info->type; |
98 |
|
|
} |
99 |
|
|
|
100 |
|
2 |
static OP_CHECK(opck_cast_similar) { |
101 |
|
2 |
const Exp_Cast *cast = (Exp_Cast*)data; |
102 |
|
2 |
return exp_self(cast)->info->type; |
103 |
|
|
} |
104 |
|
|
|
105 |
|
1448 |
ANN static void scan0_implicit_similar(const Env env, const Type lhs, const Type rhs) { |
106 |
|
1448 |
struct Op_Func opfunc = { .ck=opck_cast_similar }; |
107 |
|
1448 |
struct Op_Import opi = { .op=insert_symbol("$"), .lhs=lhs, .rhs=rhs, .func=&opfunc }; |
108 |
|
1448 |
add_op(env->gwion, &opi); |
109 |
|
1448 |
opi.lhs=rhs; |
110 |
|
1448 |
opi.rhs=lhs; |
111 |
|
1448 |
add_op(env->gwion, &opi); |
112 |
|
1448 |
opfunc.ck = opck_implicit_similar; |
113 |
|
1448 |
opi.op=insert_symbol("@implicit"); |
114 |
|
1448 |
add_op(env->gwion, &opi); |
115 |
|
1448 |
} |
116 |
|
|
|
117 |
|
722 |
ANN static void typedef_simple(const Env env, const Type_Def tdef, const Type base) { |
118 |
|
722 |
const Type t = scan0_type(env, ++env->scope->type_xid, s_name(tdef->xid), base); |
119 |
|
722 |
t->size = base->size; |
120 |
✗✓ |
2164 |
const Nspc nspc = (!env->class_def && GET_FLAG(tdef->ext, global)) ? |
121 |
✓✓ |
722 |
env->global_nspc : env->curr; |
122 |
✗✓ |
722 |
if(GET_FLAG(tdef->ext, global)) |
123 |
|
|
context_global(env); |
124 |
|
722 |
add_type(env, nspc, t); |
125 |
|
722 |
t->e->owner = nspc; |
126 |
|
722 |
t->e->owner_class = env->class_def; |
127 |
|
722 |
tdef->type = t; |
128 |
✓✓ |
722 |
if(base->nspc) |
129 |
|
3 |
ADD_REF((t->nspc = base->nspc)); |
130 |
|
722 |
t->flag = tdef->ext->flag | ae_flag_valid; |
131 |
|
722 |
scan0_implicit_similar(env, t, base); |
132 |
✓✓✓✗
|
722 |
if(tdef->ext->array && !tdef->ext->array->exp) |
133 |
|
3 |
SET_FLAG(t, empty); |
134 |
|
722 |
} |
135 |
|
|
|
136 |
|
9 |
ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) { |
137 |
✓✓ |
9 |
const ae_flag flag = base->e->def ? base->e->def->flag : 0; |
138 |
|
27 |
const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid, |
139 |
|
9 |
cpy_type_decl(env->gwion->mp, tdef->ext), NULL, |
140 |
|
18 |
loc_cpy(env->gwion->mp, td_pos(tdef->ext))); |
141 |
✓✓ |
9 |
CHECK_BB(scan0_class_def(env, cdef)) |
142 |
|
8 |
tdef->type = cdef->base.type; |
143 |
|
8 |
cdef->base.tmpl = tdef->tmpl;// check cpy |
144 |
|
8 |
return GW_OK; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
5 |
ANN static void typedef_fptr(const Env env, const Type_Def tdef, const Type base) { |
148 |
|
5 |
tdef->type = type_copy(env->gwion->mp, base); |
149 |
|
5 |
ADD_REF(tdef->type->nspc) |
150 |
|
5 |
tdef->type->name = s_name(tdef->xid); |
151 |
|
5 |
tdef->type->e->parent = base; |
152 |
|
5 |
add_type(env, env->curr, tdef->type); |
153 |
|
5 |
mk_class(env, tdef->type); |
154 |
✓✓ |
5 |
if(base->e->d.func->def->base->tmpl) |
155 |
|
3 |
SET_FLAG(tdef->type, func); |
156 |
|
5 |
} |
157 |
|
|
|
158 |
|
736 |
ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) { |
159 |
✗✓ |
736 |
CHECK_BB(env_access(env, tdef->ext->flag, td_pos(tdef->ext))) |
160 |
✓✓✗✓
|
736 |
DECL_OB(const Type, base, = tdef->tmpl ? find_type(env, tdef->ext) : known_type(env, tdef->ext)) |
161 |
✗✓ |
736 |
CHECK_BB(scan0_defined(env, tdef->xid, td_pos(tdef->ext))) |
162 |
✓✓ |
736 |
if(isa(base, env->gwion->type[et_function]) < 0) { |
163 |
✓✓✓✓ ✓✓ |
731 |
if(!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp)) |
164 |
|
722 |
typedef_simple(env, tdef, base); |
165 |
|
|
else |
166 |
✓✓ |
9 |
CHECK_BB(typedef_complex(env, tdef, base)) |
167 |
|
|
} else |
168 |
|
5 |
typedef_fptr(env, tdef, base); |
169 |
|
735 |
SET_FLAG(tdef->type, typedef); |
170 |
|
735 |
return GW_OK; |
171 |
|
|
} |
172 |
|
|
|
173 |
|
742 |
ANN static Symbol scan0_sym(const Env env, const m_str name, const loc_t pos) { |
174 |
|
742 |
const size_t line_len = num_digit(pos->first.line); |
175 |
|
742 |
const size_t col_len = num_digit(pos->first.column); |
176 |
|
742 |
char c[strlen(env->curr->name) + strlen(env->name) + line_len + col_len + strlen(name) + 6]; |
177 |
|
742 |
sprintf(c, "@%s:%s:%s:%u:%u", name, env->name, env->curr->name, |
178 |
|
|
pos->first.line, pos->first.column); |
179 |
|
742 |
return insert_symbol(c); |
180 |
|
|
} |
181 |
|
|
|
182 |
|
|
#define scan0_nspc(env, a) \ |
183 |
|
|
GET_FLAG(a, global) ? !env->class_def ? env->global_nspc : NULL : env->curr |
184 |
|
|
|
185 |
|
726 |
ANN static Type enum_type(const Env env, const Enum_Def edef) { |
186 |
|
726 |
const Type t = type_copy(env->gwion->mp, env->gwion->type[et_int]); |
187 |
|
726 |
t->xid = ++env->scope->type_xid; |
188 |
|
726 |
const Symbol sym = scan0_sym(env, "enum", edef->pos); |
189 |
✓✓ |
726 |
t->name = edef->xid ? s_name(edef->xid) : s_name(sym); |
190 |
|
726 |
t->e->parent = env->gwion->type[et_int]; |
191 |
✗✓ |
726 |
const Nspc nspc = GET_FLAG(edef, global) ? env->global_nspc : env->curr; |
192 |
|
726 |
t->e->owner = nspc; |
193 |
|
726 |
t->e->owner_class = env->class_def; |
194 |
|
726 |
add_type(env, nspc, t); |
195 |
|
726 |
mk_class(env, t); |
196 |
|
726 |
scan0_implicit_similar(env, t, env->gwion->type[et_int]); |
197 |
|
726 |
return t; |
198 |
|
|
} |
199 |
|
|
|
200 |
|
1058 |
ANN static inline m_bool scan0_global(const Env env, const ae_flag flag, const loc_t pos) { |
201 |
✓✓✓✗
|
1058 |
if(!env->class_def || !((flag & ae_flag_global) == ae_flag_global)) |
202 |
|
1058 |
return GW_OK; |
203 |
|
|
ERR_B(pos, _("can't declare as global in class def")) |
204 |
|
|
} |
205 |
|
|
|
206 |
|
727 |
ANN m_bool scan0_enum_def(const Env env, const Enum_Def edef) { |
207 |
✗✓ |
727 |
CHECK_BB(env_storage(env, edef->flag, edef->pos)) |
208 |
✓✓ |
727 |
CHECK_BB(scan0_defined(env, edef->xid, edef->pos)) |
209 |
✗✓ |
726 |
CHECK_BB(scan0_global(env, edef->flag, edef->pos)) |
210 |
|
726 |
edef->t = enum_type(env, edef); |
211 |
✗✓ |
726 |
if(GET_FLAG(edef, global)) |
212 |
|
|
context_global(env); |
213 |
|
726 |
return GW_OK; |
214 |
|
|
} |
215 |
|
|
|
216 |
|
26 |
ANN static Type union_type(const Env env, const Symbol s, const m_bool add) { |
217 |
|
26 |
const m_str name = s_name(s); |
218 |
|
26 |
const Type t = type_copy(env->gwion->mp, env->gwion->type[et_union]); |
219 |
|
26 |
t->xid = ++env->scope->type_xid; |
220 |
|
26 |
t->name = name; |
221 |
|
26 |
t->nspc = new_nspc(env->gwion->mp, name); |
222 |
|
26 |
t->e->owner = t->nspc->parent = env->curr; |
223 |
|
26 |
t->e->owner_class = env->class_def; |
224 |
|
26 |
t->e->parent = env->gwion->type[et_union]; |
225 |
|
26 |
t->e->tuple = new_tupleform(env->gwion->mp, NULL); |
226 |
|
26 |
add_type(env, env->curr, t); |
227 |
✓✓ |
26 |
if(add) |
228 |
|
18 |
mk_class(env, t); |
229 |
|
26 |
SET_FLAG(t, union); |
230 |
|
26 |
return t; |
231 |
|
|
} |
232 |
|
|
|
233 |
|
5 |
ANN static void union_tmpl(const Env env, const Union_Def udef) { |
234 |
✓✗ |
5 |
if(tmpl_base(udef->tmpl)) { |
235 |
|
|
assert(udef->type_xid); |
236 |
|
15 |
const Class_Def cdef = new_class_def(env->gwion->mp, udef->flag, udef->type_xid, |
237 |
|
10 |
NULL, (Ast)cpy_decl_list(env->gwion->mp, udef->l), loc_cpy(env->gwion->mp, udef->pos)); |
238 |
|
5 |
udef->type->e->def = cdef; |
239 |
|
5 |
cdef->base.tmpl = cpy_tmpl(env->gwion->mp, udef->tmpl); |
240 |
|
5 |
cdef->base.type = udef->type; |
241 |
|
5 |
SET_FLAG(cdef, union); |
242 |
|
5 |
SET_FLAG(udef->type, pure); |
243 |
|
5 |
SET_FLAG(udef, template); |
244 |
|
5 |
SET_FLAG(udef->type, template); |
245 |
|
|
} |
246 |
✗✓ |
5 |
if(GET_FLAG(udef, global)) |
247 |
|
|
SET_FLAG(udef->type, global); |
248 |
|
5 |
SET_FLAG(udef->type, union); |
249 |
|
5 |
} |
250 |
|
|
|
251 |
|
16 |
ANN static Value union_value(const Env env, const Type t, const Symbol sym) { |
252 |
|
16 |
const Value v = new_value(env->gwion->mp, t, s_name(sym)); |
253 |
|
16 |
valuefrom(env, v->from); |
254 |
|
16 |
nspc_add_value(env->curr, sym, v); |
255 |
|
16 |
SET_FLAG(v, valid | ae_flag_pure); |
256 |
|
16 |
return v; |
257 |
|
|
} |
258 |
|
|
|
259 |
|
32 |
ANN m_bool scan0_union_def(const Env env, const Union_Def udef) { |
260 |
✓✓ |
32 |
CHECK_BB(env_storage(env, udef->flag, udef->pos)) |
261 |
✗✓ |
26 |
CHECK_BB(scan0_global(env, udef->flag, udef->pos)) |
262 |
✓✓ |
26 |
const m_uint scope = !GET_FLAG(udef, global) ? env->scope->depth : |
263 |
|
|
env_push_global(env); |
264 |
✓✓ |
26 |
if(GET_FLAG(udef, global)) |
265 |
|
3 |
context_global(env); |
266 |
✓✓ |
26 |
if(udef->xid) { |
267 |
✗✓ |
8 |
CHECK_BB(scan0_defined(env, udef->xid, udef->pos)) |
268 |
✗✓ |
8 |
const Symbol sym = udef->type_xid ?: scan0_sym(env, "union", udef->pos); |
269 |
|
8 |
const Type t = union_type(env, sym, !!udef->type_xid); |
270 |
|
8 |
udef->value = union_value(env, t, udef->xid); |
271 |
|
8 |
udef->value->flag |= udef->flag; |
272 |
✓✓✗✓
|
8 |
SET_ACCESS(udef, t); |
273 |
✓✓✓✓
|
8 |
if(env->class_def && !GET_FLAG(udef, static)) { |
274 |
|
3 |
SET_FLAG(udef->value, member); |
275 |
|
3 |
SET_FLAG(udef, member); |
276 |
|
|
} |
277 |
✓✓ |
18 |
} else if(udef->type_xid) { |
278 |
✗✓ |
10 |
CHECK_BB(scan0_defined(env, udef->type_xid, udef->pos)) |
279 |
|
10 |
udef->type = union_type(env, udef->type_xid, 1); |
280 |
✗✓✗✓
|
10 |
SET_ACCESS(udef, udef->type); |
281 |
|
10 |
SET_FLAG(udef->type, valid); |
282 |
|
|
} else { |
283 |
|
8 |
const Symbol sym = scan0_sym(env, "union", udef->pos); |
284 |
✗✓ |
8 |
CHECK_BB(scan0_defined(env, sym, udef->pos)) |
285 |
|
8 |
const Type t = union_type(env, sym, 1); |
286 |
✗✓✗✓
|
8 |
SET_ACCESS(udef, t); |
287 |
|
8 |
udef->value = union_value(env, t, sym); |
288 |
|
8 |
udef->value->flag |= udef->flag; |
289 |
|
|
} |
290 |
✓✓ |
26 |
if(udef->tmpl) |
291 |
|
5 |
union_tmpl(env, udef); |
292 |
✓✓ |
26 |
if(GET_FLAG(udef, global)) |
293 |
|
3 |
env_pop(env, scope); |
294 |
|
26 |
union_flag(udef, ae_flag_scan0); |
295 |
|
26 |
return GW_OK; |
296 |
|
|
} |
297 |
|
|
|
298 |
|
306 |
ANN static m_bool scan0_class_def_pre(const Env env, const Class_Def cdef) { |
299 |
✗✓ |
306 |
CHECK_BB(env_storage(env, cdef->flag, cdef->pos)) |
300 |
✗✓ |
306 |
CHECK_BB(isres(env, cdef->base.xid, cdef->pos)) |
301 |
✗✓ |
306 |
CHECK_BB(scan0_global(env, cdef->flag, cdef->pos)) |
302 |
|
306 |
return GW_OK; |
303 |
|
|
} |
304 |
|
|
|
305 |
|
300 |
ANN static void cdef_flag(const Class_Def cdef, const Type t) { |
306 |
✓✓ |
300 |
if(cdef->base.tmpl) { |
307 |
|
63 |
SET_FLAG(t, template); |
308 |
|
63 |
SET_FLAG(cdef, template); |
309 |
|
|
} |
310 |
✓✓✓✓
|
300 |
if(cdef->base.ext && cdef->base.ext->array) |
311 |
|
9 |
SET_FLAG(t, typedef); |
312 |
|
300 |
} |
313 |
|
|
|
314 |
|
8 |
ANN static Type get_parent_base(const Env env, Type_Decl *td) { |
315 |
✗✓ |
8 |
DECL_OO(const Type, t, = find_type(env, td)) |
316 |
|
8 |
Type owner = env->class_def; |
317 |
✗✓ |
16 |
while(owner) { |
318 |
|
|
if(t == owner) |
319 |
|
|
ERR_O(td_pos(td), _("'%s' as parent inside itself\n."), owner->name); |
320 |
|
|
owner = owner->e->owner_class; |
321 |
|
|
} |
322 |
|
8 |
return t; |
323 |
|
|
} |
324 |
|
|
|
325 |
|
305 |
ANN static Type get_parent(const Env env, const Class_Def cdef) { |
326 |
✓✓ |
305 |
if(GET_FLAG(cdef, struct)) |
327 |
|
11 |
return env->gwion->type[et_compound]; |
328 |
✓✓ |
294 |
if(!cdef->base.ext) |
329 |
|
210 |
return env->gwion->type[et_object]; |
330 |
✓✓ |
84 |
if(tmpl_base(cdef->base.tmpl)) |
331 |
|
8 |
return get_parent_base(env, cdef->base.ext); |
332 |
✓✓ |
76 |
if(cdef->base.tmpl) |
333 |
|
22 |
template_push_types(env, cdef->base.tmpl); |
334 |
|
76 |
const Type t = known_type(env, cdef->base.ext); |
335 |
✓✓ |
76 |
if(cdef->base.tmpl) |
336 |
|
22 |
nspc_pop_type(env->gwion->mp, env->curr); |
337 |
✓✓ |
76 |
return t ?: (Type)GW_ERROR; |
338 |
|
|
} |
339 |
|
|
|
340 |
|
306 |
ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { |
341 |
✓✓ |
306 |
CHECK_BO(scan0_defined(env, cdef->base.xid, cdef->pos)) |
342 |
|
305 |
const Type parent = get_parent(env, cdef); |
343 |
✓✓ |
305 |
if(parent == (Type)GW_ERROR) |
344 |
|
5 |
return NULL; |
345 |
|
300 |
const Type t = scan0_type(env, ++env->scope->type_xid, s_name(cdef->base.xid), parent); |
346 |
✓✓ |
300 |
if(GET_FLAG(cdef, struct)) |
347 |
|
11 |
SET_FLAG(t, struct); |
348 |
|
300 |
t->e->tuple = new_tupleform(env->gwion->mp, parent); |
349 |
|
300 |
t->e->owner = env->curr; |
350 |
|
300 |
t->e->owner_class = env->class_def; |
351 |
|
300 |
t->nspc = new_nspc(env->gwion->mp, t->name); |
352 |
|
300 |
t->nspc->parent = env->curr; |
353 |
|
300 |
t->e->def = cdef; |
354 |
|
300 |
t->flag = cdef->flag; |
355 |
|
300 |
add_type(env, t->e->owner, t); |
356 |
|
300 |
cdef_flag(cdef, t); |
357 |
✓✓✓✓
|
300 |
if(cdef->base.ext && cdef->base.ext->array) |
358 |
|
9 |
SET_FLAG(t, typedef); |
359 |
|
300 |
return t; |
360 |
|
|
} |
361 |
|
|
|
362 |
|
|
ANN static m_bool scan0_stmt_list(const Env env, Stmt_List list) { |
363 |
|
|
do if(list->stmt->stmt_type == ae_stmt_pp && list->stmt->d.stmt_pp.pp_type == ae_pp_include) |
364 |
|
|
env->name = list->stmt->d.stmt_pp.data; |
365 |
|
|
while((list = list->next)); |
366 |
|
|
return GW_OK; |
367 |
|
|
} |
368 |
|
|
|
369 |
|
1439 |
ANN static m_bool scan0_section(const Env env, const Section* section) { |
370 |
✓✓ |
1439 |
if(section->section_type == ae_section_class) |
371 |
|
261 |
return scan0_class_def(env, section->d.class_def); |
372 |
✓✓ |
1178 |
if(section->section_type == ae_section_enum) |
373 |
|
8 |
return scan0_enum_def(env, section->d.enum_def); |
374 |
✓✓ |
1170 |
if(section->section_type == ae_section_union) |
375 |
|
24 |
return scan0_union_def(env, section->d.union_def); |
376 |
✓✓ |
1146 |
if(section->section_type == ae_section_fptr) |
377 |
|
72 |
return scan0_fptr_def(env, section->d.fptr_def); |
378 |
✓✓ |
1074 |
if(section->section_type == ae_section_type) |
379 |
|
21 |
return scan0_type_def(env, section->d.type_def); |
380 |
✗✓ |
1053 |
if(section->section_type == ae_section_type) |
381 |
|
|
return scan0_stmt_list(env, section->d.stmt_list); |
382 |
|
1053 |
return GW_OK; |
383 |
|
|
} |
384 |
|
|
|
385 |
|
306 |
ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) { |
386 |
✓✓ |
306 |
CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef))) |
387 |
|
300 |
SET_FLAG(cdef->base.type, scan0); |
388 |
✓✓ |
300 |
if(cdef->body) |
389 |
✓✓ |
235 |
CHECK_BB(env_body(env, cdef, scan0_section)) |
390 |
|
299 |
(void)mk_class(env, cdef->base.type); |
391 |
|
299 |
return GW_OK; |
392 |
|
|
} |
393 |
|
|
|
394 |
|
306 |
ANN m_bool scan0_class_def(const Env env, const Class_Def c) { |
395 |
|
612 |
const Class_Def cdef = !tmpl_base(c->base.tmpl) ? |
396 |
✓✓ |
306 |
c : cpy_class_def(env->gwion->mp, c); |
397 |
✓✓ |
306 |
if(GET_FLAG(cdef, global)) { |
398 |
|
4 |
vector_add(&env->scope->nspc_stack, (vtype)env->curr); |
399 |
|
4 |
env->curr = env->global_nspc; |
400 |
|
4 |
context_global(env); |
401 |
|
|
} |
402 |
|
612 |
const m_bool ret = scan0_class_def_pre(env, cdef) > 0 ? |
403 |
✓✗ |
306 |
scan0_class_def_inner(env, cdef) : GW_ERROR; |
404 |
✓✓ |
306 |
if(GET_FLAG(cdef, global)) |
405 |
|
4 |
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack); |
406 |
✓✓ |
306 |
CHECK_BB(ret) |
407 |
✓✓✓✓ ✓✓ |
299 |
if(GET_FLAG(cdef, global) || (cdef->base.tmpl && !cdef->base.tmpl->call)) |
408 |
|
30 |
c->base.type = cdef->base.type; |
409 |
|
299 |
SET_FLAG(cdef->base.type, scan0); |
410 |
|
299 |
return GW_OK; |
411 |
|
|
} |
412 |
|
|
|
413 |
|
1035 |
ANN m_bool scan0_ast(const Env env, Ast ast) { |
414 |
✓✓ |
1035 |
do CHECK_BB(scan0_section(env, ast->section)) |
415 |
✓✓ |
1021 |
while((ast = ast->next)); |
416 |
|
608 |
return GW_OK; |
417 |
|
|
} |