Gwion coverage report


Directory: src/
File: src/parse/scan2.c
Date: 2023-01-30 18:32:28
Exec Total Coverage
Lines: 396 402 98.5%
Functions: 62 63 98.4%
Branches: 284 366 77.6%

Line Branch Exec Source
1 #include "gwion_util.h"
2 #include "gwion_ast.h"
3 #include "gwion_env.h"
4 #include "vm.h"
5 #include "template.h"
6 #include "traverse.h"
7 #include "parse.h"
8 #include "operator.h"
9 #include "gwion.h"
10 #include "object.h"
11 #include "instr.h"
12 #include "import.h"
13 #include "default_args.h"
14 #include "spread.h"
15 #include "closure.h"
16
17 ANN static m_bool scan2_stmt(const Env, const Stmt);
18 ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
19
20 12144 ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
21
6/6
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 12099 times.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 11 times.
✓ Branch 7 taken 29 times.
✓ Branch 8 taken 5 times.
12144 if (tflag(t, tflag_scan2) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
22 12128 return GW_OK;
23 16 struct EnvSet es = {.env = env,
24 .data = env,
25 .func = (_exp_func)scan2_cdef,
26 16 .scope = env->scope->depth,
27 .flag = tflag_scan2};
28 16 return envset_run(&es, t);
29 }
30
31 12144 ANN static m_bool scan2_decl(const Env env, const Exp_Decl *decl) {
32 12144 const Type t = decl->type;
33
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12144 times.
12144 CHECK_BB(ensure_scan2(env, t));
34 12144 const Var_Decl vd = decl->vd;
35 12144 nspc_add_value(env->curr, vd.xid, vd.value);
36 12144 return GW_OK;
37 }
38
39 12144 ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl *decl) {
40
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 12140 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
12144 if(decl->args) CHECK_BB(scan2_exp(env, decl->args));
41 12144 const bool global = GET_FLAG(decl->td, global);
42
2/2
✓ Branch 0 taken 12139 times.
✓ Branch 1 taken 5 times.
12144 const m_uint scope = !global ? env->scope->depth : env_push_global(env);
43 12144 const m_bool ret = scan2_decl(env, decl);
44
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 12139 times.
12144 if (global) env_pop(env, scope);
45 12144 return ret;
46 }
47
48 29460 ANN static m_bool scan2_args(const Func_Def f) {
49 29460 Arg_List args = f->base->args;
50
2/2
✓ Branch 0 taken 36634 times.
✓ Branch 1 taken 29460 times.
66094 for(uint32_t i = 0; i < args->len; i++) {
51 36634 Arg *arg = mp_vector_at(args, Arg, i);
52 36634 const Value v = arg->var_decl.value;
53 36634 v->from->offset = f->stack_depth;
54 36634 f->stack_depth += v->type->size;
55 36634 set_vflag(v, vflag_arg);
56 }
57 29460 return GW_OK;
58 }
59
60 76699 ANN static Value scan2_func_assign(const Env env, const Func_Def d,
61 const Func f, const Value v) {
62 76699 valuefrom(env, v->from);
63 76699 SET_FLAG(v, const);
64 76699 set_vflag(v, vflag_func);
65
2/2
✓ Branch 0 taken 4660 times.
✓ Branch 1 taken 72039 times.
76699 if (!env->class_def) {
66
2/2
✓ Branch 0 taken 4658 times.
✓ Branch 1 taken 2 times.
4660 if (!GET_FLAG(d->base, global)) set_vflag(v, vflag_fglobal);
67 } else {
68
2/2
✓ Branch 0 taken 8112 times.
✓ Branch 1 taken 63927 times.
72039 if (GET_FLAG(d->base, static))
69 8112 SET_FLAG(v, static);
70 63927 else set_vflag(v, vflag_member);
71
3/4
✓ Branch 0 taken 6819 times.
✓ Branch 1 taken 65220 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 65220 times.
72039 SET_ACCESS(d->base, v)
72 }
73 76699 d->base->func = v->d.func_ref = f;
74 76699 return f->value_ref = v;
75 }
76
77 6816 ANN m_bool scan2_fptr_def(const Env env NUSED, const Fptr_Def fptr) {
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6816 times.
6816 if(GET_FLAG(fptr->cdef, global)) env_push_global(env);
79 6816 const m_bool ret = scan2_class_def(env, fptr->cdef);
80 6816 const Func_Def fdef = mp_vector_at(fptr->cdef->base.type->info->cdef->body, struct Section_ , 0)->d.func_def;
81
2/2
✓ Branch 0 taken 2752 times.
✓ Branch 1 taken 4064 times.
6816 if(fdef->base->func) set_fflag(fdef->base->func, fflag_fptr);
82
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4064 times.
4064 else CHECK_BB(tmpl_fptr(env, fptr, fdef));
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6816 times.
6816 if(GET_FLAG(fptr->cdef, global)) env_pop(env, 0);
84 6816 return ret;
85 }
86
87 ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f);
88 17 ANN m_bool scan2_type_def(const Env env, const Type_Def tdef) {
89
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
17 if (tdef->when) CHECK_BB(scan2_exp(env, tdef->when));
90
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 10 times.
17 if (tflag(tdef->type, tflag_cdef))
91 7 return scan2_class_def(env, tdef->type->info->cdef);
92
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (!tdef->type->info->cdef) return GW_OK;
93 return tdef->type->info->cdef ? scan2_class_def(env, tdef->type->info->cdef) : GW_OK;
94 }
95
96 12 ANN static m_bool scan2_range(const Env env, Range *range) {
97
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
12 if (range->start) CHECK_BB(scan2_exp(env, range->start));
98
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
12 if (range->end) CHECK_BB(scan2_exp(env, range->end));
99 12 return GW_OK;
100 }
101
102 3848 ANN static inline m_bool scan2_prim(const Env env, const Exp_Primary *prim) {
103
6/6
✓ Branch 0 taken 2969 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 2966 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 2945 times.
3848 if (prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_dict || prim->prim_type == ae_prim_interp)
104
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 903 times.
903 CHECK_BB(scan2_exp(env, prim->d.exp));
105
4/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2925 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 1 times.
2945 else if (prim->prim_type == ae_prim_array && prim->d.array->exp)
106 19 return scan2_exp(env, prim->d.array->exp);
107
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2923 times.
2926 else if (prim->prim_type == ae_prim_range)
108 3 return scan2_range(env, prim->d.range);
109 3826 return GW_OK;
110 }
111
112 28 ANN static inline m_bool scan2_exp_array(const Env env,
113 const Exp_Array *array) {
114
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 CHECK_BB(scan2_exp(env, array->base));
115 28 return scan2_exp(env, array->array->exp);
116 }
117
118 9 ANN static inline m_bool scan2_exp_slice(const Env env, const Exp_Slice *exp) {
119
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 CHECK_BB(scan2_exp(env, exp->base));
120 9 return scan2_range(env, exp->range);
121 }
122
123 618 ANN static inline m_bool scan2_exp_binary(const Env env,
124 const Exp_Binary *bin) {
125
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 618 times.
618 CHECK_BB(scan2_exp(env, bin->lhs));
126 618 return scan2_exp(env, bin->rhs);
127 }
128
129 19 ANN static inline m_bool scan2_exp_cast(const Env env, const Exp_Cast *cast) {
130 19 return scan2_exp(env, cast->exp);
131 }
132
133 34 ANN static inline m_bool scan2_exp_post(const Env env,
134 const Exp_Postfix *post) {
135 34 return scan2_exp(env, post->exp);
136 }
137
138 534 ANN static inline m_bool scan2_exp_call(const Env env,
139 const Exp_Call *exp_call) {
140
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 504 times.
534 if (exp_call->tmpl) return GW_OK;
141
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 504 times.
504 CHECK_BB(scan2_exp(env, exp_call->func));
142 504 const Exp args = exp_call->args;
143
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 212 times.
504 return args ? scan2_exp(env, args) : GW_OK;
144 }
145
146 474 ANN static inline m_bool scan2_exp_dot(const Env env, const Exp_Dot *member) {
147 474 return scan2_exp(env, member->base);
148 }
149
150 9 ANN static inline m_bool scan2_exp_if(const Env env, const Exp_If *exp_if) {
151
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 CHECK_BB(scan2_exp(env, exp_if->cond));
152
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
9 CHECK_BB(scan2_exp(env, exp_if->if_exp ?: exp_if->cond));
153 9 return scan2_exp(env, exp_if->else_exp);
154 }
155
156 153 ANN static m_bool scan2_exp_unary(const Env env, const Exp_Unary *unary) {
157
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 76 times.
153 if (unary->unary_type == unary_exp)
158 77 return scan2_exp(env, unary->exp);
159 76 return GW_OK;
160 }
161
162 11 ANN static inline m_bool _scan2_stmt_match_case(const restrict Env env,
163 const Stmt_Match stmt) {
164
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 CHECK_BB(scan2_exp(env, stmt->cond));
165
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
11 if (stmt->when) CHECK_BB(scan2_exp(env, stmt->when));
166 11 return scan2_stmt_list(env, stmt->list);
167 }
168
169 11 ANN static inline m_bool scan2_stmt_match_case(const restrict Env env,
170 const Stmt_Match stmt) {
171 11 RET_NSPC(_scan2_stmt_match_case(env, stmt))}
172
173 ANN static inline m_bool
174 7 _scan2_stmt_match(const restrict Env env, const Stmt_Match stmt) {
175
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
7 if (stmt->where) CHECK_BB(scan2_stmt(env, stmt->where));
176 7 Stmt_List l = stmt->list;
177
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 7 times.
18 for(m_uint i = 0; i < l->len; i++) {
178 11 const Stmt s = mp_vector_at(l, struct Stmt_, i);
179
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 CHECK_BB(scan2_stmt_match_case(env, &s->d.stmt_match));
180 }
181 7 return GW_OK;
182 }
183
184 3 ANN static inline m_bool scan2_handler(const restrict Env env,
185 const Handler *handler) {
186 3 RET_NSPC(scan2_stmt(env, handler->stmt));
187 }
188
189 3 ANN static inline m_bool scan2_handler_list(const restrict Env env,
190 const Handler_List handlers) {
191
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for(uint32_t i = 0; i < handlers->len; i++) {
192 3 Handler * handler = mp_vector_at(handlers, Handler, i);
193
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 CHECK_BB(scan2_handler(env, handler));
194 }
195 3 return GW_OK;
196 }
197
198 3 ANN static inline m_bool scan2_stmt_try(const restrict Env env,
199 const Stmt_Try stmt) {
200
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 CHECK_BB(scan2_handler_list(env, stmt->handler));
201 3 RET_NSPC(scan2_stmt(env, stmt->stmt))
202 }
203
204 7 ANN static inline m_bool scan2_stmt_match(const restrict Env env,
205 const Stmt_Match stmt) {
206
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 CHECK_BB(scan2_exp(env, stmt->cond));
207 7 RET_NSPC(_scan2_stmt_match(env, stmt))
208 }
209
210 #define scan2_exp_lambda dummy_func
211 #define scan2_exp_td dummy_func
212
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 17898 times.
✓ Branch 3 taken 428 times.
✓ Branch 4 taken 17470 times.
17898 HANDLE_EXP_FUNC(scan2, m_bool, Env)
213
214 #define scan2_stmt_func(name, type, prolog, exp) \
215 describe_stmt_func(scan2, name, type, prolog, exp)
216
2/4
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 30 times.
✗ Branch 6 not taken.
30 scan2_stmt_func(flow, Stmt_Flow,, !(scan2_exp(env, stmt->cond) < 0 ||
217 scan2_stmt(env, stmt->body) < 0) ? 1 : -1)
218
6/10
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 2 times.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
8 scan2_stmt_func(for, Stmt_For,, !(scan2_stmt(env, stmt->c1) < 0 ||
219 scan2_stmt(env, stmt->c2) < 0 ||
220 (stmt->c3 && scan2_exp(env, stmt->c3) < 0) ||
221 scan2_stmt(env, stmt->body) < 0) ? 1 : -1)
222
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
10 scan2_stmt_func(each, Stmt_Each,, !(scan2_exp(env, stmt->exp) < 0 ||
223 scan2_stmt(env, stmt->body) < 0) ? 1 : -1)
224
2/4
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
9 scan2_stmt_func(loop, Stmt_Loop,, !(scan2_exp(env, stmt->cond) < 0 ||
225 scan2_stmt(env, stmt->body) < 0) ? 1 : -1)
226
5/8
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 34 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8 times.
✓ Branch 8 taken 26 times.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
34 scan2_stmt_func(if, Stmt_If,, !(scan2_exp(env, stmt->cond) < 0 ||
227 scan2_stmt(env, stmt->if_body) < 0 ||
228 (stmt->else_body && scan2_stmt(env, stmt->else_body) < 0)) ? 1 : -1)
229
230 132 ANN static inline m_bool scan2_stmt_code(const Env env, const Stmt_Code stmt) {
231
2/2
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 1 times.
132 if (stmt->stmt_list) { RET_NSPC(scan2_stmt_list(env, stmt->stmt_list)) }
232 1 return GW_OK;
233 }
234
235 2151 ANN static inline m_bool scan2_stmt_exp(const Env env, const Stmt_Exp stmt) {
236
2/2
✓ Branch 0 taken 2132 times.
✓ Branch 1 taken 19 times.
2151 return stmt->val ? scan2_exp(env, stmt->val) : 1;
237 }
238
239 644 ANN m_bool scan2_union_def(const Env env NUSED, const Union_Def udef) {
240
2/2
✓ Branch 1 taken 638 times.
✓ Branch 2 taken 6 times.
644 if (tmpl_base(udef->tmpl)) return GW_OK;
241 6 set_tflag(udef->type, tflag_scan2);
242 6 return GW_OK;
243 }
244
245 #define scan2_stmt_while scan2_stmt_flow
246 #define scan2_stmt_until scan2_stmt_flow
247 #define scan2_stmt_continue dummy_func
248 #define scan2_stmt_break dummy_func
249 #define scan2_stmt_return scan2_stmt_exp
250 #define scan2_stmt_retry dummy_func
251
252 8 ANN static m_bool scan2_stmt_pp(const Env env, const Stmt_PP stmt) {
253
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (stmt->pp_type == ae_pp_include) env->name = stmt->data;
254 8 return GW_OK;
255 }
256
257 ANN static m_bool scan2_stmt_defer(const Env env, const Stmt_Defer stmt) {
258 return scan2_stmt(env, stmt->stmt);
259 }
260
261 #define scan2_stmt_spread dummy_func
262
263 DECL_STMT_FUNC(scan2, m_bool, Env)
264
265 2416 ANN static m_bool scan2_stmt(const Env env, const Stmt stmt) {
266 2416 return scan2_stmt_func[stmt->stmt_type](env, &stmt->d);
267 }
268
269 2467 ANN static m_bool scan2_stmt_list(const Env env, Stmt_List l) {
270
2/2
✓ Branch 0 taken 2294 times.
✓ Branch 1 taken 2467 times.
4761 for(m_uint i = 0; i < l->len; i++) {
271 2294 const Stmt s = mp_vector_at(l, struct Stmt_, i);
272
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2294 times.
2294 CHECK_BB(scan2_stmt(env, s));
273 }
274 2467 return GW_OK;
275 }
276
277 10287 ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f,
278 const Value overload) {
279
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10286 times.
10287 if (!is_func(env->gwion, overload->type)) {
280
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (!fbflag(f->base, fbflag_internal))
281 1 ERR_B(f->base->pos,
282 _("function name '%s' is already used by another value"),
283 overload->name)
284 }
285 10286 const Func obase = overload->d.func_ref;
286
3/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10285 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
10286 if (GET_FLAG(obase->def->base, final) && (!env->class_def || (obase->value_ref->from->owner_class != env->class_def))) {
287 1 env_err(env, f->base->pos, _("can't overload final function `{G}%s{0}`"), s_name(f->base->xid));
288 1 declared_here(obase->value_ref);
289 1 return GW_ERROR;
290 }
291 10285 const m_bool base = tmpl_base(f->base->tmpl);
292 10285 const m_bool tmpl = fflag(obase, fflag_tmpl);
293
9/10
✓ Branch 0 taken 10234 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 10234 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 51 times.
✓ Branch 5 taken 10234 times.
✓ Branch 6 taken 44 times.
✓ Branch 7 taken 7 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 43 times.
10285 if ((!tmpl && base) || (tmpl && !base && !f->base->tmpl))
294 1 ERR_B(f->base->pos, _("must overload template function with template"))
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10284 times.
10284 if (GET_FLAG(f->base, global) != GET_FLAG(obase->def->base, global))
296 ERR_B(f->base->pos, _("function is declared global")) // improve me
297 10284 return GW_OK;
298 }
299
300 76699 ANN static Func scan_new_func(const Env env, const Func_Def f,
301 const m_str name) {
302 76699 const Func func = new_func(env->gwion->mp, name, f);
303
4/4
✓ Branch 0 taken 72039 times.
✓ Branch 1 taken 4660 times.
✓ Branch 3 taken 23023 times.
✓ Branch 4 taken 49016 times.
76699 if (env->class_def && tflag(env->class_def, tflag_tmpl))
304 23023 set_fflag(func, fflag_ftmpl);
305
2/2
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 76682 times.
76699 if (fbflag(f->base, fbflag_lambda)) {
306
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 12 times.
17 if(env->class_def) env->class_def->info->values = env->curr->info->value;
307 17 env->curr->info->value = new_scope(env->gwion->mp);
308 }
309 76699 return func;
310 }
311
312 76699 ANN static Type func_type(const Env env, const Func func) {
313 76699 const Type base = env->gwion->type[et_function];
314 76699 const Type t = type_copy(env->gwion->mp, base);
315 76699 t->info->parent = base;
316 76699 t->name = func->name;
317 76699 t->info->func = func;
318 76699 return t;
319 }
320
321 66415 ANN static void func_no_overload(const Env env, const Func f, const Value v) {
322 66415 const Type t = v->type;
323 66415 value_addref(v);
324 66415 nspc_add_value_front(env->curr, f->def->base->xid, v);
325
326 66415 const Type newt = type_copy(env->gwion->mp, t);
327 66415 t->info->parent = newt;
328 66415 newt->name = s_name(f->def->base->xid);
329 66415 newt->info->func = f;
330 66415 nspc_add_type_front(env->curr, f->def->base->xid, newt);
331 66415 newt->info->value = v;
332 66415 }
333
334 ANN2(1, 2)
335 76699 static Value func_value(const Env env, const Func f, const Value overload) {
336 76699 const Type t = func_type(env, f);
337 76699 const Value v = t->info->value = new_value(env, t, t->name, f->def->base->pos);
338 76699 valuefrom(env, v->from);
339
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 76699 times.
76699 CHECK_OO(scan2_func_assign(env, f->def, f, v));
340
2/2
✓ Branch 0 taken 66415 times.
✓ Branch 1 taken 10284 times.
76699 if (!overload)
341 66415 func_no_overload(env, f, v);
342
1/2
✓ Branch 0 taken 10284 times.
✗ Branch 1 not taken.
10284 else if (overload->d.func_ref) {
343 10284 f->next = overload->d.func_ref->next;
344 10284 overload->d.func_ref->next = f;
345 }
346
4/4
✓ Branch 0 taken 72039 times.
✓ Branch 1 taken 4660 times.
✓ Branch 2 taken 63927 times.
✓ Branch 3 taken 8112 times.
76699 if (env->class_def && !GET_FLAG(f->def->base, static))
347 63927 set_vflag(v, vflag_member);
348 76699 return v;
349 }
350
351 ANN2(1, 2)
352 10157 static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f,
353 const Value overload) {
354 10157 const m_str name = s_name(f->base->xid);
355 10157 const Func func = scan_new_func(env, f, name);
356 10157 const Value value = func_value(env, func, overload);
357 10157 set_fflag(func, fflag_tmpl);
358 10157 set_vflag(value, vflag_valid);
359 10157 set_tflag(value->type,
360 tflag_ftmpl); // the only types with func flag, name could be better
361 10157 Type type = env->class_def;
362 10157 Nspc nspc = env->curr;
363 10157 uint i = 0;
364 do {
365 29762 const Value v = nspc_lookup_value0(nspc, f->base->xid);
366
2/2
✓ Branch 0 taken 10161 times.
✓ Branch 1 taken 19601 times.
29762 if (v) {
367 10161 Func ff = v->d.func_ref;
368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10161 times.
10161 if (!ff) continue;
369 do {
370
2/2
✓ Branch 0 taken 10157 times.
✓ Branch 1 taken 17 times.
10174 if (ff->def == f) {
371 10157 ++i;
372 10157 continue;
373 }
374
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 13 times.
17 if (compat_func(ff->def, f) > 0) {
375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ff->value_ref->from->owner == env->curr)
376 ERR_B(f->base->pos,
377 "template function '%s' already defined with those arguments "
378 "in this namespace",
379 name)
380 const Symbol sym =
381 4 func_symbol(env, env->curr->name, name, "template", ff->def->vt_index);
382 4 nspc_add_value(env->curr, sym, value);
383
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!overload) nspc_add_value(env->curr, f->base->xid, value);
384 4 nspc_add_func(env->curr, sym, func);
385 4 func->def->vt_index = ff->def->vt_index;
386 4 return GW_OK;
387 }
388
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 10157 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
10170 } while ((ff = ff->next) && ++i);
389 }
390
5/6
✓ Branch 0 taken 29734 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 29734 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19605 times.
✓ Branch 5 taken 10129 times.
29758 } while (type && (type = type->info->parent) && (nspc = type->nspc));
391 10153 --i;
392 10153 const Symbol sym = func_symbol(env, env->curr->name, name, "template", i);
393 10153 nspc_add_value(env->curr, sym, value);
394 10153 nspc_add_func(env->curr, sym, func);
395
2/2
✓ Branch 0 taken 10146 times.
✓ Branch 1 taken 7 times.
10153 if (!overload) nspc_add_value(env->curr, f->base->xid, value);
396 7 else func->def->vt_index = ++overload->from->offset;
397 10153 return GW_OK;
398 }
399
400 22 ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) {
401 22 const m_str str = s_name(f->base->xid);
402 44 struct Op_Func opfunc = {.ck = strcmp(str, "@implicit") ? 0
403
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 17 times.
22 : opck_usr_implicit};
404 22 struct Op_Import opi = {.ret = f->base->ret_type,
405 22 .pos = f->base->pos,
406 22 .data = (uintptr_t)f->base->func,
407 .func = &opfunc};
408 22 func_operator(f, &opi);
409
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
22 CHECK_BB(add_op(env->gwion, &opi));
410 22 operator_set_func(&opi);
411 22 return GW_OK;
412 }
413
414 1841 ANN static m_bool scan2_func_def_code(const Env env, const Func_Def f) {
415 1841 const Func former = env->func;
416 1841 env->func = f->base->func;
417 1841 const bool ctor = is_ctor(f);
418
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 1545 times.
1841 if(!ctor) {
419 296 env->scope->depth++;
420 296 nspc_push_value(env->gwion->mp, env->curr);
421 }
422 1841 const m_bool ret = scan2_stmt_list(env, f->d.code); // scope depth?
423
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 1545 times.
1841 if(!ctor) {
424 296 nspc_pop_value(env->gwion->mp, env->curr);
425 296 env->scope->depth--;
426 }
427 1841 env->func = former;
428 1841 return ret;
429 }
430
431 66542 ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
432 66542 set_fflag(f->base->func, fflag_pure);
433
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 66540 times.
66542 if (f->base->xid == insert_symbol("@dtor"))
434 2 set_tflag(env->class_def, tflag_dtor);
435 66542 }
436
437
438 56 ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
439 56 const m_str name = s_name(f->base->xid);
440 56 m_str tmpl_name = tl2str(env->gwion, f->base->tmpl->call, f->base->pos);
441 56 const Symbol sym = func_symbol(env, env->curr->name, name, tmpl_name,
442 56 (m_uint)f->vt_index);
443 56 return s_name(sym);
444 }
445
446 ANN2(1, 2, 4)
447 66542 static Value func_create(const Env env, const Func_Def f, const Value overload,
448 const m_str name) {
449 66542 const Func func = scan_new_func(env, f, name);
450 66542 nspc_add_func(env->curr, insert_symbol(func->name), func);
451 66542 const Value v = func_value(env, func, overload);
452 66542 scan2_func_def_flag(env, f);
453 66542 nspc_add_value(env->curr, insert_symbol(func->name), v);
454 66542 return v;
455 }
456
457 ANN2(1, 2)
458 66542 static m_str func_name(const Env env, const Func_Def f, const Value v) {
459
2/2
✓ Branch 0 taken 66486 times.
✓ Branch 1 taken 56 times.
66542 if (!f->base->tmpl) {
460
2/2
✓ Branch 0 taken 10234 times.
✓ Branch 1 taken 56252 times.
76720 const Symbol sym = func_symbol(env, env->curr->name, s_name(f->base->xid),
461 10234 NULL, v ? ++v->from->offset : 0);
462 66486 return s_name(sym);
463 }
464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 return f->base->func ? f->base->func->name : func_tmpl_name(env, f);
465 }
466
467 ANN2(1, 2)
468 66542 m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value overload) {
469 66542 const m_str name = func_name(env, f, overload);
470
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66542 times.
66542 if (!name) return GW_ERROR;
471 66542 const Func base = f->base->func;
472
1/2
✓ Branch 0 taken 66542 times.
✗ Branch 1 not taken.
66542 if (!base)
473
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 66542 times.
66542 CHECK_OB(func_create(env, f, overload, name));
474
3/4
✓ Branch 0 taken 29460 times.
✓ Branch 1 taken 37082 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 29460 times.
66542 if (f->base->args) CHECK_BB(scan2_args(f));
475
5/6
✓ Branch 0 taken 4596 times.
✓ Branch 1 taken 61946 times.
✓ Branch 2 taken 1841 times.
✓ Branch 3 taken 2755 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1841 times.
66542 if (!f->builtin && f->d.code) CHECK_BB(scan2_func_def_code(env, f));
476
1/2
✓ Branch 0 taken 66542 times.
✗ Branch 1 not taken.
66542 if (!base) {
477
3/4
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 66520 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 22 times.
66542 if (fbflag(f->base, fbflag_op)) CHECK_BB(scan2_func_def_op(env, f));
478 66542 set_vflag(f->base->func->value_ref, vflag_valid);
479 }
480
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 66486 times.
66542 if (f->base->tmpl) set_fflag(f->base->func, fflag_tmpl);
481 66542 return GW_OK;
482 }
483
484 //! use function from parent class as next.
485 69472 ANN static void upfunction(const Env env, const Func_Base *fb) {
486 69472 const Value v = find_value(env->class_def->info->parent, fb->xid);
487
2/2
✓ Branch 0 taken 64327 times.
✓ Branch 1 taken 5145 times.
69472 if (!v) return;
488 5145 Func func = fb->func;
489
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5145 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5145 while (func->next && func->next->value_ref->from->owner == env->curr)
490 func = func->next;
491 5145 func->next = v->d.func_ref;
492 }
493
494 76702 ANN m_bool scan2_fdef(const Env env, const Func_Def fdef) {
495 76702 const Value overload = nspc_lookup_value2(env->curr, fdef->base->xid);
496
4/4
✓ Branch 0 taken 10287 times.
✓ Branch 1 taken 66415 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 10284 times.
76702 if (overload) CHECK_BB(scan2_func_def_overload(env, fdef, overload));
497
3/4
✓ Branch 1 taken 66542 times.
✓ Branch 2 taken 10157 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 76699 times.
76699 CHECK_BB((!tmpl_base(fdef->base->tmpl) ? scan2_fdef_std : scan2_fdef_tmpl)(
498 env, fdef, overload));
499
4/4
✓ Branch 0 taken 72039 times.
✓ Branch 1 taken 4660 times.
✓ Branch 2 taken 69472 times.
✓ Branch 3 taken 2567 times.
76699 if (env->class_def && !fdef->base->func->next) upfunction(env, fdef->base);
500 76699 return GW_OK;
501 }
502
503 __attribute__((returns_nonnull)) static ANN Func_Def
504 10159 scan2_cpy_fdef(const Env env, const Func_Def fdef) {
505 10159 const Func_Def f = cpy_func_def(env->gwion->mp, fdef);
506 10159 f->base->ret_type = fdef->base->ret_type;
507 10159 scan0_func_def(env, f);
508 10159 scan1_func_def(env, f);
509 10159 return f;
510 }
511
512 76702 static inline int is_cpy(const Func_Def fdef) {
513
2/2
✓ Branch 0 taken 76700 times.
✓ Branch 1 taken 2 times.
153402 return GET_FLAG(fdef->base, global) ||
514
4/4
✓ Branch 0 taken 10213 times.
✓ Branch 1 taken 66487 times.
✓ Branch 2 taken 10157 times.
✓ Branch 3 taken 56 times.
76700 (fdef->base->tmpl && !fdef->base->tmpl->call);
515 }
516
517 76704 ANN m_bool _scan2_func_def(const Env env, const Func_Def fdef) {
518
4/4
✓ Branch 1 taken 10158 times.
✓ Branch 2 taken 66546 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 10157 times.
76704 if (tmpl_base(fdef->base->tmpl) && fbflag(fdef->base, fbflag_op))
519 1 return GW_OK;
520
2/2
✓ Branch 0 taken 2010 times.
✓ Branch 1 taken 74693 times.
76703 if(is_new(fdef)) {
521
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2009 times.
2010 if(!env->class_def)
522 1 ERR_B(fdef->base->pos, _("{G+}new{0} operator must be set inside {C+}class{0}"));
523 2009 SET_FLAG(env->class_def, abstract);
524
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1991 times.
2009 if(!fdef->base->ret_type)
525 // fdef->base->ret_type = env->class_def;
526 18 fdef->base->ret_type = env->gwion->type[et_auto];
527 }
528
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 76700 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
76702 if (GET_FLAG(fdef->base, global) && !env->class_def) env->context->global = 1;
529
2/2
✓ Branch 1 taken 10159 times.
✓ Branch 2 taken 66543 times.
76702 const Func_Def f = !is_cpy(fdef) ? fdef : scan2_cpy_fdef(env, fdef);
530 76702 const m_uint scope =
531
2/2
✓ Branch 0 taken 76700 times.
✓ Branch 1 taken 2 times.
76702 !GET_FLAG(f->base, global) ? env->scope->depth : env_push_global(env);
532
4/4
✓ Branch 0 taken 72039 times.
✓ Branch 1 taken 4663 times.
✓ Branch 2 taken 63927 times.
✓ Branch 3 taken 8112 times.
140629 f->stack_depth = (env->class_def && !GET_FLAG(f->base, static) &&
533
1/2
✓ Branch 0 taken 63927 times.
✗ Branch 1 not taken.
63927 !GET_FLAG(f->base, global))
534 ? SZ_INT
535 : 0;
536 76702 const m_bool ret = scanx_fdef(env, env, f, (_exp_func)scan2_fdef);
537
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 76700 times.
76702 if (GET_FLAG(f->base, global)) env_pop(env, scope);
538
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 76699 times.
76702 CHECK_BB(ret);
539 76699 fdef->base->func = f->base->func; // only needed if 'is_cpy()'
540 76699 return GW_OK;
541 }
542
543 76704 ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) {
544 76704 const uint16_t depth = env->scope->depth;
545 76704 env->scope->depth = 0;
546 76704 const m_bool ret = _scan2_func_def(env, fdef);
547 76704 env->scope->depth = depth;
548 76704 return ret;
549 }
550
551 #define scan2_enum_def dummy_func
552 #define scan2_trait_def dummy_func
553 #define scan2_extend_def dummy_func
554 #define scan2_prim_def dummy_func
555 29692 HANDLE_SECTION_FUNC(scan2, m_bool, Env)
556
557 4155 ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
558
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4150 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
4155 if (cdef->base.ext->array && cdef->base.ext->array->exp)
559
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp));
560 4155 return GW_OK;
561 }
562
563 4155 ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
564 4155 const bool tmpl = !!cdef->base.tmpl;
565
3/4
✓ Branch 0 taken 1357 times.
✓ Branch 1 taken 2798 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1357 times.
4155 if (tmpl) CHECK_BB(template_push_types(env, cdef->base.tmpl));
566 4155 const m_bool ret = scan2_parent(env, cdef);
567
2/2
✓ Branch 0 taken 1357 times.
✓ Branch 1 taken 2798 times.
4155 if (tmpl) nspc_pop_type(env->gwion->mp, env->curr);
568 4155 return ret;
569 }
570
571 8410 ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
572
2/2
✓ Branch 1 taken 4075 times.
✓ Branch 2 taken 4335 times.
8410 if (tmpl_base(cdef->base.tmpl)) return GW_OK;
573 4335 const Type t = cdef->base.type;
574 4335 const Class_Def c = t->info->cdef;
575
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4335 times.
4335 if (tflag(t, tflag_scan2)) return GW_OK;
576 4335 set_tflag(t, tflag_scan2);
577
3/4
✓ Branch 0 taken 4155 times.
✓ Branch 1 taken 180 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4155 times.
4335 if (c->base.ext) CHECK_BB(cdef_parent(env, c));
578
2/2
✓ Branch 0 taken 4302 times.
✓ Branch 1 taken 33 times.
4335 if (c->body) {
579 4302 const m_uint scope = env_push_type(env, t);
580 4302 const Tmpl *tmpl = cdef->base.tmpl;
581
5/8
✓ Branch 0 taken 1367 times.
✓ Branch 1 taken 2935 times.
✓ Branch 2 taken 1367 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1367 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1367 times.
✗ Branch 7 not taken.
4302 if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
582 1367 template_push_types(env, tmpl);
583 4302 const m_bool ret = scan2_ast(env, &c->body);
584
5/8
✓ Branch 0 taken 1367 times.
✓ Branch 1 taken 2935 times.
✓ Branch 2 taken 1367 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1367 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1367 times.
✗ Branch 7 not taken.
4302 if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
585 1367 nspc_pop_type(env->gwion->mp, env->curr);
586 4302 env_pop(env, scope);
587 4302 return ret;
588 }
589 33 return GW_OK;
590 }
591
592 3 ANN void scan2_default_args(const Env env, const Section *s, Ast *acc) {
593 3 Func_Base *const fb = s->d.func_def->base;
594 3 Arg_List args = fb->args;
595 3 uint32_t len = args->len;
596
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 while(args->len--) {
597 7 const Arg *arg = mp_vector_at(args, Arg, args->len);
598
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if(!arg->exp) break;
599 4 const Func_Def fdef = default_args(env, fb, acc, len);
600 4 scan1_func_def(env, fdef);
601 4 scan2_func_def(env, fdef);
602 }
603 3 args->len = len;
604 3 }
605
606 4814 ANN m_bool scan2_ast(const Env env, Ast *ast) {
607 4814 Ast a = *ast;
608 4814 Ast acc = new_mp_vector(env->gwion->mp, Section, 0);
609 4814 m_bool ret = GW_OK;
610
2/2
✓ Branch 0 taken 29692 times.
✓ Branch 1 taken 4810 times.
34502 for(m_uint i = 0; i < a->len; i++) {
611 29692 Section *section = mp_vector_at(a, Section, i);
612
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 29688 times.
29692 if((ret = scan2_section(env, section)) < 0) break;
613
4/4
✓ Branch 0 taken 22159 times.
✓ Branch 1 taken 7529 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 22156 times.
51847 if (section->section_type == ae_section_func &&
614 22159 fbflag(section->d.func_def->base, fbflag_default)) {
615
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 mp_vector_add(env->gwion->mp, &acc, Section, *section);
616 }
617 }
618
619
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4814 times.
4817 for(uint32_t i = 0; i < acc->len; i++) {
620 3 Section *section = mp_vector_at(acc, Section, i);
621 3 scan2_default_args(env, section, ast);
622 }
623 4814 free_mp_vector(env->gwion->mp, Section, acc);
624 4814 return ret;
625 }
626