Gwion coverage report


Directory: src/
File: src/parse/scan1.c
Date: 2023-01-30 18:32:28
Exec Total Coverage
Lines: 536 568 94.4%
Functions: 79 80 98.8%
Branches: 472 612 77.1%

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 "traverse.h"
6 #include "template.h"
7 #include "parse.h"
8 #include "object.h"
9 #include "operator.h"
10 #include "instr.h"
11 #include "import.h"
12
13 ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
14 ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
15
16 2552 ANN static inline m_bool type_cyclic(const Env env, const Type t,
17 const Type_Decl *td) {
18 2552 Type owner = env->class_def;
19 do {
20 2552 Type parent = t;
21 do {
22
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3828 times.
3828 if (parent == owner)
23 ERR_B(td->pos, _("%s declared inside %s"), t->name, owner->name);
24
2/2
✓ Branch 0 taken 1276 times.
✓ Branch 1 taken 2552 times.
3828 } while ((parent = parent->info->parent));
25
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2552 times.
2552 } while ((owner = owner->info->value->from->owner_class));
26 2552 return GW_OK;
27 }
28
29 48804 ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
30
6/6
✓ Branch 1 taken 54 times.
✓ Branch 2 taken 48750 times.
✓ Branch 4 taken 43 times.
✓ Branch 5 taken 11 times.
✓ Branch 7 taken 38 times.
✓ Branch 8 taken 5 times.
48804 if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
31 48788 return GW_OK;
32 16 struct EnvSet es = {.env = env,
33 .data = env,
34 .func = (_exp_func)scan1_cdef,
35 16 .scope = env->scope->depth,
36 .flag = tflag_scan1};
37 16 return envset_run(&es, t);
38 }
39
40 2560 ANN static m_bool check_global(const Env env, const Type t, const loc_t pos) {
41 2560 const ValueFrom *from = t->info->value->from;
42
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2560 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2560 if(from->owner_class && isa(from->owner_class, env->class_def) > 0)
43 return true;
44
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2559 times.
2560 if(from_global_nspc(env, from->owner) ||
45
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 (from->owner_class && type_global(env, from->owner_class)))
46 2559 return true;
47 1 gwerr_basic("can't use non-global type in a global class", NULL, NULL, env->name, pos, 0);
48 1 gwerr_secondary_from("not declared global", from);
49 1 const ValueFrom *ownerFrom = env->class_def->info->value->from;
50 1 gwerr_secondary_from("is global", ownerFrom);
51 1 env_set_error(env, true);
52 1 return false;
53 }
54
55 48820 ANN static Type scan1_type(const Env env, Type_Decl *td) {
56
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 48804 times.
48820 DECL_OO(const Type, t, = known_type(env, td));
57 48804 const Type base = array_base(t);
58
5/6
✓ Branch 0 taken 11976 times.
✓ Branch 1 taken 36828 times.
✓ Branch 2 taken 2552 times.
✓ Branch 3 taken 9424 times.
✓ Branch 4 taken 2552 times.
✗ Branch 5 not taken.
48804 if (!env->func && env->class_def && !GET_FLAG(td, late))
59
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2552 times.
2552 CHECK_BO(type_cyclic(env, base, td));
60
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48804 times.
48804 CHECK_BO(ensure_scan1(env, t));
61 48804 return t;
62 }
63
64 48820 ANN static Type void_type(const Env env, Type_Decl *td) {
65
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 48804 times.
48820 DECL_OO(const Type, type, = scan1_type(env, td));
66
2/2
✓ Branch 0 taken 48799 times.
✓ Branch 1 taken 5 times.
48804 if (type->size) return type;
67 5 ERR_O(td->pos, _("cannot declare variables of size '0' (i.e. 'void')..."))
68 }
69
70 12183 ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl *decl) {
71
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12174 times.
12183 if (decl->type) return decl->type;
72
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 12159 times.
12174 DECL_OO(const Type, t, = void_type(env, decl->td));
73
6/6
✓ Branch 0 taken 2724 times.
✓ Branch 1 taken 9435 times.
✓ Branch 3 taken 2560 times.
✓ Branch 4 taken 164 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 2559 times.
12159 if(env->class_def && type_global(env, env->class_def) && !check_global(env, t, decl->td->pos))
74 1 return NULL;
75
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12149 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
12158 if (decl->td->xid == insert_symbol("auto") && decl->type) return decl->type;
76
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12157 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
12158 if (GET_FLAG(t, private) && t->info->value->from->owner != env->curr)
77 1 ERR_O(exp_self(decl)->pos, _("can't use private type %s"), t->name)
78
3/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12156 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
12157 if (GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0))
79 1 ERR_O(exp_self(decl)->pos, _("can't use protected type %s"), t->name)
80 12156 return t;
81 }
82
83 12163 static inline m_bool scan1_defined(const Env env, const Var_Decl *var) {
84
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12154 times.
12163 if (var->value) // from an auto declaration
85 9 return GW_OK;
86
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2722 times.
2723 const Value v = ((!env->class_def || !GET_FLAG(env->class_def, final) ||
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 env->scope->depth)
88 ? nspc_lookup_value1
89
2/2
✓ Branch 0 taken 2723 times.
✓ Branch 1 taken 9431 times.
14877 : nspc_lookup_value2)(env->curr, var->xid);
90
3/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 12151 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
12154 if(v && (!v->from->owner_class || isa(env->class_def, v->from->owner_class) > 0))
91 3 ERR_B(var->pos,
92 _("variable %s has already been defined in the same scope..."),
93 s_name(var->xid))
94 12151 return GW_OK;
95 }
96
97 3 ANN m_bool abstract_array(const Env env, const Array_Sub array) {
98 3 Exp e = array->exp;
99
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 while(e) {
100
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if(!exp_is_zero(e))
101 3 ERR_B(e->pos, _("arrays of abstract type should use `0` size"));
102 e = e->next;
103 }
104 return GW_OK;
105 }
106
107 12163 ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) {
108
4/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 12141 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 19 times.
12163 const bool decl_ref = decl->td->array && !decl->td->array->exp;
109 12163 Var_Decl *const vd = &decl->vd;
110
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 12163 times.
12163 CHECK_BB(isres(env, vd->xid, exp_self(decl)->pos));
111 12163 Type t = decl->type;
112
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 12160 times.
12163 CHECK_BB(scan1_defined(env, vd));
113 12160 const Type base = array_base_simple(t);
114
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 12138 times.
12160 if(decl->td->array) {
115
4/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 18 times.
22 if (!GET_FLAG(decl->td, late) && !decl->td->array->exp)
116 3 ERR_B(decl->td->pos, _("arrays with no expressions should be declared `late`"));
117
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
19 if (GET_FLAG(decl->td, late) && decl->td->array->exp)
118 1 ERR_B(decl->td->array->exp->pos, _("late array should have no size"));
119
4/6
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 16 times.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
18 if (!decl->args && GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, decl->td->array));
120 }
121 12154 const Value v = vd->value =
122
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12145 times.
12154 vd->value ?: new_value(env, t, s_name(vd->xid), vd->pos);
123
4/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12142 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12154 if (GET_FLAG(t, abstract) && !decl->args && !GET_FLAG(decl->td, late)) SET_FLAG(v, late);
124 12154 v->type = t;
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12154 times.
12154 if (decl_ref) SET_FLAG(v, late);
126 12154 v->flag |= decl->td->flag;
127
2/2
✓ Branch 0 taken 11963 times.
✓ Branch 1 taken 191 times.
12154 if (!env->scope->depth) {
128 11963 valuefrom(env, v->from);
129
2/2
✓ Branch 0 taken 2717 times.
✓ Branch 1 taken 9246 times.
11963 if (env->class_def) {
130
1/2
✓ Branch 0 taken 2717 times.
✗ Branch 1 not taken.
2717 if (env->class_def->info->tuple) tuple_contains(env, v);
131
2/2
✓ Branch 0 taken 2704 times.
✓ Branch 1 taken 13 times.
2717 if (!GET_FLAG(decl->td, static)) {
132 2704 set_vflag(v, vflag_member);
133
2/2
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 2679 times.
2704 if(tflag(t, tflag_release))
134 25 set_tflag(env->class_def, tflag_release);
135
2/2
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 2020 times.
2704 if(isa(t, env->gwion->type[et_object]) > 0)
136 684 set_vflag(v, vflag_release);
137
2/2
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 2658 times.
2704 if (tflag(env->class_def, tflag_struct)) {
138 46 v->from->offset = env->class_def->size;
139 46 env->class_def->size += t->size;
140 }
141 }
142
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 9241 times.
9246 } else if (GET_FLAG(decl->td, global))
143 5 SET_FLAG(v, global);
144
2/2
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 8932 times.
9241 else if(env->context)
145 309 set_vflag(v, vflag_fglobal); // file global
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 191 times.
191 } else if (GET_FLAG(decl->td, global))
147 SET_FLAG(v, global);
148 12154 nspc_add_value(env->curr, vd->xid, v);
149 12154 ((Exp_Decl *)decl)->type = decl->vd.value->type;
150 12154 return GW_OK;
151 }
152
153 12188 ANN m_bool scan1_exp_decl(const Env env, Exp_Decl *const decl) {
154
2/2
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 12183 times.
12188 CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos));
155 12183 ((Exp_Decl *)decl)->type = scan1_exp_decl_type(env, (Exp_Decl *)decl);
156
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 12165 times.
12183 CHECK_OB(decl->type);
157
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 12161 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
12165 if(decl->args) CHECK_BB(scan1_exp(env, decl->args));
158 12165 const bool global = GET_FLAG(decl->td, global);
159
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 12158 times.
12165 if (global) {
160
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (env->context) env->context->global = true;
161
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
7 if (!type_global(env, decl->type))
162 2 ERR_B(exp_self(decl)->pos, _("type '%s' is not global"), decl->type->name)
163 }
164
2/2
✓ Branch 0 taken 12158 times.
✓ Branch 1 taken 5 times.
12163 const m_uint scope = !global ? env->scope->depth : env_push_global(env);
165 12163 const m_bool ret = scan1_decl(env, decl);
166
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 12158 times.
12163 if (global) env_pop(env, scope);
167 12163 return ret;
168 }
169
170 655 ANN static inline m_bool scan1_exp_binary(const Env env,
171 const Exp_Binary *bin) {
172
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 655 times.
655 CHECK_BB(scan1_exp(env, bin->lhs));
173 655 return scan1_exp(env, bin->rhs);
174 }
175
176 12 ANN static m_bool scan1_range(const Env env, Range *range) {
177
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(scan1_exp(env, range->start));
178
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(scan1_exp(env, range->end));
179 12 return GW_OK;
180 }
181
182 4024 ANN static inline m_bool scan1_prim(const Env env, const Exp_Primary *prim) {
183
4/4
✓ Branch 0 taken 4021 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 3997 times.
4024 if (prim->prim_type == ae_prim_dict || prim->prim_type == ae_prim_interp)
184 27 return scan1_exp(env, prim->d.exp);
185
2/2
✓ Branch 0 taken 918 times.
✓ Branch 1 taken 3079 times.
3997 if (prim->prim_type == ae_prim_hack) {
186
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 678 times.
918 if(env->func) env->func->weight = 1; // mark function has having gack
187 // we should use effects when typechecking for that
188 918 return scan1_exp(env, prim->d.exp);
189 }
190
4/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 3059 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 1 times.
3079 if (prim->prim_type == ae_prim_array && prim->d.array->exp)
191 19 return scan1_exp(env, prim->d.array->exp);
192
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3057 times.
3060 if (prim->prim_type == ae_prim_range) return scan1_range(env, prim->d.range);
193
5/6
✓ Branch 0 taken 896 times.
✓ Branch 1 taken 2161 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 893 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3057 if (env->func && prim->prim_type == ae_prim_perform && env->scope->depth <= 2)
194 3 env->func->memoize = 1;
195 3057 return GW_OK;
196 }
197
198 28 ANN static inline m_bool scan1_exp_array(const Env env,
199 const Exp_Array *array) {
200
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 CHECK_BB(scan1_exp(env, array->base));
201 28 return scan1_exp(env, array->array->exp);
202 }
203
204 9 ANN static inline m_bool scan1_exp_slice(const Env env,
205 const Exp_Slice *range) {
206
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 CHECK_BB(scan1_exp(env, range->base));
207 9 return scan1_range(env, range->range);
208 }
209
210 19 ANN static inline m_bool scan1_exp_cast(const Env env, const Exp_Cast *cast) {
211 19 return scan1_exp(env, cast->exp);
212 }
213
214 36 ANN static m_bool scan1_exp_post(const Env env, const Exp_Postfix *post) {
215
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
36 CHECK_BB(scan1_exp(env, post->exp));
216 36 const m_str access = exp_access(post->exp);
217
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 1 times.
36 if (!access) return GW_OK;
218 1 ERR_B(post->exp->pos,
219 _("post operator '%s' cannot be used"
220 " on %s data-type..."),
221 s_name(post->op), access);
222 }
223
224 548 ANN static m_bool scan1_exp_call(const Env env, const Exp_Call *exp_call) {
225
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 518 times.
548 if (exp_call->tmpl) return GW_OK;
226
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 518 times.
518 CHECK_BB(scan1_exp(env, exp_call->func));
227 518 const Exp args = exp_call->args;
228
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 224 times.
518 return args ? scan1_exp(env, args) : GW_OK;
229 }
230
231 487 ANN static inline m_bool scan1_exp_dot(const Env env, const Exp_Dot *member) {
232 487 return scan1_exp(env, member->base);
233 }
234
235 10 ANN static m_bool scan1_exp_if(const Env env, const Exp_If *exp_if) {
236
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 CHECK_BB(scan1_exp(env, exp_if->cond));
237
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
10 if(exp_if->if_exp) CHECK_BB(scan1_exp(env, exp_if->if_exp));
238 10 return scan1_exp(env, exp_if->else_exp);
239 }
240
241 159 ANN static inline m_bool scan1_exp_unary(const restrict Env env,
242 Exp_Unary *const unary) {
243
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 79 times.
159 if(unary->unary_type == unary_exp)
244 80 return scan1_exp(env, unary->exp);
245
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 50 times.
79 if (unary->unary_type == unary_code)
246 29 return scan1_stmt_list(env, unary->code);
247 50 return GW_OK;
248 }
249
250 #define scan1_exp_lambda dummy_func
251 #define scan1_exp_td dummy_func
252
4/4
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 18157 times.
✓ Branch 3 taken 442 times.
✓ Branch 4 taken 17715 times.
18192 HANDLE_EXP_FUNC(scan1, m_bool, Env)
253
254 11 ANN static inline m_bool _scan1_stmt_match_case(const restrict Env env,
255 const Stmt_Match stmt) {
256
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 CHECK_BB(scan1_exp(env, stmt->cond));
257
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(scan1_exp(env, stmt->when));
258 11 return scan1_stmt_list(env, stmt->list);
259 }
260
261 11 ANN static inline m_bool scan1_stmt_match_case(const restrict Env env,
262 const Stmt_Match stmt) {
263 11 RET_NSPC(_scan1_stmt_match_case(env, stmt))}
264
265 ANN static inline m_bool
266 7 _scan1_stmt_match(const restrict Env env, const Stmt_Match stmt) {
267
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(scan1_stmt(env, stmt->where));
268 7 Stmt_List l = stmt->list;
269
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 7 times.
18 for(m_uint i = 0; i < l->len; i++) {
270 11 const Stmt s = mp_vector_at(l, struct Stmt_, i);
271
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 CHECK_BB(scan1_stmt_match_case(env, &s->d.stmt_match));
272 }
273 7 return GW_OK;
274 }
275
276 7 ANN static inline m_bool scan1_stmt_match(const restrict Env env,
277 const Stmt_Match stmt) {
278
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 CHECK_BB(scan1_exp(env, stmt->cond));
279 7 RET_NSPC(_scan1_stmt_match(env, stmt))
280 }
281
282 3 ANN static inline m_bool scan1_handler(const restrict Env env,
283 const Handler *handler) {
284 3 RET_NSPC(scan1_stmt(env, handler->stmt));
285 }
286
287 3 ANN static inline m_bool scan1_handler_list(const restrict Env env,
288 const Handler_List handlers) {
289
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for(uint32_t i = 0; i < handlers->len; i++) {
290 3 Handler * handler = mp_vector_at(handlers, Handler, i);
291
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 CHECK_BB(scan1_handler(env, handler));
292 }
293 3 return GW_OK;
294 }
295
296 3 ANN static inline m_bool scan1_stmt_try(const restrict Env env,
297 const Stmt_Try stmt) {
298
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 CHECK_BB(scan1_handler_list(env, stmt->handler));
299 3 RET_NSPC(scan1_stmt(env, stmt->stmt))
300 }
301
302 10 ANN static inline m_bool stmt_each_defined(const restrict Env env,
303 const Stmt_Each stmt) {
304
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if (nspc_lookup_value1(env->curr, stmt->sym))
305 ERR_B(stmt_self(stmt)->pos, _("foreach value '%s' is already defined"),
306 s_name(stmt->sym))
307
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
10 if (stmt->idx && nspc_lookup_value1(env->curr, stmt->idx->sym))
308 ERR_B(stmt->idx->pos, _("foreach index '%s' is already defined"),
309 s_name(stmt->idx->sym))
310 10 return GW_OK;
311 }
312
313 2 ANN static inline m_bool shadow_err(const Env env, const Value v,
314 const loc_t loc) {
315
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(env->scope->shadowing) return GW_OK;
316 1 gwerr_basic(_("shadowing a previously defined variable"), NULL, NULL,
317 1 env->name, loc, 0);
318 1 defined_here(v);
319 1 env_set_error(env, true);
320 1 return GW_ERROR;
321 }
322
323 36656 ANN static inline m_bool shadow_arg(const Env env, const Symbol sym,
324 const loc_t loc) {
325 36656 Nspc nspc = env->curr;
326 do {
327 72450 const Value v = nspc_lookup_value0(nspc, sym);
328
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 72449 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
72450 if (v && !env->func->def->builtin) {
329 1 const Type owner = v->from->owner_class;
330
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1 if (owner && env->class_def && isa(env->class_def, owner) < 0)
331 continue;
332 1 return shadow_err(env, v, loc);
333 }
334
2/2
✓ Branch 0 taken 35794 times.
✓ Branch 1 taken 36655 times.
72449 } while ((nspc = nspc->parent));
335 36655 return GW_OK;
336 }
337
338 2 ANN static inline m_bool shadow_var(const Env env, const Symbol sym,
339 const loc_t loc) {
340 2 const Value v = nspc_lookup_value1(env->curr, sym);
341
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 return !v ? GW_OK : shadow_err(env, v, loc);
342 }
343
344 #define describe_ret_nspc(name, type, prolog, exp) \
345 describe_stmt_func(scan1, name, type, prolog, exp)
346
2/4
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 32 times.
✗ Branch 6 not taken.
32 describe_ret_nspc(flow, Stmt_Flow,, !(scan1_exp(env, stmt->cond) < 0 ||
347 scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
348
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 describe_ret_nspc(for, Stmt_For,, !(scan1_stmt(env, stmt->c1) < 0 ||
349 scan1_stmt(env, stmt->c2) < 0 ||
350 (stmt->c3 && scan1_exp(env, stmt->c3) < 0) ||
351 scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
352
3/6
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
10 describe_ret_nspc(each, Stmt_Each,, !(stmt_each_defined(env, stmt) < 0 || scan1_exp(env, stmt->exp) < 0 ||
353 scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
354
6/8
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 9 times.
✗ Branch 11 not taken.
10 describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? GW_OK : shadow_var(env, stmt->idx->sym, stmt->idx->pos)) < 0 ||
355 scan1_exp(env, stmt->cond) < 0 ||
356 scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
357
358 8 ANN static inline bool if_stmt_is_return(const Stmt stmt) {
359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (stmt->stmt_type == ae_stmt_return) return true;
360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (stmt->stmt_type == ae_stmt_code) {
361 if (mp_vector_len(stmt->d.stmt_code.stmt_list)) {
362 Stmt s = mp_vector_back(stmt->d.stmt_code.stmt_list, struct Stmt_);
363 if (s->stmt_type == ae_stmt_return) return true;
364 }
365 }
366 8 return false;
367 }
368
369 34 ANN static inline m_bool _scan1_stmt_if(const Env env, const Stmt_If stmt) {
370
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
34 CHECK_BB(scan1_exp(env, stmt->cond));
371
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
34 CHECK_BB(scan1_stmt(env, stmt->if_body));
372
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 26 times.
34 if(stmt->else_body) {
373 8 const bool is_ret = if_stmt_is_return(stmt->if_body);
374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if(is_ret) env->scope->depth--;
375
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 CHECK_BB(scan1_stmt(env, stmt->else_body));
376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if(is_ret) env->scope->depth++;
377 }
378 34 return GW_OK;
379 }
380
381 34 ANN static inline m_bool scan1_stmt_if(const Env env, const Stmt_If stmt) {
382 34 RET_NSPC(_scan1_stmt_if(env, stmt));
383 return GW_OK;
384 }
385
386 137 ANN static inline m_bool scan1_stmt_code(const Env env, const Stmt_Code stmt) {
387
2/2
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 2 times.
137 if (stmt->stmt_list) { RET_NSPC(scan1_stmt_list(env, stmt->stmt_list)) }
388 2 return GW_OK;
389 }
390
391 2183 ANN static inline m_bool scan1_stmt_exp(const Env env, const Stmt_Exp stmt) {
392
2/2
✓ Branch 0 taken 2167 times.
✓ Branch 1 taken 16 times.
2183 return stmt->val ? scan1_exp(env, stmt->val) : 1;
393 }
394
395 645 ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
396 645 const Type t = edef->type;
397 645 t->nspc = new_nspc(env->gwion->mp, t->name);
398 645 const m_uint scope = env_push_type(env, t);
399 645 ID_List list = edef->list;
400
2/2
✓ Branch 0 taken 656 times.
✓ Branch 1 taken 645 times.
1301 for(uint32_t i = 0; i < list->len; i++) {
401 656 Symbol xid = *mp_vector_at(list, Symbol, i);
402 656 const Value v = new_value(env, t, s_name(xid), edef->pos);
403 656 valuefrom(env, v->from);
404 656 nspc_add_value(env->curr, xid, v);
405
1/2
✓ Branch 0 taken 656 times.
✗ Branch 1 not taken.
656 if (env->class_def) {
406 656 SET_FLAG(v, static);
407
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 655 times.
656 SET_ACCESS(edef, v)
408
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 655 times.
656 SET_ACCESS(edef, t)
409 } else
410 set_vflag(v, vflag_builtin);
411 656 SET_FLAG(v, const);
412 656 vector_add(&edef->values, (vtype)v);
413 }
414 645 env_pop(env, scope);
415 645 return GW_OK;
416 }
417
418 36649 ANN static Value arg_value(const Env env, Arg *const arg) {
419 36649 const Var_Decl *vd = &arg->var_decl;
420 36649 const Value v = new_value(env, arg->type,
421
2/2
✓ Branch 0 taken 36605 times.
✓ Branch 1 taken 44 times.
36649 vd->xid ? s_name(vd->xid) : (m_str) __func__, arg->var_decl.pos);
422
2/2
✓ Branch 0 taken 36640 times.
✓ Branch 1 taken 9 times.
36649 if (arg->td)
423 36640 v->flag = arg->td->flag;
424 36649 return v;
425 }
426
427 29478 ANN static m_bool scan1_args(const Env env, Arg_List args) {
428
2/2
✓ Branch 0 taken 36656 times.
✓ Branch 1 taken 29471 times.
66127 for(uint32_t i = 0; i < args->len; i++) {
429 36656 Arg *arg = mp_vector_at(args, Arg, i);
430 36656 Var_Decl *const vd = &arg->var_decl;
431
4/4
✓ Branch 0 taken 36612 times.
✓ Branch 1 taken 44 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 36611 times.
36656 if (vd->xid) CHECK_BB(isres(env, vd->xid, vd->pos));
432
2/2
✓ Branch 0 taken 36646 times.
✓ Branch 1 taken 9 times.
36655 if (arg->td) {
433 36646 SET_FLAG(arg->td, late);
434
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 36640 times.
36646 CHECK_OB((arg->type = void_type(env, arg->td)));
435
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36640 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
36640 if (GET_FLAG(env->func->def->base, global) && !type_global(env, arg->type))
436 ERR_B(arg->td->pos, "is not global");
437 36640 UNSET_FLAG(arg->td, late);
438 }
439 36649 vd->value = arg_value(env, arg);
440
2/2
✓ Branch 0 taken 36605 times.
✓ Branch 1 taken 44 times.
36649 if (vd->xid) nspc_add_value(env->curr, vd->xid, vd->value);
441 }
442 29471 return GW_OK;
443 }
444
445 86890 ANN static Type scan1_noret(const Env env, const Func_Base *base) {
446 assert(base->td);
447
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 86880 times.
86890 DECL_OO(const Type, t, = known_type(env, base->td));
448
2/2
✓ Branch 1 taken 86879 times.
✓ Branch 2 taken 1 times.
86880 if (!tflag(t, tflag_noret)) return t;
449 1 ERR_O(base->pos, _("Can't use type `{+G}%s{0}` for return"), t->name);
450 }
451
452 20316 ANN static m_bool _scan1_fbase_tmpl(const Env env, Func_Base *base) {
453 20316 Specialized_List sl = base->tmpl->list;
454
2/2
✓ Branch 0 taken 20324 times.
✓ Branch 1 taken 20316 times.
40640 for(uint32_t i = 0; i < sl->len; i++) {
455 20324 Specialized *spec = mp_vector_at(sl, Specialized, i);
456 20324 nspc_add_type(env->curr, spec->xid, env->gwion->type[et_auto]);
457 }
458
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 20314 times.
20316 CHECK_OB((base->ret_type = scan1_noret(env, base)));
459 20314 return GW_OK;
460 }
461
462 20316 ANN static m_bool scan1_fbase_tmpl(const Env env, Func_Base *const base) {
463 20316 nspc_push_type(env->gwion->mp, env->curr);
464 20316 const m_bool ret = _scan1_fbase_tmpl(env, base);
465 20316 nspc_pop_type(env->gwion->mp, env->curr);
466 20316 return ret;
467 }
468
469 20317 ANN static m_bool scan1_fdef_base_tmpl(const Env env, const Func_Def fdef) {
470 20317 Func_Base *const base = fdef->base;
471
2/2
✓ Branch 1 taken 20316 times.
✓ Branch 2 taken 1 times.
20317 if (!fbflag(base, fbflag_op)) return scan1_fbase_tmpl(env, base);
472 1 Arg_List args = fdef->base->args;
473 1 Specialized_List sl = fdef->base->tmpl->list;
474 1 uint32_t j = 0;
475
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for(uint32_t i = 0; i < args->len; i++) {
476 2 Arg *arg = mp_vector_at(args, Arg, i);
477 2 Specialized *spec = mp_vector_at(sl, Specialized, j);
478
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if (!arg->td->next && spec && arg->td->xid == spec->xid) { j++; }
479 }
480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (j < sl->len) ERR_B(base->pos, "too many template types for operator");
481
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!env->curr->operators)
482 1 env->curr->operators = mp_calloc(env->gwion->mp, NspcOp);
483 1 const Vector v = &env->curr->operators->tmpl;
484
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!v->ptr) vector_init(v);
485 1 vector_add(v, (m_uint)cpy_func_def(env->gwion->mp, fdef));
486 1 return GW_OK;
487 }
488
489 6823 ANN m_bool scan1_fptr_def(const Env env, const Fptr_Def fptr) {
490 6823 const bool global = GET_FLAG(fptr->cdef, global);
491
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6823 times.
6823 if(global) env_push_global(env);
492 6823 const m_bool ret = scan1_class_def(env, fptr->cdef);
493
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6823 times.
6823 if(global) env_pop(env, 0);
494 6823 return ret;
495 }
496
497 18 ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
498
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
18 if (tdef->when) CHECK_BB(scan1_exp(env, tdef->when));
499
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
18 if(tflag(tdef->type->info->parent, tflag_ref))
500 ERR_B(tdef->pos, "can't typedef a reference type");
501
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 11 times.
18 if (tflag(tdef->type, tflag_cdef))
502 7 return scan1_class_def(env, tdef->type->info->cdef);
503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 return tdef->type->info->cdef ? scan1_cdef(env, tdef->type) : GW_OK;
504 }
505
506 7 ANN static inline m_bool scan1_union_def_inner_loop(const Env env,
507 Union_Def udef) {
508 7 nspc_allocdata(env->gwion->mp, udef->type->nspc);
509 7 Union_List l = udef->l;
510 7 m_uint sz = 0;
511 7 const Value v = new_value(env, env->gwion->type[et_int], "@index", udef->pos);
512 7 nspc_add_value_front(env->curr, insert_symbol("@index"), v);
513 7 valuefrom(env, v->from);
514
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 6 times.
19 for(uint32_t i = 0; i < l->len; i++) {
515 13 Union_Member *um = mp_vector_at(l, Union_Member, i);
516
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 DECL_OB(const Type, t, = known_type(env, um->td));
517
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if (nspc_lookup_value0(env->curr, um->vd.xid))
518 ERR_B(um->vd.pos, _("'%s' already declared in union"), s_name(um->vd.xid))
519
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
13 if(tflag(t, tflag_ref))
520 1 ERR_B(um->vd.pos, _("can't declare ref type in union"));
521 12 const Value v = new_value(env, t, s_name(um->vd.xid), um->vd.pos);
522 12 tuple_contains(env, v);
523 12 valuefrom(env, v->from);
524 12 nspc_add_value_front(env->curr, um->vd.xid, v);
525
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (t->size > sz) sz = t->size;
526 }
527 6 udef->type->nspc->offset = SZ_INT + sz;
528 6 return GW_OK;
529 }
530
531 7 ANN static m_bool scan1_union_def_inner(const Env env, const Union_Def udef) {
532
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
7 if (udef->tmpl && udef->tmpl->call)
533
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 CHECK_BB(template_push_types(env, udef->tmpl));
534 7 const m_bool ret = scan1_union_def_inner_loop(env, udef);
535
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
7 if (udef->tmpl && udef->tmpl->call) nspc_pop_type(env->gwion->mp, env->curr);
536 7 return ret;
537 }
538
539 645 ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
540
2/2
✓ Branch 1 taken 638 times.
✓ Branch 2 taken 7 times.
645 if (tmpl_base(udef->tmpl)) return GW_OK;
541 7 const m_uint scope = env_push_type(env, udef->type);
542 7 const m_bool ret = scan1_union_def_inner(env, udef);
543 7 env_pop(env, scope);
544 7 set_tflag(udef->type, tflag_scan1);
545 7 return ret;
546 }
547
548 #define scan1_stmt_while scan1_stmt_flow
549 #define scan1_stmt_until scan1_stmt_flow
550 #define scan1_stmt_continue dummy_func
551 #define scan1_stmt_break dummy_func
552 #define scan1_stmt_retry dummy_func
553
554 93 ANN static m_bool scan1_stmt_return(const Env env, const Stmt_Exp stmt) {
555
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 92 times.
93 if (!env->func)
556 1 ERR_B(stmt_self(stmt)->pos,
557 _("'return' statement found outside function definition"))
558
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 6 times.
92 if (env->scope->depth == 1) env->func->memoize = 1;
559
3/4
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 89 times.
92 if(stmt->val) CHECK_BB(scan1_exp(env, stmt->val));
560 92 return GW_OK;
561 }
562
563 8 ANN static m_bool scan1_stmt_pp(const Env env, const Stmt_PP stmt) {
564
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (stmt->pp_type == ae_pp_include) env->name = stmt->data;
565
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
8 if (stmt->pp_type == ae_pp_pragma && !strcmp(stmt->data, "packed")) {
566 if(env->class_def && !tflag(env->class_def, tflag_union)) set_tflag(env->class_def, tflag_packed);
567 else ERR_B(stmt_self(stmt)->pos, "`packed` pragma outside of {G+}class{0} or {G+}struct{0} declaration");
568 }
569 8 return GW_OK;
570 }
571
572 ANN static m_bool scan1_stmt_defer(const Env env, const Stmt_Defer stmt) {
573 return scan1_stmt(env, stmt->stmt);
574 }
575
576 1 ANN static m_bool scan1_stmt_spread(const Env env, const Spread_Def spread) {
577 1 ERR_B(stmt_self(spread)->pos, "spread statement outside of variadic environment");
578 }
579
580 DECL_STMT_FUNC(scan1, m_bool, Env)
581
582 2550 ANN static inline m_bool scan1_stmt(const Env env, const Stmt stmt) {
583 2550 return scan1_stmt_func[stmt->stmt_type](env, &stmt->d);
584 }
585
586 2387 ANN static inline bool end_flow(Stmt s) {
587 2387 const ae_stmt_t t = s->stmt_type;
588
2/2
✓ Branch 0 taken 2381 times.
✓ Branch 1 taken 5 times.
2386 return t == ae_stmt_continue ||
589
4/4
✓ Branch 0 taken 2386 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 87 times.
✓ Branch 3 taken 2294 times.
4773 t == ae_stmt_break ||
590 t == ae_stmt_return;
591 }
592
593 2 ANN static void dead_code(const Env env, Stmt_List l, uint32_t len) {
594
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for(uint32_t i = len; i < l->len; i++) {
595 2 const Stmt s = mp_vector_at(l, struct Stmt_, i);
596 2 free_stmt(env->gwion->mp, s);
597 }
598 2 l->len = len;
599 2 }
600
601 2568 ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) {
602 uint32_t i;
603
2/2
✓ Branch 0 taken 2426 times.
✓ Branch 1 taken 2436 times.
4862 for(i = 0; i < l->len; i++) {
604 2426 const Stmt s = mp_vector_at(l, struct Stmt_, i);
605
2/2
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 2387 times.
2426 CHECK_BB(scan1_stmt(env, s));
606
2/2
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 2294 times.
2387 if(end_flow(s)) break;
607 }
608
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2527 times.
2529 if(++i < l->len) dead_code(env, l, i);
609 2529 return GW_OK;
610 }
611
612 7 ANN static m_bool class_internal(const Env env, const Func_Base *base) {
613 assert(base->td);
614
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (!env->class_def)
615 1 ERR_B(base->td->pos, _("'%s' must be in class def!!"), s_name(base->xid))
616
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (base->args)
617 1 ERR_B(base->td->pos, _("'%s' must not have args"), s_name(base->xid))
618
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (base->ret_type != env->gwion->type[et_void])
619 1 ERR_B(base->td->pos, _("'%s' must return 'void'"), s_name(base->xid))
620 4 return GW_OK;
621 }
622
623 6 ANN static inline m_bool scan_internal_arg(const Env env,
624 const Func_Base *base) {
625
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
6 if (mp_vector_len(base->args) == 1) return GW_OK;
626 assert(base->td);
627 1 ERR_B(base->td->pos, _("'%s' must have one (and only one) argument"),
628 s_name(base->xid))
629 }
630
631 3 ANN static inline m_bool scan_internal_int(const Env env,
632 const Func_Base *base) {
633 assert(base->td);
634
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 CHECK_BB(scan_internal_arg(env, base));
635
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (isa(base->ret_type, env->gwion->type[et_int]) > 0) return GW_OK;
636 1 ERR_B(base->td->pos, _("'%s' must return 'int'"), s_name(base->xid))
637 }
638
639 14 ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
640 14 const Symbol op = base->xid;
641
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 9 times.
14 if (op == insert_symbol("@dtor")) {
642
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 if(safe_tflag(env->class_def, tflag_struct))
643 ERR_B(base->pos, "can't use '@dtor' for structures");
644 5 return class_internal(env, base);
645 }
646
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if (op == insert_symbol("@gack"))
647 2 return class_internal(env, base);
648
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (op == insert_symbol("@implicit")) return scan_internal_arg(env, base);
649
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (op == insert_symbol("@conditional") ||
650
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 op == insert_symbol("@unconditional"))
651 3 return scan_internal_int(env, base);
652
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(op == insert_symbol("@array_init") ||
653
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 op == insert_symbol("@each") ||
654 op == insert_symbol("@each_idx") ||
655 op == insert_symbol("@each_init") ||
656 op == insert_symbol("@each_val") ||
657 op == insert_symbol("@partial"))
658 1 ERR_B(base->pos, "operator '%s' not allowed", s_name(op));
659 return GW_OK;
660 }
661
662 29478 ANN static m_bool scan1_fdef_args(const Env env, Arg_List args) {
663
2/2
✓ Branch 0 taken 36656 times.
✓ Branch 1 taken 29478 times.
66134 for(uint32_t i = 0; i < args->len; i++) {
664 36656 Arg *arg = mp_vector_at(args, Arg, i);
665
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36656 times.
36656 CHECK_BB(shadow_arg(env, arg->var_decl.xid, arg->var_decl.pos));
666 }
667 29478 return GW_OK;
668 }
669
670 58003 ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
671
2/2
✓ Branch 0 taken 29478 times.
✓ Branch 1 taken 28525 times.
58003 if (fdef->base->args) {
672
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 29478 times.
29478 CHECK_BB(scan1_fdef_args(env, fdef->base->args));
673
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 29471 times.
29478 CHECK_BB(scan1_args(env, fdef->base->args));
674 }
675
4/4
✓ Branch 0 taken 3073 times.
✓ Branch 1 taken 54923 times.
✓ Branch 2 taken 317 times.
✓ Branch 3 taken 2756 times.
57996 if (!fdef->builtin && fdef->d.code)
676
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 315 times.
317 CHECK_BB(scan1_stmt_list(env, fdef->d.code));
677 57994 return GW_OK;
678 }
679
680 66606 ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
681
2/2
✓ Branch 0 taken 66574 times.
✓ Branch 1 taken 32 times.
66606 if (fdef->base->td)
682
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 66565 times.
66574 CHECK_OB((fdef->base->ret_type = scan1_noret(env, fdef->base)));
683
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 66583 times.
66597 if (fbflag(fdef->base, fbflag_internal))
684
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 8 times.
14 CHECK_BB(scan_internal(env, fdef->base));
685
4/4
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 66567 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 14 times.
66583 else if (fbflag(fdef->base, fbflag_op) && env->class_def)
686 2 SET_FLAG(fdef->base, static);
687
2/2
✓ Branch 1 taken 58003 times.
✓ Branch 2 taken 8588 times.
66591 if(!is_ctor(fdef)) {
688 58003 RET_NSPC(scan1_fbody(env, fdef))
689
2/2
✓ Branch 0 taken 1565 times.
✓ Branch 1 taken 7023 times.
8588 } else if(!fdef->builtin)
690
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 1557 times.
1565 CHECK_BB(scan1_stmt_list(env, fdef->d.code));
691 8580 return GW_OK;
692 }
693
694 86926 ANN static inline m_bool scan1_fdef_defined(const Env env,
695 const Func_Def fdef) {
696 86926 const Value v = nspc_lookup_value1(env->curr, fdef->base->xid);
697
2/2
✓ Branch 0 taken 76654 times.
✓ Branch 1 taken 10272 times.
86926 if (!v) return GW_OK;
698
2/2
✓ Branch 2 taken 10271 times.
✓ Branch 3 taken 1 times.
10272 if (is_func(env->gwion, actual_type(env->gwion, v->type))) return GW_OK; // is_callable
699
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(fdef->builtin) return GW_OK;
700
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
2 if ((!env->class_def || !GET_FLAG(env->class_def, final)) &&
701 1 !nspc_lookup_value0(env->curr, fdef->base->xid))
702 ERR_B(fdef->base->pos,
703 _("function '%s' has already been defined in the same scope..."),
704 s_name(fdef->base->xid))
705 1 return GW_OK;
706 }
707
708 86927 ANN static m_bool _scan1_func_def(const Env env, const Func_Def fdef) {
709
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 86924 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
86927 if(GET_FLAG(fdef->base, abstract) && !env->class_def)
710 ERR_B(fdef->base->pos, "file scope function can't be abstract");
711
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 86926 times.
86927 CHECK_BB(env_storage(env, fdef->base->flag, fdef->base->pos));
712
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 86926 times.
86926 CHECK_BB(scan1_fdef_defined(env, fdef));
713 86926 const bool global = GET_FLAG(fdef->base, global);
714
2/2
✓ Branch 0 taken 86922 times.
✓ Branch 1 taken 4 times.
86926 const m_uint scope = !global ? env->scope->depth : env_push_global(env);
715
2/2
✓ Branch 1 taken 20317 times.
✓ Branch 2 taken 66609 times.
86926 if (tmpl_base(fdef->base->tmpl)) return scan1_fdef_base_tmpl(env, fdef);
716 66609 struct Func_ fake = {.name = s_name(fdef->base->xid), .def = fdef }, *const former =
717 env->func;
718 66609 env->func = &fake;
719 66609 const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)scan1_fdef);
720 66609 env->func = former;
721
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 66605 times.
66609 if (global) env_pop(env, scope);
722
8/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 66603 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 4654 times.
✓ Branch 6 taken 61952 times.
✓ Branch 7 taken 4616 times.
✓ Branch 8 taken 38 times.
66609 if ((strcmp(s_name(fdef->base->xid), "@implicit") || fbflag(fdef->base, fbflag_internal)) && !fdef->builtin && fdef->base->ret_type &&
723
4/4
✓ Branch 0 taken 2799 times.
✓ Branch 1 taken 1817 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 2710 times.
4616 fdef->base->ret_type != env->gwion->type[et_void] && fdef->d.code &&
724
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 74 times.
89 !fake.memoize)
725 15 ERR_B(fdef->base->td->pos,
726 _("missing return statement in a non void function"));
727
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 66592 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
66594 if (fdef->base->xid == insert_symbol("@gack") && !fake.weight) {
728 gwerr_basic(_("`@gack` operator does not print anything"), NULL,
729 _("use `<<<` `>>>` in the function"), env->name, fdef->base->pos, 0);
730 env_set_error(env, true);
731 return GW_ERROR;
732 }
733 66594 return ret;
734 }
735
736 86927 ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) {
737 86927 const uint16_t depth = env->scope->depth;
738 86927 env->scope->depth = 0;
739 86927 const m_bool ret = _scan1_func_def(env, fdef);
740 86927 env->scope->depth = depth;
741 86927 return ret;
742 }
743
744 #define scan1_trait_def dummy_func
745 #define scan1_extend_def dummy_func
746 #define scan1_prim_def dummy_func
747 29814 HANDLE_SECTION_FUNC(scan1, m_bool, Env)
748
749 4163 ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) {
750 4163 const Type parent = tdef->type->info->parent;
751 4163 Type t = parent;
752 do
753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12513 times.
12513 if (tdef->type == t)
754 ERR_O(tdef->ext->pos, _("recursive (%s <= %s) class declaration."),
755 tdef->type->name, t->name)
756
2/2
✓ Branch 0 taken 8350 times.
✓ Branch 1 taken 4163 times.
12513 while ((t = t->info->parent));
757 4163 return parent;
758 }
759
760 4163 ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
761 4163 const loc_t pos = cdef->base.ext->pos;
762
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4157 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
4163 if (cdef->base.ext->array && cdef->base.ext->array->exp)
763
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp));
764
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4163 times.
4163 DECL_OB(const Type, parent, = scan1_get_parent(env, &cdef->base));
765
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4162 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
4164 if (isa(parent, env->gwion->type[et_object]) < 0 &&
766
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_udef)))
767 1 ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
768
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4161 times.
4162 if (type_ref(parent)) ERR_B(pos, _("can't use ref type in class extend"))
769 4161 return GW_OK;
770 }
771
772 4164 ANN static inline Type scan1_final(const Env env, Type_Decl *td, const bool tdef) {
773
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4164 times.
4164 DECL_OO(const Type, t, = known_type(env, td));
774
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4160 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
4164 if (!GET_FLAG(t, final) || tdef) return t;
775 1 ERR_O(td->pos, _("can't inherit from final parent class '%s'\n."), t->name);
776 }
777
778 4164 ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
779
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4163 times.
4164 CHECK_OB((cdef->base.type->info->parent = scan1_final(env, cdef->base.ext, tflag(cdef->base.type, tflag_typedef))));
780 4163 const bool tmpl = !!cdef->base.tmpl;
781
3/4
✓ Branch 0 taken 1357 times.
✓ Branch 1 taken 2806 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1357 times.
4163 if (tmpl) CHECK_BB(template_push_types(env, cdef->base.tmpl));
782 4163 const m_bool ret = scan1_parent(env, cdef);
783
2/2
✓ Branch 0 taken 1357 times.
✓ Branch 1 taken 2806 times.
4163 if (tmpl) nspc_pop_type(env->gwion->mp, env->curr);
784 4163 return ret;
785 }
786
787 4326 ANN static m_bool scan1_class_def_body(const Env env, const Class_Def cdef) {
788
3/4
✓ Branch 1 taken 4326 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1570 times.
✓ Branch 4 taken 2756 times.
4326 if(!tmpl_base(cdef->base.tmpl) && isa(cdef->base.type, env->gwion->type[et_closure]) < 0 &&
789
2/2
✓ Branch 0 taken 1565 times.
✓ Branch 1 taken 5 times.
1570 isa(cdef->base.type, env->gwion->type[et_dict]) < 0) {
790 1565 MemPool mp = env->gwion->mp;
791 1565 Ast base = cdef->body;
792 1565 Stmt_List ctor = new_mp_vector(mp, struct Stmt_, 0);
793 1565 Ast body = new_mp_vector(mp, Section, 1); // room for ctor
794
2/2
✓ Branch 0 taken 24686 times.
✓ Branch 1 taken 1565 times.
26251 for(uint32_t i = 0; i < base->len; i++) {
795 24686 Section section = *mp_vector_at(base, Section, i);
796
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 24512 times.
24686 if(section.section_type == ae_section_stmt) {
797 174 Stmt_List list = section.d.stmt_list;
798
2/2
✓ Branch 0 taken 283 times.
✓ Branch 1 taken 174 times.
457 for(uint32_t j = 0; j < list->len; j++) {
799 283 Stmt stmt = mp_vector_at(list, struct Stmt_, j);
800
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 46 times.
283 mp_vector_add(mp, &ctor, struct Stmt_, *stmt);
801 }
802
2/2
✓ Branch 0 taken 6931 times.
✓ Branch 1 taken 17581 times.
24512 } else mp_vector_add(mp, &body, Section, section);
803 }
804 1565 Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.pos);
805 1565 Symbol sym = insert_symbol("@ctor");
806 1565 Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.pos);
807 1565 Func_Def fdef = new_func_def(mp, fb, ctor);
808 1565 mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef));
809 1565 free_mp_vector(mp, Section, base);
810 1565 cdef->body = body;
811 }
812 4326 return env_body(env, cdef, scan1_section);
813 }
814
815 8453 ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
816
2/2
✓ Branch 1 taken 4081 times.
✓ Branch 2 taken 4372 times.
8453 if (tmpl_base(cdef->base.tmpl)) return GW_OK;
817 4372 const Type t = cdef->base.type;
818
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4372 times.
4372 if (tflag(t, tflag_scan1)) return GW_OK;
819 4372 set_tflag(t, tflag_scan1);
820 4372 const Class_Def c = t->info->cdef;
821
4/4
✓ Branch 0 taken 4164 times.
✓ Branch 1 taken 208 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 4161 times.
4372 if (c->base.ext) CHECK_BB(cdef_parent(env, c));
822
4/4
✓ Branch 0 taken 4326 times.
✓ Branch 1 taken 43 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 4311 times.
4369 if (c->body) CHECK_BB(scan1_class_def_body(env, c));
823 4354 return GW_OK;
824 }
825
826 578 ANN m_bool scan1_ast(const Env env, Ast *ast) {
827 578 Ast a = *ast;
828
2/2
✓ Branch 0 taken 974 times.
✓ Branch 1 taken 512 times.
1486 for(m_uint i = 0; i < a->len; i++) {
829 974 Section *section = mp_vector_at(a, Section, i);
830
2/2
✓ Branch 1 taken 66 times.
✓ Branch 2 taken 908 times.
974 CHECK_BB(scan1_section(env, section));
831 }
832 512 return GW_OK;
833 }
834