Gwion coverage report


Directory: src/
File: src/parse/check.c
Date: 2023-01-30 18:32:28
Exec Total Coverage
Lines: 1308 1532 85.4%
Functions: 151 161 93.8%
Branches: 934 1328 70.3%

Line Branch Exec Source
1 #include <ctype.h>
2 #include "gwion_util.h"
3 #include "gwion_ast.h"
4 #include "gwion_env.h"
5 #include "vm.h"
6 #include "instr.h"
7 #include "traverse.h"
8 #include "template.h"
9 #include "gwion.h"
10 #include "object.h"
11 #include "operator.h"
12 #include "import.h"
13 #include "parse.h"
14 #include "match.h"
15 #include "specialid.h"
16 #include "tmp_resolve.h"
17 #include "partial.h"
18 #include "spread.h"
19 #include "array.h"
20
21 ANN m_bool check_stmt_list(const Env env, Stmt_List list);
22 ANN m_bool check_class_def(const Env env, const Class_Def class_def);
23
24 109 ANN static Type check_internal(const Env env, const Symbol sym, const Exp e,
25 const Type t) {
26 109 struct Implicit imp = {.e = e, .t = t, .pos = e->pos};
27 109 struct Op_Import opi = {.op = sym,
28 109 .lhs = e->type,
29 .rhs = t,
30 109 .data = (uintptr_t)&imp,
31 .pos = e->pos};
32 109 return op_check(env, &opi);
33 }
34
35 160 ANN m_bool check_implicit(const Env env, const Exp e, const Type t) {
36
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 115 times.
160 if (e->type == t) return GW_OK;
37
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 109 times.
115 if (isa(e->type, t) > 0) return GW_OK;
38 109 const Symbol sym = insert_symbol("@implicit");
39
2/2
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 76 times.
109 return (e->cast_to = check_internal(env, sym, e, t)) ? GW_OK : GW_ERROR;
40 }
41
42 45 ANN m_bool check_subscripts(Env env, const Array_Sub array,
43 const m_bool is_decl) {
44
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 45 times.
45 CHECK_OB(check_exp(env, array->exp));
45 45 m_uint depth = 0;
46 45 Exp e = array->exp;
47 do {
48
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 28 times.
59 if (is_decl) {
49
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 30 times.
31 if(check_implicit(env, e, env->gwion->type[et_int]) < 0)
50 1 ERR_B(array->exp->pos, _("invalid array declaration index type."))
51 }
52
3/4
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 44 times.
58 } while (++depth && (e = e->next));
53
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 43 times.
44 if (depth != array->depth)
54 1 ERR_B(array->exp->pos, _("invalid array access expression."))
55 43 return GW_OK;
56 }
57
58 2708 ANN static inline m_bool check_exp_decl_parent(const Env env,
59 const Var_Decl *var) {
60 2708 const Value value = find_value(env->class_def->info->parent, var->xid);
61
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2707 times.
2708 if (value) {
62 1 env_err(env, var->pos, _("Value defined in parent class"));
63 1 defined_here(value);
64 1 return GW_ERROR;
65 }
66 2707 return GW_OK;
67 }
68
69 3363 ANN static m_uint get_decl_size(const Env env, const Value v) {
70
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 3363 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3363 if(safe_tflag(env->class_def, tflag_packed) && v->type->actual_size)
71 return v->type->actual_size;
72 3363 return v->type->size;
73
74 }
75
76 #define describe_check_decl(a, b, flag) \
77 ANN static inline void decl_##a(const Env env, const Value v) { \
78 const Nspc nspc = env->curr; \
79 flag; \
80 v->from->offset = nspc->b; \
81 nspc->b += get_decl_size(env, v); \
82 }
83
84 2695 describe_check_decl(member, offset, v->vflag |= vflag_member);
85 668 describe_check_decl(static, class_data_size, SET_FLAG(v, static));
86
87 19093 ANN static void var_effects(const Env env, const Type t, const Symbol sym, const loc_t loc) {
88
2/2
✓ Branch 0 taken 6990 times.
✓ Branch 1 taken 12103 times.
19093 if (t->info->parent) var_effects(env, t->info->parent, sym, loc);
89
2/2
✓ Branch 1 taken 16362 times.
✓ Branch 2 taken 2731 times.
19093 if(!tflag(t, tflag_ctor)) return;
90 2731 const Value ctor = nspc_lookup_value0(t->nspc, sym);
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2731 times.
2731 if(!ctor) return; // bit sus
92 2731 const Func f = ctor->d.func_ref;
93 2731 const Vector v = &f->def->base->effects;
94
2/2
✓ Branch 0 taken 2730 times.
✓ Branch 1 taken 1 times.
2731 if(!v->ptr) return;
95
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 for (m_uint i = 0; i < vector_size(v); i++)
96 1 env_add_effect(env, (Symbol)vector_at(v, i), loc);
97 }
98
99 12104 ANN static m_bool check_var(const Env env, const Var_Decl *var) {
100
5/6
✓ Branch 0 taken 2711 times.
✓ Branch 1 taken 9393 times.
✓ Branch 2 taken 2708 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 2708 times.
✗ Branch 5 not taken.
12104 if (env->class_def && !env->scope->depth && env->class_def->info->parent)
101
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2707 times.
2708 CHECK_BB(check_exp_decl_parent(env, var));
102 12103 var_effects(env, var->value->type, insert_symbol("@ctor"), var->pos);
103 12103 return GW_OK;
104 }
105
106 12103 ANN static m_bool check_var_td(const Env env, const Var_Decl *var,
107 Type_Decl *const td) {
108 12103 const Value v = var->value;
109
2/2
✓ Branch 0 taken 2710 times.
✓ Branch 1 taken 9393 times.
12103 if (env->class_def) {
110
2/2
✓ Branch 1 taken 2695 times.
✓ Branch 2 taken 15 times.
2710 if (vflag(v, vflag_member)) {
111 2695 decl_member(env, v);
112
1/2
✓ Branch 0 taken 2695 times.
✗ Branch 1 not taken.
2695 if (env->class_def->info->tuple) tuple_info(env, v);
113
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3 times.
15 } else if (GET_FLAG(td, static))
114 12 decl_static(env, v);
115 }
116 12103 return GW_OK;
117 }
118
119 12104 ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
120 12104 const Var_Decl *vd = &decl->vd;
121
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12103 times.
12104 CHECK_BB(check_var(env, vd));
122
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12103 times.
12103 CHECK_BB(check_var_td(env, vd, decl->td));
123
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 12087 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
12103 if (decl->td->array && decl->td->array->exp) {
124
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 15 times.
16 CHECK_BB(check_subscripts(env, decl->td->array, true));
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (GET_FLAG(array_base(decl->type), abstract))
126 CHECK_BB(check_array_instance(env, decl->td, decl->args));
127 }
128 12102 valid_value(env, vd->xid, vd->value);
129 // set_vflag(var->value, vflag_used));
130 12102 return GW_OK;
131 }
132
133 12107 ANN /*static inline*/ m_bool ensure_check(const Env env, const Type t) {
134
6/6
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 12064 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 11 times.
✓ Branch 7 taken 28 times.
✓ Branch 8 taken 4 times.
12107 if (tflag(t, tflag_check) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
135 12092 return GW_OK;
136
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 11 times.
15 if(!tflag(t, tflag_tmpl)) return GW_OK;
137 11 struct EnvSet es = {.env = env,
138 .data = env,
139 .func = (_exp_func)check_cdef,
140 11 .scope = env->scope->depth,
141 .flag = tflag_check};
142 11 return envset_run(&es, t);
143 }
144
145 4194 ANN m_bool ensure_traverse(const Env env, const Type t) {
146
6/6
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4190 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 1 times.
4194 if (tflag(t, tflag_check) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
147 4192 return GW_OK;
148
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if(!tflag(t, tflag_tmpl)) return GW_OK;
149 1 struct EnvSet es = {.env = env,
150 .data = env,
151 .func = (_exp_func)traverse_cdef,
152 1 .scope = env->scope->depth,
153 .flag = tflag_check};
154 1 return envset_run(&es, t);
155 }
156
157 12107 ANN static inline m_bool inferable(const Env env, const Type t,
158 const loc_t pos) {
159
2/2
✓ Branch 1 taken 12104 times.
✓ Branch 2 taken 3 times.
12107 if (!tflag(t, tflag_infer)) return GW_OK;
160 3 ERR_B(pos, _("can't infer type."))
161 }
162
163 12114 ANN Type check_exp_decl(const Env env, Exp_Decl *const decl) {
164
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 12098 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
12114 if (decl->td->array && decl->td->array->exp)
165
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
16 CHECK_OO(check_exp(env, decl->td->array->exp));
166
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 12103 times.
12114 if (decl->args) {
167 11 const Exp e = new_exp_unary2(env->gwion->mp, insert_symbol("new"), cpy_type_decl(env->gwion->mp, decl->td), decl->args, decl->td->pos);
168
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 4 times.
11 CHECK_OO(check_exp(env, e));
169 4 decl->args = e;
170 4 e->ref = exp_self(decl);
171 }
172
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12098 times.
12107 if (decl->td->xid == insert_symbol("auto")) { // should be better
173
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 CHECK_BO(scan1_exp(env, exp_self(decl)));
174
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 CHECK_BO(scan2_exp(env, exp_self(decl)));
175 }
176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12107 times.
12107 if (!decl->type) ERR_O(decl->td->pos, _("can't find type"));
177 {
178
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12107 times.
12107 CHECK_BO(ensure_check(env, decl->type));
179
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 12104 times.
12107 if(inferable(env, decl->type, decl->td->pos) < 0) {
180
5/8
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
3 if(!tflag(decl->type, tflag_check) && decl->type->ref > 1 && env->class_def && !env->scope->depth)
181 1 type_remref(decl->type, env->gwion);
182 3 return NULL;
183 }
184 }
185 12104 const m_bool global = GET_FLAG(decl->td, global);
186
2/2
✓ Branch 0 taken 12099 times.
✓ Branch 1 taken 5 times.
12104 const m_uint scope = !global ? env->scope->depth : env_push_global(env);
187 12104 const m_bool ret = check_decl(env, decl);
188
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 12099 times.
12104 if (global) {
189 5 env_pop(env, scope);
190 5 set_vflag(decl->vd.value, vflag_direct);
191 }
192 12104 env_weight(env, 1 + isa(decl->type, env->gwion->type[et_object]) > 0);
193
2/2
✓ Branch 0 taken 12102 times.
✓ Branch 1 taken 2 times.
12104 return ret > 0 ? decl->vd.value->type : NULL;
194 }
195
196 65 ANN static m_bool check_collection(const Env env, Type type, const Exp e,
197 65 const loc_t loc) {
198 65 const Type common = find_common_anc(e->type, type);
199
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 6 times.
65 if (common) return GW_OK;
200
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
6 if (check_implicit(env, e, type) > 0) return GW_OK;
201
202 3 char fst[20 + strlen(type->name)];
203 3 sprintf(fst, "expected `{+/}%s{0}`", type->name);
204 3 gwerr_basic(_("literal contains incompatible types"), fst, "the first element determines the type", env->name,
205 loc, 0);
206 // suggested fix: rewrite int 2 as float 2.0"
207 3 char sec[16 + strlen(e->type->name)];
208 3 sprintf(sec, "got `{+/}%s{0}`", e->type->name);
209 3 gwerr_secondary(sec, env->name, e->pos);
210 3 return GW_ERROR;
211 }
212
213 20 ANN static inline Type prim_array_match(const Env env, Exp e) {
214 20 const Type type = e->type;
215 20 bool err = false;
216 20 const loc_t loc = e->pos;
217 do
218
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 49 times.
51 if (check_collection(env, type, e, loc) < 0) err = true;
219
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 20 times.
51 while ((e = e->next));
220
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
20 if (!err) return array_type(env, array_base_simple(type), type->array_depth + 1);
221 2 env_set_error(env, true);
222 2 return NULL;
223 }
224
225 23 ANN static Type check_prim_array(const Env env, const Array_Sub *data) {
226 23 const Array_Sub array = *data;
227 23 const Exp e = array->exp;
228
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 22 times.
23 if (!e)
229 1 ERR_O(prim_pos(data), _("must provide values/expressions for array [...]"))
230
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 20 times.
22 CHECK_OO(check_exp(env, e));
231 20 env_weight(env, 1);
232 20 return array->type = prim_array_match(env, e);
233 }
234
235 12 ANN static m_bool check_range(const Env env, Range *range) {
236
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_OB(check_exp(env, range->start));
237
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_OB(check_exp(env, range->end));
238
4/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 4 times.
12 if (range->start && range->end) {
239
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (isa(range->end->type, range->start->type) < 0)
240 1 ERR_B(range->start->pos, _("range types do not match"))
241 }
242 11 return GW_OK;
243 }
244
245 3 ANN static Type check_prim_range(const Env env, Range **data) {
246 3 Range *range = *data;
247
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 CHECK_BO(check_range(env, range));
248 2 env_weight(env, 1);
249
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 const Exp e = range->start ?: range->end;
250 assert(e);
251 2 const Symbol sym = insert_symbol("[:]");
252 4 struct Op_Import opi = {.op = sym,
253 2 .lhs = e->type,
254 .pos = e->pos,
255 2 .data = (uintptr_t)prim_exp(data)};
256 2 return op_check(env, &opi);
257 }
258
259 3 ANN static Type check_prim_dict(const Env env, Exp *data) {
260 3 const Exp base = *data;
261
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 CHECK_OO(check_exp(env, base));
262 3 const Type key = base->type;
263 3 const Type val = base->next->type;
264 3 bool err = false;
265 3 const loc_t loc = base->pos;
266 3 Exp e = base;
267 3 env_weight(env, 1);
268 do {
269
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (check_collection(env, key, e, loc) < 0) err = true;
270 7 e = e->next;
271
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
7 if (check_collection(env, val, e, loc) < 0) err = true;
272
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
7 } while ((e = e->next));
273
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (!err) return dict_type(env->gwion, key, val, base->pos);
274 1 env_set_error(env, true); return NULL;
275 }
276
277 575 ANN m_bool not_from_owner_class(const Env env, const Type t, const Value v,
278 const loc_t pos) {
279
2/4
✓ Branch 0 taken 575 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 575 times.
575 if (!v->from->owner_class || isa(t, v->from->owner_class) < 0) {
280 if(!is_class(env->gwion, v->type))
281 ERR_B(pos, _("'%s' from owner namespace '%s' used in '%s'."), v->name,
282 v->from->owner ? v->from->owner->name : "?", t->name)
283 }
284 575 return GW_OK;
285 }
286
287 1351 ANN static inline Value get_value(const Env env, const Symbol sym) {
288 1351 const Value value = nspc_lookup_value1(env->curr, sym);
289
2/2
✓ Branch 0 taken 1330 times.
✓ Branch 1 taken 21 times.
1351 if(value) {
290
4/4
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 1213 times.
✓ Branch 2 taken 115 times.
✓ Branch 3 taken 2 times.
1330 if (!value->from->owner_class || isa(env->class_def, value->from->owner_class) > 0)
291 1328 return value;
292
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(env->class_def) {
293
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (isa(env->class_def, value->from->owner_class) > 0 || value == env->class_def->info->value)
294 return value;
295
296 }
297 }
298
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 4 times.
23 if (env->func && env->func->def->base->values) {
299
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 DECL_OO(const Value, v, = upvalues_lookup(env->func->def->base->values, sym));
300
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if(fbflag(env->func->def->base, fbflag_lambda))
301
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 CHECK_OO(not_upvalue(env, v));
302 8 return v;
303 }
304 15 return NULL;
305 }
306
307 3 ANN static inline bool is_value_global(const Env env, const Value v) {
308
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(GET_FLAG(v, global)) return true;
309 return from_global_nspc(env, v->from->owner);
310 }
311
312 1351 ANN static Value check_non_res_value(const Env env, const Symbol *data) {
313 1351 const Symbol var = *data;
314 1351 const Value value = get_value(env, var);
315
2/2
✓ Branch 0 taken 223 times.
✓ Branch 1 taken 1128 times.
1351 if (env->class_def) {
316
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 3 times.
223 if (value) {
317
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 103 times.
220 if(value->from->owner_class)
318
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 117 times.
117 CHECK_BO(not_from_owner_class(env,
319 env->class_def, value, prim_pos(data)));
320 }
321
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 220 times.
223 const Value v = value ?: find_value(env->class_def, var);
322
2/2
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 2 times.
223 if (v) {
323
5/6
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 196 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 23 times.
246 if (env->func && GET_FLAG(env->func->def->base, static) &&
324 25 vflag(v, vflag_member))
325 2 ERR_O(prim_pos(data),
326 _("non-static member '%s' used from static function."),
327 s_name(var))
328 }
329 221 return v;
330
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1128 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1128 } else if (SAFE_FLAG(env->class_def, global) ||
331
4/4
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 904 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 220 times.
1128 (env->func && GET_FLAG(env->func->def->base, global))) {
332
3/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4 if (!value || !(is_value_global(env, value) || vflag(value, vflag_arg)))
333 1 ERR_O(prim_pos(data),
334 _("non-global variable '%s' used from global function/class."),
335 s_name(var))
336
4/4
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 904 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 214 times.
1124 } else if(env->func && fbflag(env->func->def->base, fbflag_locale)) {
337
3/6
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6 if(!is_func(env->gwion, value->type) && value->from->owner && !from_global_nspc(env, value->from->owner)) // is_callable
338 ERR_O(prim_pos(data), _("invalid variable access from locale definition"));
339 }
340 1127 return value;
341 }
342
343 467 ANN static Type check_dot(const Env env, const Exp_Dot *member) {
344 934 struct Op_Import opi = {.op = insert_symbol("."),
345 467 .lhs = member->base->type,
346 467 .data = (uintptr_t)member,
347 467 .pos = exp_self(member)->pos};
348 467 env_weight(env, 1);
349 467 return op_check(env, &opi);
350 }
351
352 15 ANN static m_bool check_upvalue(const Env env, const Exp_Primary *prim, const Value v) {
353
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 if(not_upvalue(env, v))
354 15 return GW_OK;
355 gwerr_basic(_("value not in lambda scope"), NULL, NULL, env->name, exp_self(prim)->pos, 4242);
356 declared_here(v);
357 gw_err("{-}hint:{0} try adding it to capture list");
358 env_set_error(env, true);
359 return GW_ERROR;
360 }
361
362 116 ANN static Type prim_owned(const Env env, const Symbol *data) {
363 116 const Exp exp = exp_self(prim_exp(data));
364 116 const Value v = exp->d.prim.value;
365
3/4
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
116 if(is_class(env->gwion, v->type) && env->class_def == v->type->info->base_type) // write it better
366 return v->type->info->base_type;
367
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 100 times.
116 const m_str name = !GET_FLAG(v, static) ? "this" : v->from->owner_class->name;
368 const Exp base =
369 116 new_prim_id(env->gwion->mp, insert_symbol(name), prim_pos(data));
370 116 exp_setuse(base, 1);
371 116 exp->exp_type = ae_exp_dot;
372 116 exp->d.exp_dot.base = base;
373 116 exp->d.exp_dot.xid = *data;
374 116 return check_exp(env, exp);
375 }
376
377 1351 ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
378 1351 const Symbol sym = *data;
379 1351 const Value v = check_non_res_value(env, data);
380
6/8
✓ Branch 0 taken 1335 times.
✓ Branch 1 taken 16 times.
✓ Branch 3 taken 1335 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 769 times.
✓ Branch 6 taken 566 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 769 times.
1351 if (!v || !vflag(v, vflag_valid) || (v->from->ctx && v->from->ctx->error)) {
381 16 const m_str name = s_name(*data);
382
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
16 if (!isalpha(*name) && *name != '_') {
383 3 prim_self(data)->value = env->gwion->type[et_op]->info->value;
384 3 return env->gwion->type[et_op];
385 }
386
3/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
13 if (env->func && fbflag(env->func->def->base, fbflag_lambda) && env->func->def->base->values) {
387 const Value v = upvalues_lookup(env->func->def->base->values, sym);
388 if(v) {
389 CHECK_BO(check_upvalue(env, prim_self(data), v));
390 return v->type;
391 }
392 }
393 13 gwerr_basic(_("Invalid variable"), _("not legit at this point."), NULL,
394 13 env->name, prim_pos(data), 0);
395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 did_you_mean_nspc(v ? v->from->owner : env->curr, s_name(sym));
396 13 env_set_error(env, true);
397 13 return NULL;
398 }
399 1335 prim_self(data)->value = v;
400
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 1219 times.
1335 if (v->from->owner_class) return prim_owned(env, data);
401
2/2
✓ Branch 0 taken 392 times.
✓ Branch 1 taken 827 times.
1219 if (GET_FLAG(v, const)) exp_setmeta(prim_exp(data), 1);
402
403
4/4
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 893 times.
✓ Branch 2 taken 299 times.
✓ Branch 3 taken 27 times.
1219 if (env->func && strcmp(env->func->name, "in spork")) {
404 // if(vflag(v, vflag_fglobal) /*&& !vflag(v, vflag_builtin) */&& !is_func(env->gwion, v->type)) {
405
8/8
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 23 times.
✓ Branch 3 taken 37 times.
✓ Branch 4 taken 239 times.
✓ Branch 6 taken 40 times.
✓ Branch 7 taken 20 times.
✓ Branch 9 taken 9 times.
✓ Branch 10 taken 31 times.
299 if((GET_FLAG(v, global) || vflag(v, vflag_fglobal)) && !vflag(v, vflag_builtin) && !is_func(env->gwion, v->type)) {
406
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
9 if(!env->func->_wait)
407 7 env->func->_wait = new_mp_vector(env->gwion->mp, Value, 0);
408
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 if (!v->used_by) {
409 6 v->used_by = new_mp_vector(env->gwion->mp, Func, 1);
410 6 mp_vector_set(v->used_by, Func, 0, env->func);
411
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 mp_vector_add(env->gwion->mp, &env->func->_wait, Value, v);
412 } else {
413 3 bool found = false;
414
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 for(uint32_t i = 0; i < v->used_by->len; i++) {
415 3 const Func f = *mp_vector_at(v->used_by, Func, i);
416
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if(f == env->func) {
417 1 found = true;
418 1 break;
419 }
420 }
421
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if(!found) {
422
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 mp_vector_add(env->gwion->mp, &v->used_by, Func, env->func);
423
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 mp_vector_add(env->gwion->mp, &env->func->_wait, Value, v);
424 }
425 }
426 }
427
428
4/4
✓ Branch 0 taken 227 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 218 times.
299 if (!GET_FLAG(v, const) && v->from->owner)
429 9 unset_fflag(env->func, fflag_pure);
430
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 284 times.
299 if (fbflag(env->func->def->base, fbflag_lambda))
431
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
15 CHECK_BO(check_upvalue(env, prim_self(data), v));
432 }
433 // set_vflag(v->vflag, vflag_used);
434 1219 return v->type;
435 }
436
437 325 ANN Type check_prim_str(const Env env, const struct AstString *data) {
438
2/2
✓ Branch 1 taken 323 times.
✓ Branch 2 taken 2 times.
325 if (!prim_self(data)->value)
439 323 prim_self(data)->value = global_string(env, data->data, prim_pos(data));
440 325 exp_setmeta(prim_exp(data), true);
441 325 return env->gwion->type[et_string]; // prim->value
442 }
443
444 1734 ANN static Type check_prim_id(const Env env, const Symbol *data) {
445 1734 struct SpecialId_ *spid = specialid_get(env->gwion, *data);
446
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 1351 times.
1734 if (spid) return specialid_type(env, spid, prim_self(data));
447 1351 return prim_id_non_res(env, data);
448 }
449
450 3 ANN static Type check_prim_perform(const Env env, const Symbol *data) {
451
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(*data) env_add_effect(env, *data, prim_pos(data));
452 else if(!env->scope->in_try)
453 ERR_O(prim_pos(data), "`rethrow` outside try/handle statement");
454 3 env_weight(env, 1);
455 3 return env->gwion->type[et_void];
456 }
457
458 739 ANN static Type check_prim_interp(const Env env, const Exp *exp) {
459
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 707 times.
739 CHECK_OO(check_exp(env, *exp));
460 707 env_weight(env, 1);
461 707 return env->gwion->type[et_string];
462 }
463
464 720 ANN static Type check_prim_hack(const Env env, const Exp *data) {
465
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 501 times.
720 if (env->func) unset_fflag(env->func, fflag_pure);
466
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 688 times.
720 CHECK_OO(check_prim_interp(env, data));
467 688 env_weight(env, 1);
468 688 return env->gwion->type[et_gack];
469 }
470
471 4 ANN static Type check_prim_locale(const Env env, const Symbol *data NUSED) {
472 4 exp_setmeta(prim_exp(data), true);
473 4 return env->gwion->type[et_float];
474 }
475
476 #define describe_prim_xxx(name, type) \
477 ANN static Type check_prim_##name(const Env env NUSED, \
478 const union prim_data *data NUSED) { \
479 return type; \
480 }
481
482 564 describe_prim_xxx(num, env->gwion->type[et_int]);
483 22 describe_prim_xxx(char, env->gwion->type[et_char]);
484 72 describe_prim_xxx(float, env->gwion->type[et_float]);
485 9 describe_prim_xxx(nil, env->gwion->type[et_void]);
486
487 DECL_PRIM_FUNC(check, Type, Env);
488
489 3501 ANN static Type check_prim(const Env env, Exp_Primary *prim) {
490 3501 return exp_self(prim)->type = check_prim_func[prim->prim_type](env, &prim->d);
491 }
492
493 21 ANN Type check_array_access(const Env env, const Array_Sub array) {
494 21 const Symbol sym = insert_symbol("[]");
495 21 struct Op_Import opi = {.op = sym,
496 21 .lhs = array->exp->type,
497 21 .rhs = array->type,
498 21 .pos = array->exp->pos,
499 21 .data = (uintptr_t)array};
500 21 return op_check(env, &opi);
501 }
502
503 23 static ANN Type check_exp_array(const Env env, const Exp_Array *array) {
504
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 22 times.
23 CHECK_OO((array->array->type = check_exp(env, array->base)));
505
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 21 times.
22 CHECK_BO(check_subscripts(env, array->array, 0));
506
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 18 times.
21 if(exp_getmeta(array->base)) exp_setmeta(exp_self(array), true);
507 21 return check_array_access(env, array->array);
508 }
509
510 9 static ANN Type check_exp_slice(const Env env, const Exp_Slice *range) {
511
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 CHECK_OO(check_exp(env, range->base));
512
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 CHECK_BO(check_range(env, range->range));
513 9 env_weight(env, 1);
514 9 const Symbol sym = insert_symbol("[:]");
515
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 const Exp e = range->range->start ?: range->range->end;
516 assert(e);
517 18 struct Op_Import opi = {.op = sym,
518 9 .lhs = e->type,
519 9 .rhs = range->base->type,
520 .pos = e->pos,
521 9 .data = (uintptr_t)exp_self(range)};
522 9 return op_check(env, &opi);
523 }
524
525 // get the type of the function
526 // without the mangling
527 ANN static inline Type type_list_base_func(const Type type) {
528 const Nspc owner = type->info->value->from->owner;
529 const Symbol xid = type->info->func->def->base->xid;
530 return nspc_lookup_type0(owner, xid);
531 }
532
533 43 ANN static inline Type type_list_base(const Gwion gwion, const Type type) {
534
1/2
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
43 return !(is_func(gwion, type)) ? type : type_list_base_func(type);
535 }
536
537 43 ANN static Type_Decl* mk_td(const Env env, Type_Decl *td,
538 const Type type, const loc_t pos) {
539 43 const Type base = type_list_base(env->gwion, type);
540 86 const Type t = !td->array ?
541
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 base : array_type(env, base, td->array->depth);
542 43 return type2td(env->gwion, t, pos);
543 }
544
545 49 ANN static Type tmpl_arg_match(const Env env, const Symbol xid, const Symbol tgt, const Type t) {
546
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 6 times.
49 if (xid == tgt) return t;
547
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 if(!tflag(t, tflag_cdef)) return NULL;
548 const uint32_t len = mp_vector_len(t->info->cdef->base.tmpl->list);
549 for(uint32_t i = 0; i < len; i++) {
550 Specialized *spec = mp_vector_at(t->info->cdef->base.tmpl->list, Specialized, i);
551 const Type base = nspc_lookup_type1(t->nspc, spec->xid);
552 const Type t = tmpl_arg_match(env, xid, spec->xid, base);
553 if(t) return t;
554 }
555 return NULL;
556 }
557
558 ANN2(1, 2)
559 735 static Func find_func_match_actual(const Env env, const Func f, const Exp exp,
560 const bool implicit, const bool specific) {
561 735 Func func = f;
562 do {
563 836 Exp e = exp;
564 836 Arg_List args = func->def->base->args;
565 836 m_uint i = 0;
566 836 const m_uint args_len = mp_vector_len(args);
567
2/2
✓ Branch 0 taken 762 times.
✓ Branch 1 taken 471 times.
1233 while (e) {
568 762 e->cast_to = NULL;
569
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 758 times.
762 if (!e->type) // investigate
570 4 return NULL;
571
2/2
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 146 times.
758 Arg *arg = i < args_len ? mp_vector_at(args, Arg, i++) : NULL;
572
2/2
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 612 times.
758 if (!arg) {
573
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 121 times.
146 CHECK_OO(func->next);
574 121 return find_func_match_actual(env, func->next, exp, implicit,
575 specific);
576 }
577
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 612 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
612 if (tflag(e->type, tflag_ref) && isa(e->type, arg->type) > 0) {
578 if(!e->cast_to)e->cast_to = arg->type;
579 }
580
581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 612 times.
612 if (arg->type == env->gwion->type[et_auto]) {
582 const Type owner = func->value_ref->from->owner_class;
583 if (owner) CHECK_BO(template_push(env, owner));
584 arg->type = known_type(env, arg->td);
585 if (owner) nspc_pop_type(env->gwion->mp, env->curr);
586 CHECK_OO(arg->type);
587 }
588
589
2/2
✓ Branch 1 taken 215 times.
✓ Branch 2 taken 397 times.
612 if (!func_match_inner(env, e, arg->type, implicit, specific)) break;
590 397 e = e->next;
591 }
592
4/4
✓ Branch 0 taken 471 times.
✓ Branch 1 taken 215 times.
✓ Branch 2 taken 401 times.
✓ Branch 3 taken 70 times.
686 if (!e && args_len == i) return func;
593
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 184 times.
285 } while ((func = func->next));
594 184 return NULL;
595 }
596
597 ANN static Type check_exp_call(const Env env, Exp_Call *exp);
598
599 2 ANN static Func call2ufcs(const Env env, Exp_Call *call, const Value v) {
600 2 const Exp this = call->func->d.exp_dot.base;
601 2 this->next = call->args;
602 2 call->args = this;
603 2 call->func->type = v->type;
604 2 call->func->d.prim.value = v;
605 2 call->func->d.prim.d.var = call->func->d.exp_dot.xid;
606 2 call->func->exp_type = ae_exp_primary;
607 2 call->func->d.prim.prim_type = ae_prim_id;
608
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 CHECK_OO(check_exp_call(env, call));
609 2 return call->func->type->info->func;
610 }
611
612 37 ANN static Func ufcs(const Env env, const Func up, Exp_Call *const call) {
613 37 const Value v = nspc_lookup_value1(env->curr, up->def->base->xid);
614
5/6
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 18 times.
✓ Branch 3 taken 19 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 18 times.
37 if (v && is_func(env->gwion, v->type) && !v->from->owner_class) // is_callable
615 1 return call2ufcs(env, call, v);
616 36 return NULL;
617 }
618
619 447 ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) {
620 Func func;
621 447 const Exp exp = call->args;
622 447 const Exp args =
623
4/4
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 193 times.
✓ Branch 2 taken 246 times.
✓ Branch 3 taken 8 times.
447 (exp && isa(exp->type, env->gwion->type[et_void]) < 0) ? exp : NULL;
624
4/4
✓ Branch 1 taken 75 times.
✓ Branch 2 taken 372 times.
✓ Branch 3 taken 46 times.
✓ Branch 4 taken 29 times.
522 if ((func = find_func_match_actual(env, up, args, false, true)) ||
625
1/2
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
121 (func = find_func_match_actual(env, up, args, true, true)) ||
626
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
92 (func = find_func_match_actual(env, up, args, false, true)) ||
627 46 (func = find_func_match_actual(env, up, args, true, false)))
628 401 return func;
629
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 return call->func->exp_type == ae_exp_dot && up->value_ref->from->owner_class
630 37 ? ufcs(env, up, call)
631
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 9 times.
83 : NULL;
632 }
633
634 43 ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) {
635 43 struct Vector_ v = {};
636 43 const m_uint scope = env->scope->depth;
637 43 env->scope->depth = 0;
638 43 vector_init(&v);
639 43 const Vector w = (Vector)&env->curr->info->value->ptr;
640 43 m_uint i = vector_size(w);
641
2/2
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 43 times.
54 while (i-- > 1) vector_add(&v, vector_at(w, i));
642 43 VLEN(w) = 1;
643 43 const m_bool ret = traverse_func_def(env, fdef);
644
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 43 times.
54 for (m_uint i = vector_size(&v) + 1; --i;)
645 11 vector_add(w, vector_at(&v, i - 1));
646 43 vector_release(&v);
647 43 env->scope->depth = scope;
648 43 return ret;
649 }
650
651 29444 ANN static m_bool check_func_args(const Env env, Arg_List args) {
652
2/2
✓ Branch 0 taken 36612 times.
✓ Branch 1 taken 29443 times.
66055 for(uint32_t i = 0; i < args->len; i++) {
653 36612 Arg *arg = mp_vector_at(args, Arg, i);
654 36612 const Var_Decl *decl = &arg->var_decl;
655 36612 const Value v = decl->value;
656
4/4
✓ Branch 0 taken 36574 times.
✓ Branch 1 taken 38 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 36573 times.
36612 if(decl->xid) CHECK_BB(already_defined(env, decl->xid, decl->pos));
657 36611 valid_value(env, decl->xid, v);
658 }
659 29443 return GW_OK;
660 }
661
662 #define next_arg(type) \
663 ANN static inline type next_arg_##type(const type e) { \
664 const type next = e->next; \
665 if (next) gw_err(", "); \
666 return next; \
667 }
668
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 next_arg(Exp)
669 //next_arg(Arg_List);
670
671 7 ANN static void print_current_args(Exp e) {
672 7 gw_err(_("and not\n "));
673
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 do gw_err(" {G}%s{0}", e->type ? e->type->name : "<Unknown>");
674
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 7 times.
10 while ((e = next_arg_Exp(e)));
675 7 gw_err("\n");
676 7 }
677
678 ANN2(1)
679 17 static void function_alternative(const Env env, const Type t, const Exp args,
680 const loc_t pos) {
681
3/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 9 times.
17 if (env->context && env->context->error) // needed for ufcs
682 8 return;
683 9 gwerr_basic("Argument type mismatch", "call site",
684 9 "valid alternatives:", env->name, pos, 0);
685 9 const bool is_closure = isa(t, env->gwion->type[et_closure]) < 0;
686 9 Func up = is_closure
687
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
9 ? t->info->func : closure_def(t)->base->func;
688 10 do print_signature(up);
689
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
10 while ((up = up->next));
690
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
9 if (args)
691 7 print_current_args(args);
692 else
693 2 gw_err(_("and not:\n {G}void{0}\n"));
694 9 env_set_error(env, true);
695 }
696
697 41 ANN static Func get_template_func(const Env env, Exp_Call *const func,
698 const Value v) {
699 41 const Func f = find_template_match(env, v, func);
700
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 2 times.
41 if (f) {
701 39 Tmpl *tmpl = new_tmpl_call(env->gwion->mp, func->tmpl->call);
702 78 tmpl->list = v->d.func_ref
703 39 ? v->d.func_ref->def->base->tmpl->list
704
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 : func->func->type->info->func->def->base->tmpl->list;
705 39 ((Exp_Call *)func)->tmpl = tmpl;
706 39 func->func->type = f->value_ref->type;
707 39 return f;
708 }
709 2 ((Exp_Call *)func)->tmpl = NULL;
710 assert(exp_self(func));
711 2 ERR_O(exp_self(func)->pos,
712 _("function is a template for which automatic type inference is not fully implemented"));
713 }
714
715 ANN static Func predefined_func(const Env env, const Value v, Exp_Call *exp,
716 const Tmpl *tm) {
717 Tmpl tmpl = {.call = tm->call};
718 exp->tmpl = &tmpl;
719 DECL_OO(const Func, func, = get_template_func(env, exp, v));
720 return v->d.func_ref = func;
721 }
722
723 ANN static Type check_predefined(const Env env, Exp_Call *exp, const Value v,
724 const Tmpl *tm, const Func_Def fdef) {
725 DECL_OO(const Func, func,
726 = v->d.func_ref ?: predefined_func(env, v, exp, tm));
727 if (!fdef->base->ret_type) { // template fptr
728 struct EnvSet es = {.env = env,
729 .data = env,
730 .func = (_exp_func)check_cdef,
731 .scope = env->scope->depth,
732 .flag = tflag_check};
733 CHECK_BO(envset_pushv(&es, v));
734 func->def->base->fbflag |= fbflag_internal;
735 const m_bool ret = check_traverse_fdef(env, func->def);
736 envset_pop(&es, v->from->owner_class);
737 CHECK_BO(ret);
738 }
739 exp->func->type = func->value_ref->type;
740 return func->def->base->ret_type;
741 }
742
743 43 ANN static Type_List check_template_args(const Env env, Exp_Call *exp,
744 const Tmpl *tm, const Func_Def fdef) {
745 43 Specialized_List sl = tm->list;
746 43 const bool spread = is_spread_tmpl(fdef->base->tmpl);
747 43 const uint32_t len = sl->len - spread;
748 43 Type_List tl = new_mp_vector(env->gwion->mp, Type_Decl*, len);
749 43 m_uint args_number = 0;
750
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if(exp->other) {
752 for(uint32_t i = 0; i < len; i++) {
753 Specialized *spec = mp_vector_at(sl, Specialized, i);
754 if (tmpl_arg_match(env, spec->xid, fdef->base->td->xid, fdef->base->ret_type)) {
755 CHECK_OO(check_exp(env, exp->other));
756 if(!is_func(env->gwion, exp->other->type)) {
757 Type_Decl *td = type2td(env->gwion, exp->other->type, fdef->base->td->pos);
758 mp_vector_set(tl, Type_Decl*, 0, td);
759 } else {
760 Func func = exp->other->type->info->func;
761 do {
762 if(mp_vector_len(func->def->base->args) == 1) {
763 Arg *arg = mp_vector_at(func->def->base->args, Arg, 0);
764 Type_Decl *td = cpy_type_decl(env->gwion->mp, arg->td);
765 mp_vector_set(tl, Type_Decl*, 0, td);
766 break;
767 }
768 } while((func = func->next));
769 }
770 ++args_number;
771 break;
772 }
773 }
774 }
775
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 43 times.
89 for(uint32_t i = 0; i < len; i++) {
776 46 Specialized *spec = mp_vector_at(sl, Specialized, i);
777 46 Arg_List args = fdef->base->args;
778 46 const uint32_t args_len = mp_vector_len(args);
779 46 Exp template_arg = exp->args;
780 46 uint32_t count = 0;
781
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
52 while (count < args_len && template_arg) {
782 49 Arg *arg = mp_vector_at(args, Arg, count);
783
2/2
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 6 times.
49 if (tmpl_arg_match(env, spec->xid, arg->td->xid, template_arg->type)) {
784 43 mp_vector_set(tl, Type_Decl*, args_number,
785 mk_td(env, arg->td, template_arg->type, fdef->base->pos));
786 43 ++args_number;
787 43 break;
788 }
789 6 count++;
790 6 template_arg = template_arg->next;
791 }
792 }
793
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 41 times.
43 if (args_number < len) //TODO: free type_list
794 2 ERR_O(exp->func->pos, _("not able to infer types for template call."))
795
796
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39 times.
41 if(spread) {
797 2 Exp e = exp->args;
798
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(fdef->base->args)
799 for(uint32_t i = 0; i < fdef->base->args->len && e; i++) e = e->next;
800
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 while(e) {
801
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 mp_vector_add(env->gwion->mp, &tl, Type_Decl*, type2td(env->gwion, e->type, e->pos));
802 2 e = e->next;
803 }
804 }
805 41 return tl;
806 }
807
808 43 ANN static Type check_exp_call_template(const Env env, Exp_Call *exp) {
809 43 /*const */Type t = exp->func->type;
810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if(isa(t, env->gwion->type[et_closure]) > 0) {
811 const Func_Def fdef = closure_def(t);
812 t = fdef->base->func->value_ref->type;
813 }
814
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
43 DECL_OO(const Value, value, = type_value(env->gwion, t));
815 43 const Func_Def fdef =
816
1/2
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
43 value->d.func_ref ? value->d.func_ref->def : t->info->func->def;
817 43 Tmpl *tm = fdef->base->tmpl;
818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (tm->call) return check_predefined(env, exp, value, tm, fdef);
819
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 41 times.
43 DECL_OO(const Type_List, tl, = check_template_args(env, exp, tm, fdef));
820 41 Tmpl tmpl = {.call = tl};
821 41 ((Exp_Call *)exp)->tmpl = &tmpl;
822
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 39 times.
41 DECL_OO(const Func, func, = get_template_func(env, exp, value));
823 39 return func->def->base->ret_type != env->gwion->type[et_auto] ?
824
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1 times.
39 func->def->base->ret_type : exp->func->d.exp_dot.base->type;
825 }
826
827 ANN Type upvalue_type(const Env env, Capture *cap);
828
829 9 ANN static m_bool lambda_args_ref(const Env env, Exp_Call *const call) {
830 9 Exp e = call->args;
831
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 CHECK_OB(check_exp(env, e));
832
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
10 do if(tflag(e->type, tflag_ref) && !safe_tflag(exp_self(e)->cast_to, tflag_ref))
833 exp_setvar(e, true);
834
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
10 while((e = e->next));
835 9 return GW_OK;
836 }
837
838 1 ANN2(1) static m_bool lambda_append_args(const Env env, Exp_Call *const call, const Exp add) {
839
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!add) return GW_ERROR;
840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (call->args) {
841 Exp e = call->args;
842 while(e->next) e = e->next;
843 e->next = add;
844 1 } else call->args = add;
845 1 return traverse_exp(env, add);
846 }
847
848 1 ANN static Exp check_lambda_captures(const Env env, const Func_Def fdef) {
849
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!fdef->base->args)
850 1 fdef->base->args = new_mp_vector(env->gwion->mp, Arg, 0);
851 1 Exp args = NULL, tmp;
852
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for(uint32_t i = 0; i < fdef->captures->len; i++) {
853 1 Capture *const cap = mp_vector_at(fdef->captures, Capture, i);
854 1 const Type t = upvalue_type(env, cap);
855
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!t) {
856 if(args) free_exp(env->gwion->mp, args);
857 return NULL;
858 }
859 2 Arg arg = {
860 1 .td = type2td(env->gwion, t, cap->pos),
861 1 .var_decl = { .xid = cap->xid }
862 };
863
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mp_vector_add(env->gwion->mp, &fdef->base->args, Arg, arg);
864 1 const Exp exp = new_prim_id(env->gwion->mp, cap->xid, cap->pos);
865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(args) tmp = tmp->next = exp;
866 1 else args = tmp = exp;
867 }
868 1 free_mp_vector(env->gwion->mp, Capture, fdef->captures);
869 1 fdef->captures = NULL;
870 1 return args;
871 }
872
873 14 ANN static Type check_lambda_call(const Env env, Exp_Call *const exp) {
874 14 const Func_Def fdef = exp->func->d.exp_lambda.def;
875 14 const bool captures = !!fdef->captures;
876
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
14 if (exp->args) CHECK_BO(lambda_args_ref(env, exp));
877
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
14 const Exp _args = !captures ? NULL : check_lambda_captures(env, fdef);
878
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
14 if(captures) CHECK_BO(lambda_append_args(env, exp, _args));
879 14 Exp_Lambda *l = &exp->func->d.exp_lambda;
880 14 Arg_List args = l->def->base->args;
881 14 Exp e = exp->args;
882
4/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 13 times.
25 for(uint32_t i = 0; i < (args ? args->len : 0); i++) {
883
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11 times.
12 if(!e)
884 1 ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
885 11 Arg *arg = mp_vector_at(args, Arg, i);
886 11 arg->type = e->type;
887
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if(is_class(env->gwion, arg->type))
888 type_addref(arg->type);
889 11 e = e->next;
890 }
891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(e)
892 ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
893 13 Upvalues upvalues = { .values = env->curr->info->value};
894
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
13 if(env->func && env->func->def->base->values)
895 upvalues.parent = env->func->def->base->values;
896 13 l->def->base->values = &upvalues;
897 13 const m_bool ret = traverse_func_def(env, l->def);
898
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (l->def->base->func) {
899 13 free_scope(env->gwion->mp, env->curr->info->value);
900 13 env->curr->info->value = l->def->base->values->values;
901
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10 times.
13 if (env->class_def) set_vflag(l->def->base->func->value_ref, vflag_member);
902 13 exp->func->type = l->def->base->func->value_ref->type;
903
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6 times.
13 if (!l->def->base->ret_type)
904 7 l->def->base->ret_type = env->gwion->type[et_void];
905 }
906
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 return ret > 0 ? l->def->base->ret_type : NULL;
907 }
908
909 458 ANN m_bool func_check(const Env env, Exp_Call *const exp) {
910 458 exp->func->is_call = true;
911
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 450 times.
458 CHECK_OB(check_exp(env, exp->func));
912
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 448 times.
450 if (exp->func->exp_type == ae_exp_decl)
913 2 ERR_B(exp->func->pos, _("Can't call late function pointer at declaration "
914 "site. did you meant to use `:=>`?"))
915 448 const Type t = actual_type(env->gwion, exp->func->type);
916
4/4
✓ Branch 1 taken 386 times.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 220 times.
✓ Branch 4 taken 166 times.
448 if (is_func(env->gwion, t) && exp->func->exp_type == ae_exp_dot && // is_callable
917
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 219 times.
220 !t->info->value->from->owner_class) {
918
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 if (exp->args) CHECK_OB(check_exp(env, exp->args));
919
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 return call2ufcs(env, exp, t->info->func->value_ref) ? GW_OK : GW_ERROR;
920 }
921 447 const Exp e = exp_self(exp);
922 447 struct Op_Import opi = {.op = insert_symbol("@func_check"),
923 .rhs = t,
924 .pos = e->pos,
925 447 .data = (uintptr_t)e};
926
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 443 times.
447 if(op_get(env, &opi))
927
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 CHECK_OB(op_check(env, &opi));
928
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 444 times.
446 if (e->exp_type != ae_exp_call) return 0;
929
1/2
✓ Branch 0 taken 444 times.
✗ Branch 1 not taken.
444 return e->type != env->gwion->type[et_error] ? GW_OK : GW_ERROR;
930 }
931
932 395 ANN void call_add_effect(const Env env, const Func func, const loc_t pos) {
933
3/4
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 384 times.
395 if (func != env->func && func->def->base->effects.ptr) {
934 const Vector v = &func->def->base->effects;
935 for (m_uint i = 0; i < vector_size(v); i++)
936 env_add_effect(env, (Symbol)vector_at(v, i), pos);
937 }
938 395 }
939
940 435 ANN Type call_type(const Env env, Exp_Call *const exp) {
941 435 const Type t = exp->func->type;
942
2/2
✓ Branch 1 taken 360 times.
✓ Branch 2 taken 75 times.
435 if (is_func(env->gwion, t)) return t;
943
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 6 times.
75 if(isa(exp->func->type, env->gwion->type[et_closure]) > 0)
944 69 return closure_def(t)->base->func->value_ref->type;
945
3/4
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
6 if(is_class(env->gwion, t) && tflag(t->info->base_type, tflag_struct)) {
946 4 const Value v = nspc_lookup_value0(t->info->base_type->nspc, insert_symbol("new"));
947
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(v) return exp->func->type = v->type;
948 }
949 6 struct Op_Import opi = {.op = insert_symbol("call_type"),
950 2 .rhs = actual_type(env->gwion, exp->func->type),
951 2 .data = (uintptr_t)exp,
952 2 .pos = exp_self(exp)->pos};
953 2 return op_check(env, &opi);
954 }
955
956 1 ANN static inline bool is_super(const Exp func) {
957 2 return func->exp_type == ae_exp_primary &&
958
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 func->d.prim.prim_type == ae_prim_id &&
959
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 !strcmp(s_name(func->d.prim.d.var), "super");
960 }
961
962 347 ANN static Type call_return(const Env env, Exp_Call *const exp,
963 const Func func) {
964 347 const Value v = func->value_ref;
965 347 exp->func->type = v->type;
966 347 call_add_effect(env, func, exp->func->pos);
967
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 17 times.
347 if(func->def->base->ret_type != env->gwion->type[et_auto])
968 330 return func->def->base->ret_type;
969
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 9 times.
17 if(tflag(v->from->owner_class, tflag_struct))
970 8 return v->from->owner_class;
971
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 if(exp->func->exp_type == ae_exp_dot)
972 8 return exp->func->d.exp_dot.base->type;
973
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(is_super(exp->func))
974 1 return exp->func->type;
975 return NULL;
976 }
977
978 435 ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) {
979
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 433 times.
435 DECL_OO(const Type, t, = call_type(env, exp));
980
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 431 times.
433 if (t == env->gwion->type[et_op]) return check_op_call(env, exp);
981
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 417 times.
431 if (!t->info->func) // TODO: effects?
982 14 return check_lambda_call(env, exp);
983
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 193 times.
417 if (exp->args) {
984
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 224 times.
224 CHECK_OO(check_exp(env, exp->args));
985 224 Exp e = exp->args;
986 300 do exp_setuse(e, true);
987
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 224 times.
300 while((e = e->next));
988 }
989
2/2
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 374 times.
417 if (tflag(t, tflag_ftmpl))
990 43 return check_exp_call_template(env, (Exp_Call *)exp); // TODO: effects?
991 374 const Func func = find_func_match(env, t->info->func, exp);
992
2/2
✓ Branch 0 taken 347 times.
✓ Branch 1 taken 27 times.
374 if (func) return call_return(env, exp, func);
993 27 return exp->func->exp_type != ae_exp_lambda
994
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 ? NULL : partial_type(env, exp);
995 }
996
997 418 ANN static Type check_static(const Env env, const Exp e) {
998 418 const Type t = e->type;
999
2/2
✓ Branch 1 taken 360 times.
✓ Branch 2 taken 58 times.
418 if(unlikely(!is_func(env->gwion, t)) ||
1000
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 16 times.
360 !t->info->func ||
1001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 !GET_FLAG(t->info->func->def->base, abstract) ||
1002
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
418 !is_static_call(env->gwion, e)) return t;
1003 env_err(env, e->pos, "making a static call to an abstract function");
1004 declared_here(t->info->value);
1005 return NULL;
1006 }
1007
1008 430 ANN Type check_exp_call1(const Env env, Exp_Call *const exp) {
1009
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 420 times.
430 DECL_BO(const m_bool, ret, = func_check(env, exp));
1010
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 418 times.
420 if (!ret) return exp_self(exp)->type;
1011 418 const Type t = exp->func->type;
1012
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 418 times.
418 CHECK_OO(check_static(env, exp->func));
1013 418 const Type _ret = _check_exp_call1(env, exp);
1014
2/2
✓ Branch 0 taken 385 times.
✓ Branch 1 taken 33 times.
418 if(_ret) return _ret;
1015
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 15 times.
33 if(isa(exp->func->type, env->gwion->type[et_closure]) > 0) {
1016
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
18 if(exp->func->exp_type == ae_exp_dot && t->info->value->from->owner_class) {
1017 17 const Exp args = exp->args;
1018 17 const Exp this_arg = cpy_exp(env->gwion->mp, exp->func->d.exp_dot.base);
1019 17 this_arg->next = args;
1020 17 exp->args = this_arg;
1021 17 const Type t = _check_exp_call1(env, exp);
1022
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 times.
17 if(t) return t;
1023 }
1024 }
1025 17 function_alternative(env, exp->func->type, exp->args, exp->func->pos);
1026 17 return NULL;
1027 }
1028
1029 629 ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) {
1030
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 621 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
629 if(bin->lhs->exp_type == ae_exp_call && !bin->lhs->d.exp_call.tmpl) {
1031
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 CHECK_OO(check_exp(env, bin->lhs->d.exp_call.func));
1032 // check is template?
1033 8 bin->lhs->d.exp_call.other = bin->rhs;
1034 }
1035
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 626 times.
629 CHECK_OO(check_exp(env, bin->lhs));
1036 626 const m_bool is_auto = //bin->op == insert_symbol(":=>") &&
1037
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 501 times.
751 bin->rhs->exp_type == ae_exp_decl &&
1038
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 117 times.
125 bin->rhs->d.exp_decl.type == env->gwion->type[et_auto];
1039
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 618 times.
626 if (is_auto) bin->rhs->d.exp_decl.type = bin->lhs->type;
1040 // allow foo => new C to mean new C(foo)
1041
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 486 times.
626 if(bin->op == insert_symbol("=>") &&
1042
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
140 bin->rhs->exp_type == ae_exp_unary && bin->rhs->d.exp_unary.unary_type == unary_td &&
1043 !bin->rhs->d.exp_unary.ctor.td->array &&
1044 !bin->rhs->d.exp_unary.ctor.exp) {
1045 Exp lhs = bin->lhs;
1046 Exp rhs = bin->rhs;
1047 Exp e = exp_self(bin);
1048 Exp_Unary *const unary = &e->d.exp_unary;
1049 e->exp_type = ae_exp_unary;
1050 unary->unary_type = unary_td;
1051 unary->op = insert_symbol("new");
1052 unary->ctor.td = cpy_type_decl(env->gwion->mp, bin->rhs->d.exp_unary.ctor.td);
1053 unary->ctor.exp = lhs;
1054 free_exp(env->gwion->mp, rhs);
1055 return check_exp(env, e);
1056 }
1057
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 618 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
626 if(bin->rhs->exp_type == ae_exp_call && !bin->rhs->d.exp_call.tmpl)
1058 8 bin->rhs->d.exp_call.other = bin->lhs;
1059
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 624 times.
626 CHECK_OO(check_exp(env, bin->rhs));
1060
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 616 times.
624 if (is_auto) {
1061 assert(bin->rhs->type == bin->lhs->type);
1062 8 set_vflag(bin->rhs->d.exp_decl.vd.value, vflag_assigned);
1063 }
1064 1248 struct Op_Import opi = {.op = bin->op,
1065 624 .lhs = bin->lhs->type,
1066 624 .rhs = bin->rhs->type,
1067 624 .data = (uintptr_t)bin,
1068 624 .pos = exp_self(bin)->pos};
1069 624 exp_setuse(bin->lhs, 1);
1070 624 exp_setuse(bin->rhs, 1);
1071 624 const Type ret = op_check(env, &opi);
1072
5/6
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 565 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 57 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
624 if (!ret && is_auto && exp_self(bin)->exp_type == ae_exp_binary)
1073 bin->rhs->d.exp_decl.vd.value->type = env->gwion->type[et_auto];
1074 624 return ret;
1075 }
1076
1077 21 ANN static Type check_exp_cast(const Env env, const Exp_Cast *cast) {
1078
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
21 DECL_OO(const Type, t, = check_exp(env, cast->exp));
1079
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 19 times.
21 CHECK_OO((exp_self(cast)->type = known_type(env, cast->td)));
1080 57 struct Op_Import opi = {.op = insert_symbol("$"),
1081 .lhs = t,
1082 19 .rhs = exp_self(cast)->type,
1083 19 .data = (uintptr_t)cast,
1084 19 .pos = exp_self(cast)->pos};
1085 19 return op_check(env, &opi);
1086 }
1087
1088 31 ANN static Type check_exp_post(const Env env, const Exp_Postfix *post) {
1089 93 struct Op_Import opi = {.op = post->op,
1090 31 .lhs = check_exp(env, post->exp),
1091 31 .data = (uintptr_t)post,
1092 31 .pos = exp_self(post)->pos};
1093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 CHECK_OO(opi.lhs);
1094 31 exp_setuse(post->exp, 1);
1095 31 const Type t = op_check(env, &opi);
1096
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
31 if (t && isa(t, env->gwion->type[et_object]) < 0)
1097 29 exp_setmeta(exp_self(post), 1);
1098 31 return t;
1099 }
1100
1101 2 ANN static m_bool predefined_call(const Env env, const Type t,
1102 const loc_t pos) {
1103 const m_str str =
1104 2 tl2str(env->gwion, t->info->func->def->base->tmpl->call, pos);
1105 2 env_err(env, pos, _("Type '%s' has '%s' as pre-defined types."), t->name,
1106 str);
1107 2 free_mstr(env->gwion->mp, str);
1108
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (tflag(t, tflag_typedef)) {
1109 gwerr_secondary("from definition:", env->name,
1110 t->info->func->def->base->pos);
1111 }
1112 2 return GW_ERROR;
1113 }
1114
1115 409 ANN2(1) static inline bool is_partial(const Env env, Exp exp) {
1116
2/2
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 402 times.
676 while (exp) {
1117
3/4
✓ Branch 1 taken 267 times.
✓ Branch 2 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 267 times.
274 if (is_hole(env, exp) || is_typed_hole(env, exp))
1118 7 return true;
1119 267 exp = exp->next;
1120 }
1121 402 return false;
1122 }
1123
1124 3 ANN static bool tl_match(const Env env, const Type_List tl0, const Type_List tl1) {
1125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (tl0->len != tl1->len) return false;
1126
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for(uint32_t i = 0; i < tl0->len; i++) {
1127 3 Type_Decl *td0 = *mp_vector_at(tl0, Type_Decl*, i);
1128 3 Type_Decl *td1 = *mp_vector_at(tl1, Type_Decl*, i);
1129
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
3 if(known_type(env, td0) != known_type(env, td1))
1130 2 return false;
1131 }
1132 1 return true;
1133 }
1134
1135 26 ANN static Type check_exp_call_tmpl(const Env env, Exp_Call *exp, const Type t) {
1136
3/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19 times.
26 if (exp->args) CHECK_OO(check_exp(env, exp->args));
1137
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 25 times.
26 if (!t->info->func->def->base->tmpl)
1138 1 ERR_O(exp_self(exp)->pos, _("template call of non-template function."))
1139
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 22 times.
25 if (t->info->func->def->base->tmpl->call) {
1140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (env->func == t->info->func) {
1141 exp->func->type = env->func->value_ref->type;
1142 return env->func->def->base->ret_type;
1143 } else {
1144
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 if(tl_match(env, t->info->func->def->base->tmpl->call, exp->tmpl->call))
1145 1 return check_exp_call1(env, exp);
1146
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 CHECK_BO(predefined_call(env, t, exp_self(exp)->pos));
1147 }
1148 }
1149 22 const Value v = type_value(env->gwion, t);
1150
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 14 times.
22 DECL_OO(const Func, f, = find_template_match(env, v, exp));
1151 14 exp->func->type = f->value_ref->type;
1152 14 return f->def->base->ret_type;
1153 }
1154
1155 409 ANN static Type check_exp_call(const Env env, Exp_Call *exp) {
1156
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 402 times.
409 if (is_partial(env, exp->args)) {
1157
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 CHECK_OO(check_exp(env, exp->func));
1158 7 struct Op_Import opi = {.op = insert_symbol("@partial"),
1159 7 .lhs = exp->func->type,
1160 7 .pos = exp->func->pos,
1161 7 .data = (uintptr_t)exp};
1162 7 return op_check(env, &opi);
1163 }
1164
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 374 times.
402 if (exp->tmpl) {
1165
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 27 times.
28 DECL_BO(const m_bool, ret, = func_check(env, exp));
1166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (!ret) return exp_self(exp)->type;
1167 27 Type t = actual_type(env->gwion, exp->func->type);
1168
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 24 times.
27 if(isa(exp->func->type, env->gwion->type[et_closure]) > 0) {
1169 3 t = typedef_base(t);
1170 3 t = mp_vector_at(t->info->cdef->body, Section , 0)->d.func_def->base->func->value_ref->type;
1171 }
1172 // check for closure and b ring it back
1173
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 26 times.
27 if (!is_func(env->gwion, t)) return check_exp_call1(env, exp);
1174
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if(!is_new(t->info->func->def))
1175 26 return check_exp_call_tmpl(env, exp, t);
1176 }
1177 374 return check_exp_call1(env, exp);
1178 }
1179
1180 130 ANN static Type check_exp_unary(const Env env, const Exp_Unary *unary) {
1181 130 const Type rhs =
1182
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 64 times.
130 unary->unary_type == unary_exp ? check_exp(env, unary->exp) : NULL;
1183
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 64 times.
130 if (unary->unary_type == unary_exp) {
1184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 CHECK_OO(rhs);
1185 66 exp_setuse(unary->exp, 1);
1186 }
1187 260 struct Op_Import opi = {.op = unary->op,
1188 .rhs = rhs,
1189 130 .data = (uintptr_t)unary,
1190 130 .pos = exp_self(unary)->pos};
1191
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 114 times.
130 DECL_OO(const Type, ret, = op_check(env, &opi));
1192 114 return ret;
1193 }
1194
1195 81 ANN static Type _flow(const Env env, const Exp e, const m_bool b) {
1196
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
81 DECL_OO(const Type, type, = check_exp(env, e));
1197 162 struct Op_Import opi = {
1198 81 .op = insert_symbol(b ? "@conditional" : "@unconditional"),
1199 .rhs = type,
1200 .pos = e->pos,
1201
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 13 times.
81 .data = (uintptr_t)e};
1202 81 return op_check(env, &opi);
1203 }
1204 #define check_flow(emit, b) _flow(emit, b, 1)
1205
1206 8 ANN static Type check_exp_if(const Env env, Exp_If *const exp_if) {
1207
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (!exp_if->if_exp) {
1208 1 const Exp e = exp_if->if_exp = cpy_exp(env->gwion->mp, exp_if->cond);
1209 1 scan1_exp(env, e);
1210 1 scan2_exp(env, e);
1211 }
1212
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 DECL_OO(const Type, cond, = check_flow(env, exp_if->cond));
1213
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 DECL_OO(const Type, if_exp, = check_exp(env, exp_if->if_exp));
1214
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 DECL_OO(const Type, else_exp, = check_exp(env, exp_if->else_exp));
1215
1216 8 const uint meta =
1217
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8 exp_getmeta(exp_if->if_exp) || exp_getmeta(exp_if->else_exp);
1218 8 exp_setmeta(exp_self(exp_if), meta);
1219 8 const Type ret = find_common_anc(if_exp, else_exp);
1220
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (!ret)
1221 1 ERR_O(exp_self(exp_if)->pos,
1222 _("incompatible types '%s' and '%s' in if expression..."),
1223 if_exp->name, else_exp->name)
1224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (isa(if_exp, else_exp) < 0)
1225 ERR_O(exp_self(exp_if)->pos, _("condition type '%s' does not match '%s'"),
1226 cond->name, ret->name)
1227 7 exp_setuse(exp_if->cond, true);
1228 7 exp_setuse(exp_if->if_exp, true);
1229 7 exp_setuse(exp_if->else_exp, true);
1230 7 return ret;
1231 }
1232
1233 470 ANN static Type check_exp_dot(const Env env, Exp_Dot *member) {
1234
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 467 times.
470 CHECK_OO(check_exp(env, member->base));
1235 467 return check_dot(env, member);
1236 }
1237
1238 17 ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
1239
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 14 times.
17 if (tdef->when) {
1240 3 set_tflag(tdef->type, tflag_contract);
1241 3 struct Var_Decl_ decl = { .xid = insert_symbol("self"), .pos = tdef->when->pos };
1242 3 Type_Decl *td = cpy_type_decl(env->gwion->mp, tdef->ext);
1243 3 Arg_List args = new_mp_vector(env->gwion->mp, Arg, 1);
1244 3 mp_vector_set(args, Arg, 0, ((Arg) { .td = td, .var_decl = decl }));
1245 6 Func_Base *fb = new_func_base(
1246 3 env->gwion->mp, type2td(env->gwion, tdef->type, tdef->pos),
1247 3 insert_symbol("@implicit"), args, ae_flag_none, tdef->pos);
1248 3 set_fbflag(fb, fbflag_op);
1249 3 const Exp helper = new_prim_id(env->gwion->mp, insert_symbol("@predicate"),
1250 3 tdef->when->pos);
1251 3 const Exp when = tdef->when;
1252 3 tdef->when = NULL;
1253 3 when->next = helper;
1254 3 Stmt_List code = new_mp_vector(env->gwion->mp, struct Stmt_, 2);
1255 3 mp_vector_set(code, struct Stmt_, 0,
1256 ((struct Stmt_) {
1257 .stmt_type = ae_stmt_exp, .d = { .stmt_exp = { .val = when }},
1258 .pos = when->pos
1259 }));
1260 3 mp_vector_set(code, struct Stmt_, 1,
1261 ((struct Stmt_) {
1262 .stmt_type = ae_stmt_exp,
1263 .pos = when->pos
1264 }));
1265 3 const Func_Def fdef = new_func_def(env->gwion->mp, fb, code);
1266 3 tdef->when_def = fdef;
1267
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
4 CHECK_BB(traverse_func_def(env, fdef));
1268
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (isa(when->type, env->gwion->type[et_bool]) < 0) {
1269 1 char explain[strlen(when->type->name) + 20];
1270 1 sprintf(explain, "found `{/+}%s{0}`", when->type->name);
1271 1 gwerr_basic("Invalid `{/+}when{0}` predicate expression type", explain,
1272 1 "use `{/+}bool{0}`", env->name, when->pos, 0);
1273 1 char from[strlen(tdef->type->name) + 39];
1274 1 sprintf(from, "in `{/+}%s{0}` definition", tdef->type->name);
1275 1 gwerr_secondary(from, env->name, tdef->pos);
1276 1 env_set_error(env, true);
1277 1 return GW_ERROR;
1278 }
1279 // we handle the return after, so that we don't get *cant' use implicit
1280 // casting while defining it*
1281 2 const Exp ret_id = new_prim_id(env->gwion->mp, insert_symbol("self"), when->pos);
1282 2 ret_id->d.prim.value = new_value(env, tdef->type, "self", tdef->pos);
1283 2 struct Stmt_ ret = {
1284 .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ret_id }},
1285 .pos = when->pos
1286 };
1287 2 mp_vector_set(fdef->d.code, struct Stmt_, 1, ret);
1288 2 ret_id->type = tdef->type;
1289 }
1290
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 9 times.
16 if (tflag(tdef->type, tflag_cdef))
1291 7 return check_class_def(env, tdef->type->info->cdef);
1292 9 else inherit(tdef->type);
1293 9 return GW_OK;
1294 }
1295
1296 25 ANN static Type check_exp_lambda(const Env env, const Exp_If *exp_if NUSED) {
1297 25 return env->gwion->type[et_function];
1298 }
1299
1300 ANN static Type check_exp_td(const Env env, Type_Decl **td) {
1301 DECL_OO(const Type, t, = known_type(env, *td));
1302 if(t == env->gwion->type[et_class])
1303 ERR_O(exp_self(td)->pos, "can't use {G+}Class{0} in type decl expression");
1304 if (!is_func(env->gwion, t)) return type_class(env->gwion, t);
1305 return t;
1306 }
1307
1308 DECL_EXP_FUNC(check, Type, Env)
1309
1310 18939 ANN Type check_exp(const Env env, const Exp exp) {
1311 18939 Exp curr = exp;
1312
2/2
✓ Branch 0 taken 16981 times.
✓ Branch 1 taken 1958 times.
18939 if (!exp->type) {
1313 16981 env_weight(env, 1);
1314 do {
1315
2/2
✓ Branch 1 taken 214 times.
✓ Branch 2 taken 17154 times.
17368 CHECK_OO((curr->type = check_exp_func[curr->exp_type](env, &curr->d)));
1316
6/6
✓ Branch 0 taken 1889 times.
✓ Branch 1 taken 15265 times.
✓ Branch 3 taken 1859 times.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 160 times.
✓ Branch 6 taken 1699 times.
19013 if (env->func && !is_class(env->gwion, curr->type) &&
1317
2/2
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 108 times.
2019 is_func(env->gwion, curr->type) &&
1318 160 !safe_fflag(curr->type->info->func, fflag_pure))
1319 52 unset_fflag(env->func, fflag_pure);
1320
2/2
✓ Branch 0 taken 387 times.
✓ Branch 1 taken 16767 times.
17154 } while ((curr = curr->next));
1321 }
1322 18725 return exp->type;
1323 }
1324
1325 645 ANN m_bool check_enum_def(const Env env, const Enum_Def edef) {
1326 645 const m_uint scope = env_push_type(env, edef->type);
1327 645 ID_List list = edef->list;
1328
2/2
✓ Branch 0 taken 656 times.
✓ Branch 1 taken 645 times.
1301 for(uint32_t i = 0; i < list->len; i++) {
1329 656 Symbol xid = *mp_vector_at(list, Symbol, i);
1330 656 decl_static(env, nspc_lookup_value0(env->curr, xid));
1331 }
1332 645 env_pop(env, scope);
1333 645 nspc_allocdata(env->gwion->mp, edef->type->nspc);
1334 645 return GW_OK;
1335 }
1336
1337 132 ANN static m_bool check_stmt_code(const Env env, const Stmt_Code stmt) {
1338
2/2
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 1 times.
132 if (stmt->stmt_list) { RET_NSPC(check_stmt_list(env, stmt->stmt_list)) }
1339 1 return GW_OK;
1340 }
1341
1342 53 ANN static inline m_bool _check_breaks(const Env env, const Stmt b) {
1343 53 RET_NSPC(check_stmt(env, b))}
1344
1345 53 ANN static m_bool check_breaks(const Env env, const Stmt a, const Stmt b) {
1346 53 vector_add(&env->scope->breaks, (vtype)a);
1347 53 const m_bool ret = _check_breaks(env, b);
1348 53 vector_pop(&env->scope->breaks);
1349 53 return ret;
1350 }
1351
1352 53 ANN static m_bool check_conts(const Env env, const Stmt a, const Stmt b) {
1353 53 vector_add(&env->scope->conts, (vtype)a);
1354
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 52 times.
53 CHECK_BB(check_breaks(env, a, b));
1355 52 vector_pop(&env->scope->conts);
1356 52 return GW_OK;
1357 }
1358
1359 8 ANN static inline m_bool for_empty(const Env env, const Stmt_For stmt) {
1360
3/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 7 times.
8 if (!stmt->c2 || !stmt->c2->d.stmt_exp.val)
1361 1 ERR_B(stmt_self(stmt)->pos,
1362 _("empty for loop condition..."
1363 "...(note: explicitly use 'true' if it's the intent)"
1364 "...(e.g., 'for(; true;){{ /*...*/ }')"))
1365 7 return GW_OK;
1366 }
1367
1368 2 ANN static void check_idx(const Env env, const Type base, struct EachIdx_ *const idx) {
1369 2 idx->v = new_value(env, base, s_name(idx->sym), idx->pos);
1370 2 valid_value(env, idx->sym, idx->v);
1371 2 SET_FLAG(idx->v, const);
1372 2 }
1373
1374 /** sets for the key expression value
1375 with eg type *int* for an array or the *Key* type of a Dict **/
1376 1 ANN static m_bool check_each_idx(const Env env, const Exp exp, struct EachIdx_ *const idx) {
1377 1 struct Op_Import opi = {
1378 1 .lhs = exp->type,
1379 1 .op = insert_symbol("@each_idx"),
1380 1 .data = (m_uint)exp,
1381 .pos = idx->pos
1382 };
1383
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 DECL_OB(const Type, t, = op_check(env, &opi));
1384 1 check_idx(env, t, idx);
1385 1 return GW_OK;
1386 }
1387
1388 /** return the base type for the foreach expression
1389 eg the base type of an array or the *Val* type of a Dict **/
1390 7 ANN static Type check_each_val(const Env env, const Exp exp) {
1391 7 struct Op_Import opi = {
1392 7 .lhs = exp->type,
1393 7 .op = insert_symbol("@each_val"),
1394 7 .data = (m_uint)exp,
1395 .pos = exp->pos
1396 };
1397 7 return op_check(env, &opi);
1398 }
1399
1400 9 ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
1401
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 7 times.
9 CHECK_OB(check_exp(env, stmt->exp));
1402
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (stmt->idx)
1403
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 CHECK_BB(check_each_idx(env, stmt->exp, stmt->idx));
1404
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 DECL_OB(const Type, ret, = check_each_val(env, stmt->exp));
1405 7 stmt->v = new_value(env, ret, s_name(stmt->sym), stmt->vpos);
1406 7 valid_value(env, stmt->sym, stmt->v);
1407 7 return check_conts(env, stmt_self(stmt), stmt->body);
1408 }
1409
1410 8 ANN static m_bool do_stmt_repeat(const Env env, const Stmt_Loop stmt) {
1411
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (stmt->idx) check_idx(env, env->gwion->type[et_int], stmt->idx);
1412 8 return check_conts(env, stmt_self(stmt), stmt->body);
1413 }
1414
1415 9 ANN static inline m_bool repeat_type(const Env env, const Exp e) {
1416 9 const Type t_int = env->gwion->type[et_int];
1417
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 8 times.
9 if (check_implicit(env, e, t_int) < 0) {
1418 1 char explain[40 + strlen(e->type->name)];
1419 1 sprintf(explain, "expected `{/+}int{0}`, got `{/+}%s{0}`", e->type->name);
1420 1 gwerr_basic(_("invalid repeat condition type"), explain,
1421 1 _("use an integer or cast to int if possible"), env->name,
1422 e->pos, 0);
1423 1 env_set_error(env, true);
1424 1 return GW_ERROR;
1425 }
1426 8 return GW_OK;
1427 }
1428
1429 #define stmt_func_xxx(name, type, prolog, exp) \
1430 describe_stmt_func(check, name, type, prolog, exp)
1431
5/8
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 33 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8 times.
✓ Branch 8 taken 25 times.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
33 stmt_func_xxx(if, Stmt_If,, !(!check_flow(env, stmt->cond) ||
1432 check_stmt(env, stmt->if_body) < 0 ||
1433 (stmt->else_body && check_stmt(env, stmt->else_body) < 0)) ? 1 : -1)
1434
5/8
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 14 times.
✓ Branch 9 taken 32 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 32 times.
✗ Branch 14 not taken.
32 stmt_func_xxx(flow, Stmt_Flow, env_inline_mult(env, 1.5),
1435 !(!check_exp(env, stmt->cond) ||
1436 !_flow(env, stmt->cond, !stmt->is_do ?
1437 stmt_self(stmt)->stmt_type == ae_stmt_while :
1438 stmt_self(stmt)->stmt_type != ae_stmt_while) ||
1439 check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
1440
9/12
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 1 times.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5 times.
✓ Branch 11 taken 1 times.
✓ Branch 13 taken 5 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 6 times.
✗ Branch 18 not taken.
8 stmt_func_xxx(for, Stmt_For, env_inline_mult(env, 1.5), !(
1441 for_empty(env, stmt) < 0 ||
1442 check_stmt(env, stmt->c1) < 0 ||
1443 !check_flow(env, stmt->c2->d.stmt_exp.val) ||
1444 (stmt->c3 && !check_exp(env, stmt->c3)) ||
1445 check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
1446
4/6
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 1 times.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
9 stmt_func_xxx(loop, Stmt_Loop, env_inline_mult(env, 1.5); check_idx(env, stmt->idx), !(!check_exp(env, stmt->cond) ||
1447 repeat_type(env, stmt->cond) < 0 ||
1448 do_stmt_repeat(env, stmt) < 0) ? 1 : -1)
1449 9 stmt_func_xxx(each, Stmt_Each, env_inline_mult(env, 1.5), do_stmt_each(env, stmt))
1450
1451 83 ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) {
1452
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 82 times.
83 if (is_new(env->func->def)) {
1453
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(stmt->val)
1454 1 ERR_B(stmt_self(stmt)->pos,
1455 _("'return' statement inside constructor function should have no expression"))
1456 return GW_OK;
1457 }
1458
3/4
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 82 times.
82 DECL_OB(const Type, ret_type,
1459 = stmt->val ? check_exp(env, stmt->val) : env->gwion->type[et_void]);
1460
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 76 times.
82 if (!env->func->def->base->ret_type) {
1461 6 env->func->def->base->ret_type = ret_type;
1462 6 return GW_OK;
1463 }
1464
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 7 times.
76 if (isa(ret_type, env->func->def->base->ret_type) > 0) return GW_OK;
1465
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (tflag(ret_type, tflag_noret))
1466 ERR_B(stmt->val->pos, _("Can't use type `{+G}%s{+G}` for return"),
1467 ret_type->name);
1468
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if (stmt->val) {
1469 6 Arg *arg = mp_vector_at(env->func->def->base->args, Arg, 0);
1470
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (env->func->def->base->xid == insert_symbol("@implicit") &&
1471
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ret_type == arg->type)
1472 1 ERR_B(stmt_self(stmt)->pos,
1473 _("can't use implicit casting while defining it"))
1474
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
5 if (check_implicit(env, stmt->val, env->func->def->base->ret_type) > 0)
1475 4 return GW_OK;
1476 1 ERR_B(stmt_self(stmt)->pos,
1477 _("invalid return type: got '%s', expected '%s'"), ret_type->name,
1478 env->func->def->base->ret_type->name)
1479 }
1480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (isa(env->func->def->base->ret_type, env->gwion->type[et_void]) > 0)
1481 return GW_OK;
1482 1 ERR_B(stmt_self(stmt)->pos, _("missing value for return statement"))
1483 }
1484
1485 #define describe_check_stmt_stack(stack, name) \
1486 ANN static m_bool check_stmt_##name(const Env env, const Stmt stmt) { \
1487 if (!vector_size(&env->scope->stack)) \
1488 ERR_B(stmt->pos, _("'" #name "' found outside of for/while/until...")) \
1489 return GW_OK; \
1490 }
1491
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 9 times.
10 describe_check_stmt_stack(conts, continue);
1492
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
13 describe_check_stmt_stack(breaks, break);
1493
1494 1277 ANN m_bool check_union_def(const Env env NUSED, const Union_Def udef) {
1495
2/2
✓ Branch 1 taken 1276 times.
✓ Branch 2 taken 1 times.
1277 if (tmpl_base(udef->tmpl)) // there's a func for this
1496 1276 return GW_OK;
1497 1 set_tflag(udef->type, tflag_check);
1498 1 return GW_OK;
1499 }
1500
1501 1853 ANN static m_bool check_stmt_exp(const Env env, const Stmt_Exp stmt) {
1502
2/2
✓ Branch 0 taken 1840 times.
✓ Branch 1 taken 13 times.
1853 if(stmt->val) {
1503
2/2
✓ Branch 1 taken 136 times.
✓ Branch 2 taken 1704 times.
1840 CHECK_OB(check_exp(env, stmt->val));
1504
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1703 times.
1704 if(stmt->val->exp_type == ae_exp_lambda) {
1505 1 const loc_t loc = stmt->val->d.exp_lambda.def->base->pos;
1506 1 env_warn(env, loc, _("Partial application not used"));
1507 }
1508 }
1509
3/4
✓ Branch 0 taken 1704 times.
✓ Branch 1 taken 13 times.
✓ Branch 3 taken 1704 times.
✗ Branch 4 not taken.
1717 return stmt->val ? check_exp(env, stmt->val) ? 1 : -1 : 1;
1510 }
1511
1512 2 ANN static Value match_value(const Env env, const Type base,
1513 const Exp_Primary *prim) {
1514 2 const Symbol sym = prim->d.var;
1515 2 const Value v = new_value(env, base, s_name(sym), prim_pos(prim));
1516 // valuefrom?
1517 2 valid_value(env, sym, v);
1518 2 return v;
1519 }
1520
1521 16 ANN Symbol case_basic_op(const Env env, const Type base, const Exp e) {
1522 16 const Symbol _op = insert_symbol("==");
1523 16 struct Op_Import opi = {.op = _op,
1524 .lhs = base,
1525 16 .rhs = e->type,
1526 .data = (uintptr_t)NULL,
1527 .pos = e->pos};
1528 16 return op_get(env, &opi)
1529 8 ? insert_symbol("==")
1530
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
24 : insert_symbol("?=");
1531 }
1532
1533 11 ANN static Symbol case_op(const Env env, const Type base, const Exp e) {
1534
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (e->exp_type == ae_exp_primary) {
1535
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8 times.
11 if (e->d.prim.prim_type == ae_prim_id) {
1536
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (e->d.prim.d.var == insert_symbol("_")) return NULL;
1537
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!nspc_lookup_value1(env->curr, e->d.prim.d.var)) {
1538 2 e->d.prim.value = match_value(env, base, &e->d.prim);
1539 2 return NULL;
1540 }
1541 }
1542 } else if (isa(base, env->gwion->type[et_union]) > 0 &&
1543 e->exp_type == ae_exp_call) {
1544 const Exp func = e->d.exp_call.func;
1545 if (func->d.prim.prim_type == ae_prim_id) {
1546 const Value v = find_value(base, func->d.prim.d.var);
1547 if (v) {
1548 e->type = v->type;
1549 case_op(env, v->type, e->d.exp_call.args);
1550 e->d.exp_call.args->type = v->type;
1551 return NULL;
1552 }
1553 }
1554 }
1555 8 return case_basic_op(env, base, e);
1556 }
1557
1558 11 ANN static m_bool match_case_exp(const Env env, Exp e) {
1559 11 Exp last = e;
1560
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 11 times.
22 for (m_uint i = 0; i < vector_size(&env->scope->match->cond); e = e->next, ++i) {
1561
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (!e) ERR_B(last->pos, _("no enough to match"))
1562 11 last = e;
1563 11 const Exp base = (Exp)vector_at(&env->scope->match->cond, i);
1564 11 const Symbol op = case_op(env, base->type, e);
1565
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 if (op) {
1566 8 const Exp next = e->next;
1567 8 e->next = NULL;
1568 8 const Type t = check_exp(env, e);
1569 8 e->next = next;
1570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 CHECK_OB(t);
1571 8 Exp_Binary bin = {.lhs = cpy_exp(env->gwion->mp, base), .rhs = cpy_exp(env->gwion->mp, e), .op = op};
1572 8 struct Exp_ ebin = {.d = {.exp_binary = bin}, .exp_type = ae_exp_binary, .pos = e->pos };
1573
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 CHECK_BB(traverse_exp(env, &ebin));
1574 8 const Type ret = ebin.type;
1575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if(ebin.exp_type == ae_exp_binary) {
1576 free_exp(env->gwion->mp, bin.lhs);
1577 free_exp(env->gwion->mp, bin.rhs);
1578 }
1579
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 CHECK_OB(ret);
1580 }
1581 }
1582
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
11 if (e) ERR_B(e->pos, _("too many expression to match"))
1583 10 return GW_OK;
1584 }
1585
1586 11 ANN static m_bool _check_stmt_case(const Env env, const Stmt_Match stmt) {
1587
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
11 CHECK_BB(match_case_exp(env, stmt->cond));
1588
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
10 if (stmt->when) CHECK_OB(check_flow(env, stmt->when));
1589 10 return check_stmt_list(env, stmt->list);
1590 }
1591
1592 11 ANN static m_bool check_stmt_case(const Env env, const Stmt_Match stmt) {
1593 11 RET_NSPC(_check_stmt_case(env, stmt))}
1594
1595 7 ANN static m_bool case_loop(const Env env, const Stmt_Match stmt) {
1596
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 6 times.
17 for(m_uint i = 0; i < stmt->list->len; i++) {
1597 11 const Stmt s = mp_vector_at(stmt->list, struct Stmt_, i);
1598
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
11 CHECK_BB(check_stmt_case(env, &s->d.stmt_match));
1599 }
1600 6 return GW_OK;
1601 }
1602
1603 3 ANN static inline m_bool check_handler(const restrict Env env,
1604 const Handler *handler) {
1605 3 RET_NSPC(check_stmt(env, handler->stmt));
1606 }
1607
1608 3 ANN static inline m_bool check_handler_list(const restrict Env env,
1609 const Handler_List handlers) {
1610 3 const bool in_try = env->scope->in_try;
1611 3 env->scope->in_try = true;
1612
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for(uint32_t i = 0; i < handlers->len; i++) {
1613 3 Handler *handler = mp_vector_at(handlers, Handler, i);
1614
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 CHECK_BB(check_handler(env, handler));
1615 }
1616 3 env->scope->in_try = in_try;
1617 3 return GW_OK;
1618 }
1619
1620 ANN static inline bool find_handler(const Handler_List handlers, const Symbol xid) {
1621 for(uint32_t i = 0; i < handlers->len; i++) {
1622 Handler *handler = mp_vector_at(handlers, Handler, i);
1623 if(xid == handler->xid) return true;
1624 if(!handler->xid) return true;
1625 }
1626 return false;
1627 }
1628
1629 3 ANN static inline m_bool check_stmt_try_start(const restrict Env env,
1630 const Stmt_Try stmt) {
1631 3 RET_NSPC(check_stmt(env, stmt->stmt))
1632 }
1633
1634 3 ANN static inline m_bool check_stmt_try(const restrict Env env, const Stmt_Try stmt) {
1635
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 CHECK_BB(check_handler_list(env, stmt->handler));
1636 3 vector_add(&env->scope->effects, 0);
1637 3 const m_bool ret = check_stmt_try_start(env, stmt);
1638 3 MP_Vector *const v = (MP_Vector*)vector_pop(&env->scope->effects);
1639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (v) {
1640 for (m_uint i = 0; i < v->len; i++) {
1641 struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
1642 bool found = find_handler(stmt->handler, eff->sym);
1643 if (!found) env_add_effect(env, eff->sym, eff->pos);
1644 }
1645 free_mp_vector(env->gwion->mp, struct ScopeEffect, v);
1646 }
1647 3 return ret;
1648 }
1649
1650 7 ANN static m_bool _check_stmt_match(const Env env, const Stmt_Match stmt) {
1651
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 CHECK_OB(check_exp(env, stmt->cond));
1652 7 MATCH_INI(env->scope)
1653 7 const m_bool ret = case_loop(env, stmt);
1654 7 MATCH_END(env->scope)
1655 7 return ret;
1656 }
1657
1658 7 ANN static inline m_bool handle_where(const Env env, const Stmt_Match stmt) {
1659
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(check_stmt(env, stmt->where));
1660 7 RET_NSPC(_check_stmt_match(env, stmt))
1661 }
1662
1663 7 ANN static m_bool check_stmt_match(const Env env, const Stmt_Match stmt) {
1664 7 RET_NSPC(handle_where(env, stmt))
1665 }
1666
1667 #define check_stmt_while check_stmt_flow
1668 #define check_stmt_until check_stmt_flow
1669
1670 8 ANN static m_bool check_stmt_pp(const Env env, const Stmt_PP stmt) {
1671
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (stmt->pp_type == ae_pp_include) env->name = stmt->data;
1672 // check for memoization
1673
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
6 else if (env->func && stmt->pp_type == ae_pp_pragma &&
1674
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 !strncmp(stmt->data, "memoize", strlen("memoize")))
1675 1 env->func->memoize = strtol(stmt->data + 7, NULL, 10);
1676
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 else if(stmt->pp_type == ae_pp_locale) {
1677 2 const loc_t loc = stmt_self(stmt)->pos;
1678 2 const Exp id = new_prim_id(env->gwion->mp, stmt->xid, loc);
1679 2 const Exp arg = new_prim_id(env->gwion->mp, insert_symbol("_"), loc);
1680 2 arg->next = stmt->exp;
1681 2 const Exp call = new_exp_call(env->gwion->mp, id, arg, loc);
1682 2 stmt->exp = call;
1683
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 CHECK_BB(traverse_exp(env, id));
1684
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 CHECK_OB(partial_type(env, &call->d.exp_call));
1685 }
1686 8 return GW_OK;
1687 }
1688
1689 ANN static m_bool check_stmt_defer(const Env env, const Stmt_Defer stmt) {
1690 return check_stmt(env, stmt->stmt);
1691 }
1692
1693 #define check_stmt_retry dummy_func
1694 #define check_stmt_spread dummy_func
1695 DECL_STMT_FUNC(check, m_bool, Env)
1696
1697 2201 ANN m_bool check_stmt(const Env env, const Stmt stmt) {
1698 2201 return check_stmt_func[stmt->stmt_type](env, &stmt->d);
1699 }
1700
1701 2445 ANN m_bool check_stmt_list(const Env env, Stmt_List l) {
1702
2/2
✓ Branch 0 taken 2093 times.
✓ Branch 1 taken 2298 times.
4391 for(m_uint i = 0; i < l->len; i++) {
1703 2093 const Stmt s = mp_vector_at(l, struct Stmt_, i);
1704
2/2
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 1946 times.
2093 CHECK_BB(check_stmt(env, s));
1705 }
1706 2298 return GW_OK;
1707 }
1708
1709 5148 ANN static m_bool check_signature_match(const Env env, const Func_Def fdef,
1710 const Func parent) {
1711
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5147 times.
5148 if (GET_FLAG(parent->def->base, final))
1712 1 ERR_B(fdef->base->td->pos, _("can't override final function '%s'\n"),
1713 parent->name)
1714
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5145 times.
5147 if (GET_FLAG(parent->def->base, static) != GET_FLAG(fdef->base, static)) {
1715 2 const m_str c_name = fdef->base->func->value_ref->from->owner_class->name;
1716 2 const m_str p_name = parent->value_ref->from->owner_class->name;
1717 2 const m_str f_name = s_name(fdef->base->xid);
1718
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 ERR_B(fdef->base->td->pos,
1719 _("function '%s.%s' ressembles '%s.%s' but cannot override...\n"
1720 " ...(reason: '%s.%s' is declared as 'static')"),
1721 c_name, f_name, p_name, c_name,
1722 GET_FLAG(fdef->base, static) ? c_name : p_name, f_name)
1723 }
1724
3/4
✓ Branch 0 taken 5135 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5135 times.
✗ Branch 3 not taken.
5145 if(fdef->base->tmpl || isa(fdef->base->ret_type, parent->def->base->ret_type) > 0)
1725 5145 return GW_OK;
1726 gwerr_basic_from("invalid overriding", NULL, NULL, fdef->base->func->value_ref->from, 0);
1727 gwerr_secondary_from("does not match", parent->value_ref->from);
1728 env_set_error(env, true);
1729 return GW_ERROR;
1730 }
1731
1732 5148 ANN static m_bool parent_match_actual(const Env env,
1733 const restrict Func_Def fdef,
1734 const restrict Func func) {
1735 5148 Func parent_func = func;
1736 do {
1737
3/4
✓ Branch 0 taken 5163 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 5148 times.
✓ Branch 4 taken 15 times.
5163 if (parent_func->def->base && compat_func(fdef, parent_func->def) > 0) {
1738
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5145 times.
5148 CHECK_BB(check_signature_match(env, fdef, parent_func));
1739
2/2
✓ Branch 0 taken 5135 times.
✓ Branch 1 taken 10 times.
5145 if (!fdef->base->tmpl) {
1740 5135 fdef->vt_index = parent_func->def->vt_index;
1741 5135 vector_set(&env->curr->vtable, fdef->vt_index,
1742 5135 (vtype)fdef->base->func);
1743 }
1744 5145 return GW_OK;
1745 }
1746
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 } while ((parent_func = parent_func->next));
1747 return 0;
1748 }
1749
1750 72020 ANN static m_bool check_parent_match(const Env env, const Func_Def fdef) {
1751 72020 const Func func = fdef->base->func;
1752 72020 const Type parent = env->class_def->info->parent;
1753
2/2
✓ Branch 0 taken 9415 times.
✓ Branch 1 taken 62605 times.
72020 if (!env->curr->vtable.ptr) vector_init(&env->curr->vtable);
1754
1/2
✓ Branch 0 taken 72020 times.
✗ Branch 1 not taken.
72020 if (parent) {
1755 72020 const Value v = find_value(parent, fdef->base->xid);
1756
4/4
✓ Branch 0 taken 5151 times.
✓ Branch 1 taken 66869 times.
✓ Branch 3 taken 5148 times.
✓ Branch 4 taken 3 times.
72020 if (v && is_func(env->gwion, v->type)) {
1757 5148 const m_bool match = parent_match_actual(env, fdef, v->d.func_ref);
1758
1/2
✓ Branch 0 taken 5148 times.
✗ Branch 1 not taken.
5148 if (match) return match;
1759 }
1760 }
1761 66872 func->def->vt_index = vector_size(&env->curr->vtable);
1762 66872 vector_add(&env->curr->vtable, (vtype)func);
1763 66872 return GW_OK;
1764 }
1765
1766 77 ANN static inline Func get_overload(const Env env, const Func_Def fdef,
1767 const m_uint i) {
1768 const Symbol sym =
1769 77 func_symbol(env, env->curr->name, s_name(fdef->base->xid), NULL, i);
1770 77 return nspc_lookup_func1(env->curr, sym);
1771 }
1772
1773 20 ANN static m_bool check_func_overload(const Env env, const Func_Def fdef) {
1774 20 const Value v = fdef->base->func->value_ref;
1775
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 19 times.
63 for (m_uint i = 0; i <= v->from->offset; ++i) {
1776 44 const Func f1 = get_overload(env, fdef, i);
1777
3/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 43 times.
76 for (m_uint j = i + 1; f1 && j <= v->from->offset; ++j) {
1778 33 const Func f2 = get_overload(env, fdef, j);
1779
4/6
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
34 if (f2 && compat_func(f1->def, f2->def) > 0 &&
1780 1 fbflag(f1->def->base, fbflag_op) ==
1781
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 fbflag(f2->def->base, fbflag_op) &&
1782 1 fbflag(f1->def->base, fbflag_unary) ==
1783
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 fbflag(f2->def->base, fbflag_unary) &&
1784 1 fbflag(f1->def->base, fbflag_postfix) ==
1785 1 fbflag(f2->def->base, fbflag_postfix))
1786 1 ERR_B(f2->def->base->pos,
1787 _("global function '%s' already defined"
1788 " for those arguments"),
1789 s_name(fdef->base->xid))
1790 }
1791 }
1792 19 return GW_OK;
1793 }
1794
1795 1 ANN static bool check_effect_overload(const Vector base, const Func override) {
1796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!base->ptr) return true;
1797
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!override->def->base->effects.ptr) return false;
1798 const Vector v = &override->def->base->effects;
1799 for (m_uint i = 0; i < vector_size(v); i++) {
1800 if (vector_find(base, vector_at(v, i)) == -1) return false;
1801 }
1802 return true;
1803 }
1804
1805 66519 ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef,
1806 Value *ov) {
1807 66519 const Func func = fdef->base->func;
1808
3/4
✓ Branch 0 taken 61893 times.
✓ Branch 1 taken 4626 times.
✓ Branch 2 taken 61893 times.
✗ Branch 3 not taken.
66519 if (env->class_def && env->class_def->info->parent) {
1809 const Value override =
1810 61893 find_value(env->class_def->info->parent, fdef->base->xid);
1811
3/4
✓ Branch 0 taken 5144 times.
✓ Branch 1 taken 56749 times.
✓ Branch 2 taken 5144 times.
✗ Branch 3 not taken.
61893 if (override && override->from->owner_class &&
1812
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5141 times.
5144 !is_func(env->gwion, override->type))
1813 3 ERR_B(fdef->base->pos,
1814 _("function name '%s' conflicts with previously defined value...\n"
1815 " from super class '%s'..."),
1816 s_name(fdef->base->xid), override->from->owner_class->name)
1817 61890 *ov = override;
1818 }
1819
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 66496 times.
66516 if (func->value_ref->from->offset &&
1820
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 (!fdef->base->tmpl /*|| !fdef->base->tmpl->base*/))
1821
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 19 times.
20 CHECK_BB(check_func_overload(env, fdef));
1822 66515 return GW_OK;
1823 }
1824
1825 1817 ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) {
1826 1817 MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects);
1827
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1814 times.
1817 if (v) {
1828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (fdef->base->xid == insert_symbol("@dtor"))
1829 ERR_B(fdef->base->pos, _("can't use effects in destructors"));
1830 3 const Vector base = &fdef->base->effects;
1831
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!base->ptr) vector_init(base);
1832
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for (uint32_t i = 0; i < v->len; i++) {
1833 3 struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
1834
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if(vector_find(base, (m_uint)eff->sym) == -1)
1835 3 vector_add(base, (m_uint)eff->sym);
1836 }
1837 3 free_mp_vector(env->gwion->mp, struct ScopeEffect, v);
1838 }
1839 1817 return GW_OK;
1840 }
1841
1842 66515 ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
1843
4/4
✓ Branch 0 taken 29444 times.
✓ Branch 1 taken 37071 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 29443 times.
66515 if (fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args));
1844
2/2
✓ Branch 0 taken 61946 times.
✓ Branch 1 taken 4568 times.
66514 if(fdef->builtin) return GW_OK;
1845
3/4
✓ Branch 0 taken 1817 times.
✓ Branch 1 taken 2751 times.
✓ Branch 2 taken 1817 times.
✗ Branch 3 not taken.
4568 if (fdef->d.code && fdef->d.code) {
1846 1817 const bool ctor = is_ctor(fdef);
1847
2/2
✓ Branch 0 taken 273 times.
✓ Branch 1 taken 1544 times.
1817 if(!ctor) {
1848 273 env->scope->depth++;
1849 273 nspc_push_value(env->gwion->mp, env->curr);
1850 }
1851 1817 const m_bool ret = check_stmt_list(env, fdef->d.code);
1852
2/2
✓ Branch 0 taken 273 times.
✓ Branch 1 taken 1544 times.
1817 if(!ctor) {
1853 273 nspc_pop_value(env->gwion->mp, env->curr);
1854 273 env->scope->depth--;
1855 }
1856
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1817 times.
1817 CHECK_BB(check_fdef_effects(env, fdef));
1857 1817 return ret;
1858 }
1859 2751 return GW_OK;
1860 }
1861
1862 1362 ANN static m_bool check_ctor(const Env env, const Func func) {
1863
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1353 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 2 times.
1362 if(!func->def->builtin && !GET_FLAG(func, const)) {
1864 7 const Type_Decl *td = env->class_def->info->cdef->base.ext;
1865 const m_uint depth = !td || !td->array
1866
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 ? 1 : td->array->exp->d.prim.d.num;
1867
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if(depth) { // check if size is 0
1868 7 const Type parent = env->class_def->info->parent;
1869 7 const Value v = nspc_lookup_value0(parent->nspc, insert_symbol("new"));
1870
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7 if(v && !GET_FLAG(v->d.func_ref->def->base, abstract))
1871 ERR_B(func->def->base->pos, "missing call to parent constructor");
1872 }
1873 }
1874
1875 1362 return GW_OK;
1876 }
1877
1878 76675 ANN m_bool _check_func_def(const Env env, const Func_Def f) {
1879
4/4
✓ Branch 1 taken 10153 times.
✓ Branch 2 taken 66522 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 10152 times.
76675 if (tmpl_base(f->base->tmpl) && fbflag(f->base, fbflag_op)) return GW_OK;
1880 76674 const Func func = f->base->func;
1881 76674 const Func_Def fdef = func->def;
1882
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 76674 times.
76674 if(fflag(func, fflag_valid))return GW_OK;
1883 76674 set_fflag(func, fflag_valid);
1884 assert(func == fdef->base->func);
1885
4/4
✓ Branch 0 taken 72025 times.
✓ Branch 1 taken 4649 times.
✓ Branch 3 taken 72020 times.
✓ Branch 4 taken 5 times.
76674 if (env->class_def && !fbflag(func->def->base, fbflag_lambda))
1886
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 72017 times.
72020 CHECK_BB(check_parent_match(env, fdef));
1887
2/2
✓ Branch 1 taken 10152 times.
✓ Branch 2 taken 66519 times.
76671 if (tmpl_base(fdef->base->tmpl)) return GW_OK;
1888 66519 Value override = NULL;
1889
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 66515 times.
66519 CHECK_BB(check_func_def_override(env, fdef, &override));
1890
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 66513 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 66515 times.
66515 DECL_BB(const m_int, scope, = GET_FLAG(fdef->base, global)
1891 ? env_push_global(env)
1892 : env->scope->depth);
1893 66515 const Func former = env->func;
1894 66515 env->func = func;
1895 66515 nspc_push_value(env->gwion->mp, env->curr);
1896 66515 struct Op_Import opi = {};
1897
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 66497 times.
66515 if (fbflag(fdef->base, fbflag_op)) {
1898 18 func_operator(f, &opi);
1899 18 operator_suspend(env->curr, &opi);
1900 }
1901
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66515 times.
66515 if(fdef->captures) {
1902 uint32_t offset = fdef->stack_depth;
1903 for(uint32_t i = 0; i < fdef->captures->len; i++) {
1904 Capture *cap = mp_vector_at(fdef->captures, Capture, i);
1905 valid_value(env, cap->xid, cap->temp);
1906 cap->temp->from->offset = offset;
1907 offset += cap->temp->type->size;
1908 }
1909 }
1910 66515 vector_add(&env->scope->effects, 0);
1911 66515 const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef);
1912 66515 vector_pop(&env->scope->effects);
1913
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 66497 times.
66515 if (fbflag(fdef->base, fbflag_op)) operator_resume(&opi);
1914 66515 nspc_pop_value(env->gwion->mp, env->curr);
1915 66515 env->func = former;
1916
2/2
✓ Branch 0 taken 66485 times.
✓ Branch 1 taken 30 times.
66515 if (ret > 0) {
1917
4/4
✓ Branch 0 taken 61869 times.
✓ Branch 1 taken 4616 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 61867 times.
66485 if (env->class_def && fdef->base->effects.ptr &&
1918
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 (override &&
1919
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 !check_effect_overload(&fdef->base->effects, override->d.func_ref)))
1920 1 ERR_B(fdef->base->pos, _("too much effects in override."),
1921 s_name(fdef->base->xid))
1922
4/4
✓ Branch 0 taken 1370 times.
✓ Branch 1 taken 65114 times.
✓ Branch 3 taken 1362 times.
✓ Branch 4 taken 8 times.
66484 if(is_new(f) && !tflag(env->class_def, tflag_struct))
1923
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1362 times.
1362 CHECK_BB(check_ctor(env, func));
1924 }
1925
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 66512 times.
66514 if (GET_FLAG(fdef->base, global)) env_pop(env, scope);
1926
2/2
✓ Branch 0 taken 61889 times.
✓ Branch 1 taken 4625 times.
66514 if (func->value_ref->from->owner_class)
1927 61889 func->inline_mult += 3;
1928 else
1929 4625 func->inline_mult += 4;
1930 66514 return ret;
1931 }
1932
1933 76675 ANN m_bool check_func_def(const Env env, const Func_Def fdef) {
1934 76675 const uint16_t depth = env->scope->depth;
1935 76675 env->scope->depth = 0;
1936 76675 const m_bool ret = _check_func_def(env, fdef);
1937 76675 env->scope->depth = depth;
1938 76675 return ret;
1939 }
1940
1941 ANN bool check_trait_requests(const Env env, const Type t, const ID_List list, const ValueFrom *from);
1942 ANN static m_bool check_extend_def(const Env env, const Extend_Def xdef) {
1943 const Type t = xdef->type;
1944 ValueFrom from = { .filename = env->name, .loc=xdef->td->pos, .ctx=env->context,
1945 .owner = env->curr, .owner_class = env->class_def
1946 };
1947 const bool ret = check_trait_requests(env, t, xdef->traits, &from);
1948 if(ret) {
1949 if(!t->info->traits) {
1950 t->info->traits = new_mp_vector(env->gwion->mp, Symbol, xdef->traits->len);
1951 for(uint32_t i = 0; i < xdef->traits->len; i++) {
1952 const Symbol sym = *mp_vector_at(t->info->traits, Symbol, i);
1953 mp_vector_set(t->info->traits, Symbol, i, sym);
1954 }
1955 } else {
1956 for(uint32_t i = 0; i < xdef->traits->len; i++) {
1957 const Symbol sym = *mp_vector_at(t->info->traits, Symbol, i);
1958 mp_vector_add(env->gwion->mp, &t->info->traits, Symbol, sym);
1959 }
1960 }
1961 return GW_OK;
1962 }
1963 return GW_ERROR;
1964 }
1965
1966 ANN static m_bool _check_trait_def(const Env env, const Trait_Def pdef) {
1967 const Trait trait = nspc_lookup_trait1(env->curr, pdef->xid);
1968 Ast ast = pdef->body;
1969 if(!ast) return GW_OK;
1970 for(m_uint i = 0; i < ast->len; i++) {
1971 Section * section = mp_vector_at(ast, Section, i);
1972 // we should traverse the funcs here also
1973 if (section->section_type == ae_section_stmt) {
1974 Stmt_List l = section->d.stmt_list;
1975 for(m_uint i = 0; i < l->len; i++) {
1976 const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
1977 if (stmt->stmt_type == ae_stmt_exp) {
1978 CHECK_BB(traverse_exp(env, stmt->d.stmt_exp.val));
1979 Var_Decl vd = stmt->d.stmt_exp.val->d.exp_decl.vd;
1980 const Value value = vd.value;
1981 valuefrom(env, value->from);
1982 if (!trait->var)
1983 trait->var = new_mp_vector(env->gwion->mp, Value, 0);
1984 mp_vector_add(env->gwion->mp, &trait->var, Value, value);
1985 }
1986 }
1987 }
1988 }
1989 return GW_OK;
1990 }
1991
1992 ANN static m_bool check_trait_def(const Env env, const Trait_Def pdef) {
1993 RET_NSPC(_check_trait_def(env, pdef));
1994 }
1995
1996 6808 ANN m_bool check_fptr_def(const Env env, const Fptr_Def fptr) {
1997
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6808 times.
6808 if(GET_FLAG(fptr->cdef, global)) env_push_global(env);
1998 6808 const m_bool ret = check_class_def(env, fptr->cdef);
1999
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6808 times.
6808 if(GET_FLAG(fptr->cdef, global)) env_pop(env, 0);
2000 6808 return ret;
2001 }
2002
2003 #define check_prim_def dummy_func
2004 29636 HANDLE_SECTION_FUNC(check, m_bool, Env)
2005
2006 4151 ANN static m_bool check_parent(const Env env, const Class_Def cdef) {
2007 4151 const Type parent = cdef->base.type->info->parent;
2008 4151 const Type_Decl *td = cdef->base.ext;
2009
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4146 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
4151 if (td->array && td->array->exp)
2010
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 CHECK_BB(check_subscripts(env, td->array, 1));
2011
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4151 times.
4151 CHECK_BB(ensure_traverse(env, parent));
2012
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 4144 times.
4151 if(GET_FLAG(parent, abstract))
2013 7 SET_FLAG(cdef->base.type, abstract);
2014 4151 return GW_OK;
2015 }
2016
2017 4151 ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
2018 4151 const bool tmpl = !!cdef->base.tmpl;
2019
3/4
✓ Branch 0 taken 1357 times.
✓ Branch 1 taken 2794 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1357 times.
4151 if (tmpl) CHECK_BB(template_push_types(env, cdef->base.tmpl));
2020 4151 const m_bool ret = check_parent(env, cdef);
2021
2/2
✓ Branch 0 taken 1357 times.
✓ Branch 1 taken 2794 times.
4151 if (tmpl) nspc_pop_type(env->gwion->mp, env->curr);
2022 4151 return ret;
2023 }
2024
2025 4298 ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
2026
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 4281 times.
4298 if (!cdef->base.type->nspc->vtable.ptr) return GW_OK;
2027 4281 bool err = false;
2028
2/2
✓ Branch 1 taken 27596 times.
✓ Branch 2 taken 4281 times.
31877 for (m_uint i = 0; i < vector_size(&cdef->base.type->nspc->vtable); ++i) {
2029 27596 const Func f = (Func)vector_at(&cdef->base.type->nspc->vtable, i);
2030
4/6
✓ Branch 0 taken 27596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27596 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 27593 times.
27596 if (f && f->def->base && GET_FLAG(f->def->base, abstract)) {
2031
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (!err) {
2032 2 err = true;
2033 2 gwerr_basic(_("missing function definition"),
2034 _("must be declared 'abstract'"),
2035 _("provide an implementation for the following:"),
2036 2 env->name, cdef->pos, 0);
2037 }
2038 3 ValueFrom *from = f->value_ref->from;
2039 3 gwerr_secondary_from("implementation missing", from);
2040 3 env_set_error(env, true);
2041 }
2042 }
2043
2/2
✓ Branch 0 taken 4279 times.
✓ Branch 1 taken 2 times.
4281 return !err ? GW_OK : GW_ERROR;
2044 }
2045 /*
2046 ANN static inline void ctor_effects(const Env env) {
2047 const Vector v = &env->scope->effects;
2048 MP_Vector *const w = (MP_Vector*)vector_back(v);
2049 if (!w) return;
2050 vector_init(&env->class_def->effects);
2051 for (uint32_t j = 0; j < w->len; j++) {
2052 struct ScopeEffect *eff = mp_vector_at(w, struct ScopeEffect, j);
2053 vector_add(&env->class_def->effects, (m_uint)eff->sym);
2054 }
2055 free_mp_vector(env->gwion->mp, struct ScopeEffect, w);
2056 vector_pop(v);
2057 }
2058 */
2059 28785 ANN static m_bool check_body(const Env env, Section *const section) {
2060 28785 const m_bool ret = check_section(env, section);
2061 // ctor_effects(env);
2062 28785 return ret;
2063 }
2064
2065 4241 ANN static bool class_def_has_body(Ast ast) {
2066 4241 const Section *section = mp_vector_at(ast, Section, 0);
2067
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4241 times.
4241 if(section->section_type != ae_section_func) return false;
2068 4241 Func_Def f = section->d.func_def;
2069
2/2
✓ Branch 0 taken 2748 times.
✓ Branch 1 taken 1493 times.
4241 if(strcmp(s_name(f->base->xid), "@ctor"))return false;
2070 1493 Stmt_List l = f->d.code;
2071
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 1418 times.
1538 for(m_uint i = 0; i < l->len; i++) {
2072 120 const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
2073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
120 if (stmt->stmt_type == ae_stmt_pp) continue;
2074
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 9 times.
120 if (stmt->stmt_type == ae_stmt_exp) {
2075 111 const Exp exp = stmt->d.stmt_exp.val;
2076
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 108 times.
113 if (!exp) continue;
2077
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 63 times.
129 if (exp->exp_type != ae_exp_decl) return true;
2078
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 61 times.
63 if (GET_FLAG(exp->d.exp_decl.td, late)) continue;
2079 61 Var_Decl vd = exp->d.exp_decl.vd;
2080
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (GET_FLAG(vd.value, late)) continue;
2081
2/2
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 40 times.
61 if (tflag(vd.value->type, tflag_compound))
2082 21 return true;
2083 9 } else return true;
2084 }
2085 1418 return false;
2086 }
2087
2088 332 ANN static inline bool type_is_recurs(const Type t, const Type tgt) {
2089
4/8
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 331 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 331 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
332 return isa(tgt, t) > 0 || isa(t, tgt) > 0 || (tgt->info->tuple && vector_find(&tgt->info->tuple->contains, (m_uint)t) > -1);
2090 }
2091
2092 ANN static m_bool recursive_type_base(const Env env, const Type t);
2093 ANN static bool recursive_type(const Env env, const Type t, const Type tgt);
2094 332 ANN static bool recursive_value(const Env env, const Type t, const Value v) {
2095 332 const Type tgt = array_base(v->type);
2096
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 331 times.
332 if(type_is_recurs(t, tgt)) {
2097 1 env_err(env, v->from->loc, _("recursive type"));
2098 1 env_set_error(env, false);
2099 1 gwerr_secondary("in class", t->name, t->info->cdef->base.pos);
2100
2101 2 const Type first = tgt->info->value->from->loc.first.line < t->info->value->from->loc.first.line ?
2102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 v->type : t;
2103 2 const Type second = tgt->info->value->from->loc.first.line > t->info->value->from->loc.first.line ?
2104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 v->type : t;
2105
2106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(first != second) {
2107 const Map m1 = &first->info->value->from->owner->info->type->map;
2108 map_remove(m1, (m_uint)insert_symbol(first->name));
2109 const Map m2 = &second->info->value->from->owner->info->type->map;
2110 map_remove(m2, (m_uint)insert_symbol(second->name));
2111 if(first->ref > 2)
2112 type_remref(first, env->gwion);
2113 if(second->ref > 2)
2114 type_remref(second, env->gwion);
2115 if(v->from->owner_class->ref > 2)
2116 type_remref(v->from->owner_class, env->gwion);
2117 if(t->ref > 2)
2118 type_remref(t, env->gwion);
2119 }
2120 1 set_tflag(t, tflag_infer);
2121 1 set_tflag(tgt, tflag_infer);
2122 1 unset_tflag(t, tflag_check);
2123 1 unset_tflag(tgt, tflag_check);
2124 1 return true;
2125 }
2126
2127
2/12
✓ Branch 0 taken 331 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 331 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
331 if(t != tgt && v->type->nspc && (!GET_FLAG(v, late) || vflag(v, vflag_assigned)) && strncmp(tgt->name, "Option:[", 8) &&
2128 tflag(tgt, tflag_compound))
2129 return recursive_type(env, t, tgt);
2130
2131 331 return false;
2132 }
2133
2134 34 ANN static bool recursive_type(const Env env, const Type t, const Type tgt) {
2135 Value v;
2136 34 struct scope_iter inner = {tgt->nspc->info->value, 0, 0};
2137 34 bool error = false;
2138
2/2
✓ Branch 1 taken 332 times.
✓ Branch 2 taken 34 times.
366 while (scope_iter(&inner, &v) > 0) {
2139
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 332 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 332 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 331 times.
332 if((!GET_FLAG(v, late) || vflag(v, vflag_assigned)) && v->type != tgt && recursive_value(env, t, v)) {
2140 1 error = true;
2141 }
2142 }
2143 34 return error;
2144 }
2145
2146 4298 ANN static m_bool recursive_type_base(const Env env, const Type t) {
2147 Value value;
2148 4298 bool error = false;
2149 4298 struct scope_iter iter = {t->nspc->info->value, 0, 0};
2150
2/2
✓ Branch 1 taken 50826 times.
✓ Branch 2 taken 4298 times.
55124 while (scope_iter(&iter, &value) > 0) {
2151
2/2
✓ Branch 1 taken 50787 times.
✓ Branch 2 taken 39 times.
50826 if (!tflag(value->type, tflag_compound)) continue;
2152
4/6
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 35 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
39 if (value->type->nspc && (!GET_FLAG(value, late) || vflag(value, vflag_assigned))) {
2153
4/4
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 33 times.
35 if(value->type == t || recursive_type(env, t, value->type)) {
2154 2 env_err(env, value->from->loc, _("recursive type"));
2155 2 gw_err("use {+G}late{0} on one (or more) of the variables?\n");
2156 2 error = true;
2157 }
2158 }
2159 }
2160 4298 return error;
2161 }
2162
2163 ANN bool check_trait_requests(const Env env, const Type t, const ID_List list, const ValueFrom *from);
2164 4330 ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) {
2165 4330 const Type t = cdef->base.type;
2166
3/4
✓ Branch 0 taken 4151 times.
✓ Branch 1 taken 179 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4151 times.
4330 if (cdef->base.ext) CHECK_BB(cdef_parent(env, cdef));
2167
2/2
✓ Branch 1 taken 4304 times.
✓ Branch 2 taken 26 times.
4330 if (!tflag(t, tflag_struct)) inherit(t);
2168
2/2
✓ Branch 0 taken 4297 times.
✓ Branch 1 taken 33 times.
4330 if (cdef->body) {
2169
2/2
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 4267 times.
4297 CHECK_BB(env_body(env, cdef, check_body));
2170
4/4
✓ Branch 1 taken 4241 times.
✓ Branch 2 taken 26 times.
✓ Branch 4 taken 75 times.
✓ Branch 5 taken 4166 times.
4267 if (cflag(cdef, cflag_struct) || class_def_has_body(cdef->body))
2171 // if (class_def_has_body(cdef->body))
2172 101 set_tflag(t, tflag_ctor);
2173 }
2174
4/4
✓ Branch 0 taken 4298 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 4296 times.
4300 if (!GET_FLAG(cdef, abstract)) CHECK_BB(check_abstract(env, cdef));
2175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4298 times.
4298 if (cdef->traits) {
2176 ID_List list = cdef->traits;
2177 if (!check_trait_requests(env, t, list, t->info->value->from)) {
2178 env->class_def = t;
2179 env_error_footer(env);
2180 env_set_error(env, true);
2181 return GW_ERROR;
2182 }
2183 }
2184
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4298 times.
4298 CHECK_BB(recursive_type_base(env, t));
2185 4298 nspc_allocdata(env->gwion->mp, t->nspc);
2186 4298 return GW_OK;
2187 }
2188
2189 8401 ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
2190
2/2
✓ Branch 1 taken 4071 times.
✓ Branch 2 taken 4330 times.
8401 if (tmpl_base(cdef->base.tmpl)) return GW_OK;
2191 4330 const Type t = cdef->base.type;
2192
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4330 times.
4330 if (tflag(t, tflag_check)) return GW_OK;
2193 4330 set_tflag(t, tflag_check);
2194 4330 return _check_class_def(env, t->info->cdef);
2195 }
2196
2197 350 ANN static inline void check_unhandled(const Env env) {
2198 350 const Vector v = &env->scope->effects;
2199 350 MP_Vector *const w = (MP_Vector*)vector_back(v);
2200
2/2
✓ Branch 0 taken 349 times.
✓ Branch 1 taken 1 times.
350 if(!w) return;
2201
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (m_uint j = 0; j < w->len; j++) {
2202 1 struct ScopeEffect *eff = mp_vector_at(w, struct ScopeEffect, j);
2203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(s_name(eff->sym)[0] == '!')
2204 continue;
2205 1 gwerr_secondary("Unhandled effect", env->name, eff->pos);
2206 1 env_set_error(env, false);
2207 }
2208 1 free_mp_vector(env->gwion->mp, struct ScopeEffect, w);
2209 1 vector_pop(v);
2210 }
2211
2212 ANN static void check_extend(const Env env, Ast ast) {
2213 for(m_uint i = 0; i < ast->len; i++) {
2214 Section * section = mp_vector_at(ast, Section, i);
2215 (void)check_section(env, section);
2216 mp_vector_add(env->gwion->mp, &env->context->tree, Section, *section);
2217 }
2218 free_mp_vector(env->gwion->mp, Section, env->context->extend);
2219 env->context->extend = NULL;
2220 }
2221
2222 508 ANN m_bool check_ast(const Env env, Ast *ast) {
2223 508 Ast a = *ast;
2224
2/2
✓ Branch 0 taken 851 times.
✓ Branch 1 taken 350 times.
1201 for(m_uint i = 0; i < a->len; i++) {
2225 851 Section * section = mp_vector_at(a, Section, i);
2226
2/2
✓ Branch 1 taken 158 times.
✓ Branch 2 taken 693 times.
851 CHECK_BB(check_section(env, section));
2227 }
2228
1/2
✓ Branch 1 taken 350 times.
✗ Branch 2 not taken.
350 if(vector_size(&env->scope->effects)) check_unhandled(env);
2229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 350 times.
350 if(env->context->extend) check_extend(env, env->context->extend);
2230 350 return GW_OK;
2231 }
2232