| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "gwion_util.h" | ||
| 2 | #include "gwion_ast.h" | ||
| 3 | #include "gwion_env.h" | ||
| 4 | #include "vm.h" | ||
| 5 | #include "traverse.h" | ||
| 6 | #include "template.h" | ||
| 7 | #include "parse.h" | ||
| 8 | #include "gwion.h" | ||
| 9 | #include "object.h" | ||
| 10 | #include "instr.h" | ||
| 11 | #include "operator.h" | ||
| 12 | #include "import.h" | ||
| 13 | #include "spread.h" | ||
| 14 | #include "emit.h" | ||
| 15 | |||
| 16 | 12967 | static inline void add_type(const Env env, const Nspc nspc, const Type t) { | |
| 17 | 12967 | nspc_add_type_front(nspc, insert_symbol(t->name), t); | |
| 18 | 12967 | } | |
| 19 | |||
| 20 | 19810 | ANN static inline m_bool scan0_defined(const Env env, const Symbol s, | |
| 21 | const loc_t pos) { | ||
| 22 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 19807 times.
|
19810 | if (nspc_lookup_type1(env->curr, s)) |
| 23 | 3 | ERR_B(pos, _("type '%s' already defined"), s_name(s)); | |
| 24 | 19807 | return already_defined(env, s, pos); | |
| 25 | } | ||
| 26 | |||
| 27 | 6826 | ANN static Arg_List fptr_arg_list(const Env env, const Fptr_Def fptr) { | |
| 28 |
4/4✓ Branch 0 taken 6791 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 27 times.
✓ Branch 3 taken 6764 times.
|
6826 | if(env->class_def && !GET_FLAG(fptr->base, static)) { |
| 29 | 27 | Arg arg = { .td = type2td(env->gwion, env->class_def, fptr->base->td->pos) }; | |
| 30 | 27 | const uint32_t len = mp_vector_len(fptr->base->args); | |
| 31 | 27 | Arg_List args = new_mp_vector(env->gwion->mp, Arg, len + 1); | |
| 32 | 27 | mp_vector_set(args, Arg, 0, arg); | |
| 33 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 27 times.
|
45 | for(uint32_t i = 0; i < len; i++) { |
| 34 | 18 | Arg *base = mp_vector_at(fptr->base->args, Arg, i); | |
| 35 | 18 | Arg arg = { .td = cpy_type_decl(env->gwion->mp, base->td) }; | |
| 36 | 18 | mp_vector_set(args, Arg, i+1, arg); | |
| 37 | } | ||
| 38 | 27 | return args; | |
| 39 |
2/2✓ Branch 0 taken 6775 times.
✓ Branch 1 taken 24 times.
|
6799 | } else if(fptr->base->args) |
| 40 | 6775 | return cpy_arg_list(env->gwion->mp, fptr->base->args); | |
| 41 | 24 | return NULL; | |
| 42 | } | ||
| 43 | |||
| 44 | 12987 | ANN static inline m_bool scan0_global(const Env env, const ae_flag flag, | |
| 45 | const loc_t loc) { | ||
| 46 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 2 taken 12982 times.
|
12987 | CHECK_BB(env_storage(env, flag, loc)); |
| 47 | 12982 | const bool global = (flag & ae_flag_global) == ae_flag_global; | |
| 48 |
2/2✓ Branch 0 taken 12975 times.
✓ Branch 1 taken 7 times.
|
12982 | if (!global) return global; |
| 49 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (!env->class_def) { |
| 50 | 7 | env_push_global(env); | |
| 51 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (env->context) env->context->global = true; |
| 52 | 7 | return GW_OK; | |
| 53 | } | ||
| 54 | ✗ | ERR_B(loc, _("can't declare as global in class def")) | |
| 55 | } | ||
| 56 | |||
| 57 | 6829 | ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) { | |
| 58 | 6829 | const loc_t loc = fptr->base->td->pos; | |
| 59 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 6826 times.
|
6829 | CHECK_BB(env_access(env, fptr->base->flag, loc)); |
| 60 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6826 times.
|
6826 | CHECK_BB(scan0_defined(env, fptr->base->xid, loc)); |
| 61 | 6826 | const Arg_List args = fptr_arg_list(env, fptr); | |
| 62 | 6826 | Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, fptr->base->td), | |
| 63 | 6826 | insert_symbol("func"), args, ae_flag_static | ae_flag_private, loc); | |
| 64 | 6826 | const Func_Def fdef = new_func_def(env->gwion->mp, fbase, NULL); | |
| 65 | 6826 | Ast body = new_mp_vector(env->gwion->mp, Section, 1); | |
| 66 | 6826 | mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef)); | |
| 67 | 6826 | Type_Decl* td = new_type_decl(env->gwion->mp, insert_symbol(env->gwion->type[et_closure]->name), loc); | |
| 68 | 6826 | const Class_Def cdef = new_class_def(env->gwion->mp, ae_flag_final, fptr->base->xid, td, body, loc); | |
| 69 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6824 times.
|
6826 | if(GET_FLAG(fptr->base, global)) { |
| 70 | 2 | SET_FLAG(cdef, global); | |
| 71 | 2 | UNSET_FLAG(fptr->base, global); | |
| 72 | } | ||
| 73 |
2/2✓ Branch 0 taken 4079 times.
✓ Branch 1 taken 2747 times.
|
6826 | if(fptr->base->tmpl) { |
| 74 | 4079 | fbase->tmpl = cpy_tmpl(env->gwion->mp, fptr->base->tmpl); | |
| 75 |
2/2✓ Branch 0 taken 4067 times.
✓ Branch 1 taken 12 times.
|
4079 | if(!fptr->base->tmpl->call) |
| 76 | 4067 | cdef->base.tmpl = cpy_tmpl(env->gwion->mp, fptr->base->tmpl); | |
| 77 | } | ||
| 78 | 6826 | fptr->cdef = cdef; | |
| 79 | 6826 | return scan0_class_def(env, cdef); | |
| 80 | } | ||
| 81 | |||
| 82 | ✗ | static OP_CHECK(opck_implicit_similar) { | |
| 83 | ✗ | const struct Implicit *imp = (struct Implicit *)data; | |
| 84 | ✗ | return imp->e->type; | |
| 85 | } | ||
| 86 | |||
| 87 | ✗ | static OP_CHECK(opck_contract_similar) { | |
| 88 | ✗ | const Exp_Cast *cast = (Exp_Cast *)data; | |
| 89 | ✗ | if(tflag(exp_self(cast)->type, tflag_contract)) { | |
| 90 | ✗ | struct Implicit imp = { .t=exp_self(cast)->type, .e=cast->exp}; | |
| 91 | ✗ | struct Op_Import opi = { | |
| 92 | ✗ | .op = insert_symbol("@implicit"), .lhs = cast->exp->type, .rhs = exp_self(cast)->type, .data=(m_uint)&imp }; | |
| 93 | ✗ | CHECK_NN(op_check(env, &opi)); | |
| 94 | } | ||
| 95 | ✗ | return opck_similar_cast(env, data); | |
| 96 | } | ||
| 97 | |||
| 98 | 15 | ANN static void scan0_implicit_similar(const Env env, const Type lhs, | |
| 99 | const Type rhs) { | ||
| 100 | 15 | struct Op_Func opfunc = {.ck = opck_similar_cast}; | |
| 101 | 15 | struct Op_Import opi = { | |
| 102 | 15 | .op = insert_symbol("$"), .lhs = lhs, .rhs = rhs, .func = &opfunc}; | |
| 103 | 15 | add_op(env->gwion, &opi); | |
| 104 | 15 | opi.lhs = rhs; | |
| 105 | 15 | opi.rhs = lhs; | |
| 106 | 15 | add_op(env->gwion, &opi); | |
| 107 | 15 | opfunc.ck = opck_implicit_similar; | |
| 108 | 15 | opi.op = insert_symbol("@implicit"); | |
| 109 | 15 | add_op(env->gwion, &opi); | |
| 110 | 15 | } | |
| 111 | |||
| 112 | 3 | ANN static void scan0_explicit_distinct(const Env env, const Type lhs, | |
| 113 | const Type rhs) { | ||
| 114 | 3 | struct Op_Func opfunc = {.ck = opck_similar_cast}; | |
| 115 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | if(tflag(rhs, tflag_contract)) { |
| 116 | 3 | opfunc.ck = opck_contract_similar; | |
| 117 | 3 | opfunc.em = opem_contract_similar; | |
| 118 | } | ||
| 119 | 3 | struct Op_Import opi = { | |
| 120 | 3 | .op = insert_symbol("$"), .lhs = lhs, .rhs = rhs, .func = &opfunc}; | |
| 121 | 3 | add_op(env->gwion, &opi); | |
| 122 | 3 | opi.lhs = rhs; | |
| 123 | 3 | opi.rhs = lhs; | |
| 124 | 3 | add_op(env->gwion, &opi); | |
| 125 | 3 | } | |
| 126 | |||
| 127 | 11 | ANN static void typedef_simple(const Env env, const Type_Def tdef, | |
| 128 | const Type base) { | ||
| 129 | 11 | const Type t = new_type(env->gwion->mp, s_name(tdef->xid), base); | |
| 130 | 11 | t->size = base->size; | |
| 131 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | const Nspc nspc = (!env->class_def && GET_FLAG(tdef->ext, global)) |
| 132 | ? env->global_nspc | ||
| 133 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
|
21 | : env->curr; |
| 134 | 11 | add_type(env, nspc, t); | |
| 135 | 11 | tdef->type = t; | |
| 136 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
|
11 | if (base->nspc) { |
| 137 | 5 | t->nspc = new_nspc(env->gwion->mp, t->name); | |
| 138 | 5 | t->nspc->parent = base->nspc; | |
| 139 | } | ||
| 140 | 11 | t->flag = tdef->ext->flag; | |
| 141 |
3/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
11 | if (tdef->ext->array && !tdef->ext->array->exp) { |
| 142 | 3 | set_tflag(t, tflag_empty); | |
| 143 | 3 | SET_FLAG(t, abstract); | |
| 144 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | } else if(tflag(base, tflag_union)) |
| 145 | ✗ | set_tflag(t, tflag_union); | |
| 146 | 11 | } | |
| 147 | |||
| 148 | 7 | ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, | |
| 149 | const Type base) { | ||
| 150 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | const ae_flag flag = base->info->cdef ? base->info->cdef->flag : 0; |
| 151 | 7 | const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid, | |
| 152 | 7 | cpy_type_decl(env->gwion->mp, tdef->ext), | |
| 153 | 7 | NULL, tdef->ext->pos); | |
| 154 | 7 | const bool final = GET_FLAG(base, final); | |
| 155 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
|
7 | if(final) UNSET_FLAG(base, final); |
| 156 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
|
7 | CHECK_BB(scan0_class_def(env, cdef)); |
| 157 | 7 | tdef->type = cdef->base.type; | |
| 158 | 7 | cdef->base.tmpl = tdef->tmpl; // check cpy | |
| 159 | 7 | set_tflag(tdef->type, tflag_cdef); | |
| 160 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
|
7 | if(final) SET_FLAG(base, final); |
| 161 | 7 | return GW_OK; | |
| 162 | } | ||
| 163 | |||
| 164 | 22 | ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) { | |
| 165 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
|
22 | CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->pos)); |
| 166 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 20 times.
|
22 | DECL_OB(const Type, base, = known_type(env, tdef->ext)); |
| 167 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 18 times.
|
20 | CHECK_BB(scan0_defined(env, tdef->xid, tdef->ext->pos)); |
| 168 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
|
18 | DECL_BB(const m_bool, global, = scan0_global(env, tdef->ext->flag, tdef->ext->pos)); |
| 169 |
6/6✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 4 times.
|
18 | if (!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp)) |
| 170 | 11 | typedef_simple(env, tdef, base); | |
| 171 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
|
7 | else CHECK_BB(typedef_complex(env, tdef, base)); |
| 172 | 18 | mk_class(env, tdef->type, tdef->pos); | |
| 173 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 15 times.
|
18 | if (tdef->when) set_tflag(tdef->type, tflag_contract); |
| 174 |
4/6✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 3 times.
|
18 | if (tdef->type != base && !tdef->distinct && !tdef->when) |
| 175 | 15 | scan0_implicit_similar(env, base, tdef->type); | |
| 176 |
3/4✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 15 times.
|
21 | if (tdef->distinct || tdef->when) { |
| 177 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (base->info->gack) |
| 178 | 3 | vmcode_addref(tdef->type->info->gack = base->info->gack); | |
| 179 | 3 | set_tflag(tdef->type, tflag_distinct); | |
| 180 | 3 | struct Op_Import opi = {.lhs = base, .rhs = tdef->type}; | |
| 181 | 3 | op_cpy(env, &opi); | |
| 182 | 3 | scan0_explicit_distinct(env, base, tdef->type); | |
| 183 | } else //if(tdef->ext->array) | ||
| 184 | 15 | set_tflag(tdef->type, tflag_typedef); | |
| 185 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
|
18 | if(tflag(base, tflag_ref)) { |
| 186 | ✗ | set_tflag(tdef->type, tflag_ref); | |
| 187 | ✗ | set_tflag(tdef->type, tflag_infer); | |
| 188 | } | ||
| 189 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
|
18 | if (global) env_pop(env, 0); |
| 190 | 18 | return GW_OK; | |
| 191 | } | ||
| 192 | |||
| 193 | 646 | ANN static Type enum_type(const Env env, const Enum_Def edef) { | |
| 194 | 646 | const Type t = type_copy(env->gwion->mp, env->gwion->type[et_enum]); | |
| 195 | 646 | t->name = s_name(edef->xid); | |
| 196 | 646 | t->info->parent = env->gwion->type[et_enum]; | |
| 197 | 646 | add_type(env, env->curr, t); | |
| 198 | 646 | mk_class(env, t, edef->pos); | |
| 199 | 646 | return t; | |
| 200 | } | ||
| 201 | |||
| 202 | 646 | ANN m_bool scan0_enum_def(const Env env, const Enum_Def edef) { | |
| 203 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 646 times.
|
646 | CHECK_BB(scan0_defined(env, edef->xid, edef->pos)); |
| 204 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 646 times.
|
646 | DECL_BB(const m_bool, global, = scan0_global(env, edef->flag, edef->pos)); |
| 205 | 646 | edef->type = enum_type(env, edef); | |
| 206 | 646 | vector_init(&edef->values); | |
| 207 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 646 times.
|
646 | if (global) env_pop(env, 0); |
| 208 | 646 | return GW_OK; | |
| 209 | } | ||
| 210 | |||
| 211 | 1284 | ANN static Type union_type(const Env env, const Symbol s, const loc_t loc) { | |
| 212 | 1284 | const m_str name = s_name(s); | |
| 213 | 1284 | const Type t = new_type(env->gwion->mp, name, env->gwion->type[et_union]); | |
| 214 | 1284 | t->nspc = new_nspc(env->gwion->mp, name); | |
| 215 | 1284 | t->nspc->parent = env->curr; | |
| 216 | 1284 | t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ??? | |
| 217 | 1284 | set_tflag(t, tflag_union); | |
| 218 | 1284 | add_type(env, env->curr, t); | |
| 219 | 1284 | mk_class(env, t, loc); | |
| 220 | 1284 | SET_FLAG(t, final); | |
| 221 | 1284 | set_tflag(t, tflag_compound); | |
| 222 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1281 times.
|
1284 | if (strncmp(t->name, "Option", 6)) SET_FLAG(t, abstract); |
| 223 | 1284 | return t; | |
| 224 | } | ||
| 225 | |||
| 226 | 1282 | ANN static void union_tmpl(const Env env, const Union_Def udef) { | |
| 227 |
2/2✓ Branch 1 taken 639 times.
✓ Branch 2 taken 643 times.
|
1282 | if (tmpl_base(udef->tmpl)) { |
| 228 | 639 | const Union_Def u = cpy_union_def(env->gwion->mp, udef); | |
| 229 | 639 | u->type = udef->type; | |
| 230 | 639 | udef->type->info->udef = u; | |
| 231 | 639 | set_tflag(u->type, tflag_tmpl); | |
| 232 | 639 | set_tflag(u->type, tflag_udef); | |
| 233 | } | ||
| 234 | 1282 | } | |
| 235 | |||
| 236 | 1287 | ANN m_bool scan0_union_def(const Env env, const Union_Def udef) { | |
| 237 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1284 times.
|
1287 | DECL_BB(const m_bool, global, = scan0_global(env, udef->flag, udef->pos)); |
| 238 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1284 times.
|
1284 | CHECK_BB(scan0_defined(env, udef->xid, udef->pos)); |
| 239 | 1284 | udef->type = union_type(env, udef->xid, udef->pos); | |
| 240 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 1284 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1284 times.
|
1284 | SET_ACCESS(udef, udef->type); |
| 241 |
2/2✓ Branch 0 taken 1282 times.
✓ Branch 1 taken 2 times.
|
1284 | if (udef->tmpl) union_tmpl(env, udef); |
| 242 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1284 times.
|
1284 | if (global) env_pop(env, 0); |
| 243 | 1284 | set_tflag(udef->type, tflag_scan0); | |
| 244 | 1284 | return GW_OK; | |
| 245 | } | ||
| 246 | |||
| 247 | 8474 | ANN static inline void cdef_flag(const Class_Def cdef, const Type t) { | |
| 248 |
2/2✓ Branch 0 taken 5458 times.
✓ Branch 1 taken 3016 times.
|
8474 | if (cdef->base.tmpl) set_tflag(t, tflag_tmpl); |
| 249 |
4/4✓ Branch 0 taken 8234 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 8228 times.
|
8474 | if (cdef->base.ext && cdef->base.ext->array) set_tflag(t, tflag_typedef); |
| 250 | 8474 | } | |
| 251 | |||
| 252 | 4071 | ANN static Type get_parent_base(const Env env, Type_Decl *td) { | |
| 253 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4068 times.
|
4071 | DECL_OO(const Type, t, = known_type(env, td)); |
| 254 | 4068 | Type owner = env->class_def; | |
| 255 |
2/2✓ Branch 0 taken 4060 times.
✓ Branch 1 taken 4068 times.
|
8128 | while (owner) { |
| 256 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4060 times.
|
4060 | if (t == owner) |
| 257 | ✗ | ERR_O(td->pos, _("'%s' as parent inside itself\n."), owner->name); | |
| 258 | 4060 | owner = owner->info->value->from->owner_class; | |
| 259 | } | ||
| 260 | 4068 | return t; | |
| 261 | } | ||
| 262 | |||
| 263 | 4170 | ANN static inline Type scan0_final(const Env env, Type_Decl *td) { | |
| 264 | 4170 | const Type t = known_type(env, td); | |
| 265 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4166 times.
|
4170 | if(!t) ERR_O(td->pos, _("can't find parent class %s\n."), s_name(td->xid)); |
| 266 | 4166 | return t; | |
| 267 | } | ||
| 268 | |||
| 269 | 8481 | ANN static Type cdef_parent(const Env env, const Class_Def cdef) { | |
| 270 |
2/2✓ Branch 1 taken 30 times.
✓ Branch 2 taken 8451 times.
|
8481 | if (cflag(cdef, cflag_struct)) return env->gwion->type[et_compound]; |
| 271 |
2/2✓ Branch 0 taken 210 times.
✓ Branch 1 taken 8241 times.
|
8451 | if (!cdef->base.ext) return env->gwion->type[et_object]; |
| 272 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8235 times.
|
8241 | Exp e = cdef->base.ext->array ? cdef->base.ext->array->exp : NULL; |
| 273 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8241 times.
|
8247 | while(e) { |
| 274 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | if(!is_prim_int(e)) |
| 275 | ✗ | ERR_O(e->pos, "non null array type extension must be literal"); | |
| 276 | 6 | e = e->next; | |
| 277 | } | ||
| 278 |
2/2✓ Branch 1 taken 4071 times.
✓ Branch 2 taken 4170 times.
|
8241 | if (tmpl_base(cdef->base.tmpl)) return get_parent_base(env, cdef->base.ext); |
| 279 | 4170 | const bool tmpl = !!cdef->base.tmpl; | |
| 280 |
2/2✓ Branch 0 taken 1357 times.
✓ Branch 1 taken 2813 times.
|
4170 | if (tmpl) template_push_types(env, cdef->base.tmpl); |
| 281 | 4170 | const Type t = scan0_final(env, cdef->base.ext); | |
| 282 |
2/2✓ Branch 0 taken 1357 times.
✓ Branch 1 taken 2813 times.
|
4170 | if (tmpl) nspc_pop_type(env->gwion->mp, env->curr); |
| 283 | 4170 | return t; | |
| 284 | } | ||
| 285 | |||
| 286 | ✗ | ANN static m_bool find_traits(const Env env, ID_List traits, const loc_t pos) { | |
| 287 | ✗ | for(uint32_t i = 0; i < traits->len; i++) { | |
| 288 | ✗ | Symbol xid = *mp_vector_at(traits, Symbol, i); | |
| 289 | ✗ | if (!nspc_lookup_trait1(env->curr, xid)) { | |
| 290 | ✗ | gwerr_basic(_("can't find trait"), NULL, NULL, env->name, pos, 0); | |
| 291 | ✗ | did_you_mean_trait(env->curr, s_name(xid)); | |
| 292 | ✗ | env_set_error(env, true); | |
| 293 | ✗ | return GW_ERROR; | |
| 294 | } | ||
| 295 | } | ||
| 296 | ✗ | return GW_OK; | |
| 297 | } | ||
| 298 | |||
| 299 | 8482 | ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { | |
| 300 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 8481 times.
|
8482 | CHECK_BO(scan0_defined(env, cdef->base.xid, cdef->pos)); |
| 301 |
2/2✓ Branch 1 taken 7 times.
✓ Branch 2 taken 8474 times.
|
8481 | DECL_OO(const Type, parent, = cdef_parent(env, cdef)); |
| 302 |
4/6✓ Branch 0 taken 7 times.
✓ Branch 1 taken 8467 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
|
8474 | if(GET_FLAG(cdef, global) && isa(parent, env->gwion->type[et_closure]) < 0 && !type_global(env, parent)) { |
| 303 | ✗ | gwerr_basic(_("parent type is not global"), NULL, NULL, env->name, cdef->base.ext ? cdef->base.ext->pos : cdef->base.pos, 0); | |
| 304 | ✗ | declared_here(parent->info->value); | |
| 305 | ✗ | env_set_error(env, true); | |
| 306 | ✗ | return NULL; | |
| 307 | } | ||
| 308 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 8474 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
8474 | if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->pos)); |
| 309 | 8474 | const Type t = new_type(env->gwion->mp, s_name(cdef->base.xid), parent); | |
| 310 |
2/2✓ Branch 1 taken 30 times.
✓ Branch 2 taken 8444 times.
|
8474 | if (cflag(cdef, cflag_struct)) { |
| 311 | 30 | t->size = 0; | |
| 312 | 30 | set_tflag(t, tflag_struct); | |
| 313 | 8444 | } else set_tflag(t, tflag_release); | |
| 314 | 8474 | set_tflag(t, tflag_compound); | |
| 315 | 8474 | t->info->tuple = new_tupleform(env->gwion->mp, parent); | |
| 316 | 8474 | t->nspc = new_nspc(env->gwion->mp, t->name); | |
| 317 | 8474 | t->nspc->parent = env->curr; | |
| 318 | 8474 | t->info->cdef = cdef; | |
| 319 | 8474 | t->flag |= cdef->flag; | |
| 320 | 8474 | cdef_flag(cdef, t); | |
| 321 | 8474 | return t; | |
| 322 | } | ||
| 323 | |||
| 324 | |||
| 325 | 7 | ANN static m_bool _spread_tmpl(const Env env, const Type t, const Spread_Def spread) { | |
| 326 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if(t->info->value->from->owner_class) |
| 327 | ✗ | CHECK_BB(_spread_tmpl(env, t->info->value->from->owner_class, spread)); | |
| 328 | 7 | const Tmpl *tmpl = t->info->cdef->base.tmpl; | |
| 329 |
3/4✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 3 times.
|
7 | if(!tmpl || !tmpl->call) return GW_OK; |
| 330 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | if(is_spread_tmpl(tmpl)) |
| 331 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
|
3 | CHECK_BB(spread_ast(env, spread, tmpl)); |
| 332 | 2 | return GW_OK; | |
| 333 | } | ||
| 334 | |||
| 335 | 9 | ANN static m_bool spread_tmpl(const Env env, const Spread_Def spread) { | |
| 336 |
4/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 6 times.
|
9 | if(env->class_def) CHECK_BB(_spread_tmpl(env, env->class_def, spread)); |
| 337 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
|
8 | if(!env->func) return GW_OK; |
| 338 | 2 | const Tmpl *tmpl = env->func->def->base->tmpl; | |
| 339 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if(!tmpl || !tmpl->call) return GW_OK; |
| 340 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | if(is_spread_tmpl(tmpl)) |
| 341 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | CHECK_BB(spread_ast(env, spread, tmpl)); |
| 342 | 2 | return GW_OK; | |
| 343 | } | ||
| 344 | |||
| 345 | 11 | ANN static bool spreadable(const Env env) { | |
| 346 | 11 | const Func f = env->func; | |
| 347 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
11 | if(f && f->def->base->tmpl && is_spread_tmpl(f->def->base->tmpl)) |
| 348 | 2 | return true; | |
| 349 | 9 | Type t = env->class_def; | |
| 350 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
|
10 | while(t) { |
| 351 | 8 | const Tmpl *tmpl = t->info->cdef->base.tmpl; | |
| 352 |
3/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
|
8 | if(tmpl && is_spread_tmpl(tmpl)) |
| 353 | 7 | return true; | |
| 354 | 1 | t = t->info->value->from->owner_class; | |
| 355 | } | ||
| 356 | 2 | return false; | |
| 357 | } | ||
| 358 | |||
| 359 | 761 | ANN static m_bool scan0_stmt_list(const Env env, Stmt_List l) { | |
| 360 |
2/2✓ Branch 0 taken 1802 times.
✓ Branch 1 taken 715 times.
|
2517 | for(m_uint i = 0; i < l->len; i++) { |
| 361 | 1802 | const Stmt stmt = mp_vector_at(l, struct Stmt_, i); | |
| 362 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 1752 times.
|
1802 | if (stmt->stmt_type == ae_stmt_pp) { |
| 363 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 48 times.
|
50 | if (stmt->d.stmt_pp.pp_type == ae_pp_include) |
| 364 | 2 | env->name = stmt->d.stmt_pp.data; | |
| 365 |
2/2✓ Branch 0 taken 43 times.
✓ Branch 1 taken 5 times.
|
48 | else if (stmt->d.stmt_pp.pp_type == ae_pp_import) |
| 366 |
1/2✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
|
43 | CHECK_BB(plugin_ini(env->gwion, stmt->d.stmt_pp.data, stmt->pos)); |
| 367 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1741 times.
|
1752 | } else if (stmt->stmt_type == ae_stmt_spread) { |
| 368 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 9 times.
|
11 | if(!spreadable(env)) |
| 369 | 2 | ERR_B(stmt->pos, "spread statement outside of variadic environment"); | |
| 370 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
|
9 | if(!env->context->extend) |
| 371 | 6 | env->context->extend = new_mp_vector(env->gwion->mp, Section, 0); | |
| 372 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 8 times.
|
9 | CHECK_BB(spread_tmpl(env, &stmt->d.stmt_spread)); |
| 373 | } | ||
| 374 | } | ||
| 375 | 715 | return GW_OK; | |
| 376 | } | ||
| 377 | |||
| 378 | 89442 | ANN m_bool scan0_func_def(const Env env, const Func_Def fdef) { | |
| 379 |
2/2✓ Branch 0 taken 714 times.
✓ Branch 1 taken 88728 times.
|
89442 | const Ast old_extend = env->context ? env->context->extend : NULL; |
| 380 |
4/4✓ Branch 0 taken 24450 times.
✓ Branch 1 taken 64992 times.
✓ Branch 2 taken 24388 times.
✓ Branch 3 taken 62 times.
|
89442 | if(!fdef->base->tmpl || !fdef->base->tmpl->call) return GW_OK; |
| 381 |
1/2✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
|
62 | if(env->context) { |
| 382 |
4/6✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 60 times.
|
62 | if(fdef->base->tmpl && fdef->base->tmpl->call && is_spread_tmpl(fdef->base->tmpl)) { |
| 383 | 2 | struct Func_ fake = {.name = s_name(fdef->base->xid), .def = fdef }, *const former = | |
| 384 | env->func; | ||
| 385 | 2 | env->func = &fake; | |
| 386 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | if(!fdef->builtin && fdef->d.code) |
| 387 | 2 | scan0_stmt_list(env, fdef->d.code); | |
| 388 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if(env->context->extend) |
| 389 | 2 | fdef->d.code = spread_func(env, fdef->d.code); | |
| 390 | 2 | env->func = former; | |
| 391 | 2 | env->context->extend = old_extend; | |
| 392 | }} | ||
| 393 | 62 | return GW_OK; | |
| 394 | } | ||
| 395 | |||
| 396 | ✗ | ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) { | |
| 397 | ✗ | DECL_OB(const Type, t, = known_type(env, xdef->td)); | |
| 398 | ✗ | if(type_global(env, t)) { | |
| 399 | ✗ | for(uint32_t i = 0; i < xdef->traits->len; i++) { | |
| 400 | ✗ | const Symbol xid = *mp_vector_at(xdef->traits, Symbol, i); | |
| 401 | ✗ | const Trait global = nspc_lookup_trait1(env->global_nspc, xid); | |
| 402 | ✗ | if(!global) { | |
| 403 | ✗ | const Trait trait = nspc_lookup_trait1(env->curr, xid); | |
| 404 | ✗ | gwerr_basic("trait should be declared global", NULL, NULL, trait->filename, trait->loc, 0); | |
| 405 | ✗ | gwerr_secondary("from the request ", env->name, xdef->td->pos); | |
| 406 | ✗ | env_set_error(env, true); | |
| 407 | } | ||
| 408 | } | ||
| 409 | } | ||
| 410 | ✗ | xdef->type = t; | |
| 411 | ✗ | return GW_OK; | |
| 412 | } | ||
| 413 | |||
| 414 | ✗ | ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) { | |
| 415 | ✗ | CHECK_BB(scan0_defined(env, pdef->xid, pdef->pos)); | |
| 416 | ✗ | DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, pdef->pos)); | |
| 417 | ✗ | const Trait trait = new_trait(env->gwion->mp, pdef->pos); | |
| 418 | ✗ | trait->loc = pdef->pos; | |
| 419 | ✗ | trait->name = s_name(pdef->xid); | |
| 420 | ✗ | trait->filename = env->name; | |
| 421 | ✗ | nspc_add_trait(env->curr, pdef->xid, trait); | |
| 422 | ✗ | if(global) env_pop(env, 0); | |
| 423 | ✗ | Ast ast = pdef->body; | |
| 424 | ✗ | if(!ast) return GW_OK; // ??? | |
| 425 | ✗ | for(m_uint i = 0; i < ast->len; i++) { | |
| 426 | ✗ | Section *section = mp_vector_at(ast, Section, i); | |
| 427 | ✗ | if (section->section_type == ae_section_func) { | |
| 428 | ✗ | const Func_Def fdef = section->d.func_def; | |
| 429 | ✗ | if (fdef->base->flag != ae_flag_none && | |
| 430 | ✗ | fdef->base->flag != (ae_flag_none | ae_flag_abstract)) | |
| 431 | ✗ | ERR_B(fdef->base->pos, "Trait function must be declared without qualifiers"); | |
| 432 | ✗ | if (!trait->fun) trait->fun = new_mp_vector(env->gwion->mp, Func_Def, 0); | |
| 433 | ✗ | mp_vector_add(env->gwion->mp, &trait->fun, Func_Def, fdef); | |
| 434 | } | ||
| 435 | } | ||
| 436 | ✗ | return GW_OK; | |
| 437 | } | ||
| 438 | |||
| 439 | ✗ | ANN static m_bool scan0_trait_def(const Env env, const Trait_Def pdef) { | |
| 440 | ✗ | const Symbol s = pdef->xid; | |
| 441 | ✗ | const Trait exists = nspc_lookup_trait1(env->curr, s); | |
| 442 | ✗ | if (exists) { | |
| 443 | ✗ | gwerr_basic("trait already defined", NULL, NULL, env->name, pdef->pos, 0); | |
| 444 | ✗ | gwerr_secondary("defined here", env->name, exists->loc); | |
| 445 | ✗ | env_set_error(env, true); | |
| 446 | ✗ | return already_defined(env, s, pdef->pos); | |
| 447 | } | ||
| 448 | ✗ | if (pdef->traits) CHECK_BB(find_traits(env, pdef->traits, pdef->pos)); | |
| 449 | ✗ | _scan0_trait_def(env, pdef); | |
| 450 | ✗ | return GW_OK; | |
| 451 | } | ||
| 452 | |||
| 453 | 2552 | ANN m_bool scan0_prim_def(const Env env, const Prim_Def pdef) { | |
| 454 | 2552 | const loc_t loc = pdef->loc; | |
| 455 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2552 times.
|
2552 | CHECK_BB(env_access(env, pdef->flag, loc)); |
| 456 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2552 times.
|
2552 | CHECK_BB(scan0_defined(env, pdef->name, loc)); |
| 457 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2552 times.
|
2552 | DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, loc)); |
| 458 | 2552 | const Type t = mk_primitive(env, s_name(pdef->name), pdef->size); | |
| 459 | 2552 | add_type(env, env->curr, t); | |
| 460 | 2552 | mk_class(env, t, pdef->loc); | |
| 461 | 2552 | t->flag = pdef->flag; | |
| 462 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2552 times.
|
2552 | if(global) env_pop(env, 0); |
| 463 | 2552 | return GW_OK; | |
| 464 | } | ||
| 465 | |||
| 466 | 32618 | HANDLE_SECTION_FUNC(scan0, m_bool, Env) | |
| 467 | |||
| 468 | 8482 | ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) { | |
| 469 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8482 times.
|
8482 | CHECK_BB(isres(env, cdef->base.xid, cdef->pos)); |
| 470 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8474 times.
|
8482 | CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef))); |
| 471 | 8474 | cdef->base.type->info->traits = cdef->traits; // should we copy the traits? | |
| 472 | 8474 | set_tflag(cdef->base.type, tflag_scan0); | |
| 473 | 8474 | (void)mk_class(env, cdef->base.type, cdef->pos); | |
| 474 | 8474 | add_type(env, cdef->base.type->info->value->from->owner, cdef->base.type); | |
| 475 |
2/2✓ Branch 0 taken 8416 times.
✓ Branch 1 taken 58 times.
|
8474 | const m_bool ret = cdef->body ? env_body(env, cdef, scan0_section) : GW_OK; |
| 476 | 8474 | return ret; | |
| 477 | } | ||
| 478 | |||
| 479 | ANN Ast spread_class(const Env env, const Ast body); | ||
| 480 | |||
| 481 | 3 | static INSTR(StructAssign) { | |
| 482 | 3 | memcpy(*(m_bit**)REG(-SZ_INT), REG((m_int)instr->m_val), instr->m_val2); | |
| 483 | 3 | } | |
| 484 | |||
| 485 | 3 | static OP_EMIT(opem_struct_assign) { | |
| 486 | 3 | const Exp_Binary *bin = data; | |
| 487 | 3 | const Type t = bin->lhs->type; | |
| 488 | 3 | const Exp e = exp_self(bin); | |
| 489 | |||
| 490 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
3 | if(tflag(t, tflag_release)) { |
| 491 | ✗ | const Instr release = emit_add_instr(emit, StructReleaseRegAddr); | |
| 492 | ✗ | release->m_val = -SZ_INT; | |
| 493 | ✗ | release->m_val2 = (m_uint)t; | |
| 494 | } | ||
| 495 | |||
| 496 | 3 | const Instr instr = emit_add_instr(emit, StructAssign); | |
| 497 | 3 | instr->m_val = -t->size - SZ_INT; | |
| 498 | 3 | instr->m_val2 = t->size; | |
| 499 | 3 | emit_struct_addref(emit, t, -SZ_INT, true); // add ref on lhs | |
| 500 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
3 | if(exp_getvar(e)) { |
| 501 | 2 | emit_regmove(emit, -t->size); | |
| 502 | 2 | const Instr instr = emit_add_instr(emit, Reg2Reg); | |
| 503 | 2 | instr->m_val = -SZ_INT; | |
| 504 | 2 | instr->m_val2 = t->size - SZ_INT; | |
| 505 | 1 | } else emit_regmove(emit, -SZ_INT); | |
| 506 | 3 | return GW_OK; | |
| 507 | } | ||
| 508 | |||
| 509 | 3 | ANN static OP_CHECK(opck_struct_assign) { | |
| 510 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
3 | CHECK_NN(opck_rassign(env, data)); |
| 511 | 3 | Exp_Binary *bin = data; | |
| 512 | 3 | bin->rhs->ref = bin->lhs; | |
| 513 | 3 | return bin->lhs->type; | |
| 514 | } | ||
| 515 | |||
| 516 | 30 | ANN static void scan0_struct_assign(const Env env, const Type t) { | |
| 517 | 30 | struct Op_Func opfunc = {.ck = opck_struct_assign, .em = opem_struct_assign }; | |
| 518 | 30 | struct Op_Import opi = { | |
| 519 | 30 | .op = insert_symbol(":=>"), .lhs = t, .rhs = t, .ret = t, .func = &opfunc}; | |
| 520 | 30 | add_op(env->gwion, &opi); | |
| 521 | 30 | } | |
| 522 | |||
| 523 | 8484 | ANN m_bool scan0_class_def(const Env env, const Class_Def c) { | |
| 524 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8482 times.
|
8484 | DECL_BB(const m_bool, global, = scan0_global(env, c->flag, c->pos)); |
| 525 |
2/2✓ Branch 0 taken 406 times.
✓ Branch 1 taken 8076 times.
|
8482 | const Ast old_extend = env->context ? env->context->extend : NULL; |
| 526 |
4/4✓ Branch 1 taken 4394 times.
✓ Branch 2 taken 4088 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 4387 times.
|
8482 | const int cpy = tmpl_base(c->base.tmpl) || GET_FLAG(c, global); |
| 527 |
2/2✓ Branch 0 taken 4095 times.
✓ Branch 1 taken 4387 times.
|
8482 | const Class_Def cdef = !cpy ? c : cpy_class_def(env->gwion->mp, c); |
| 528 | 8482 | const m_bool ret = scan0_class_def_inner(env, cdef); | |
| 529 | |||
| 530 |
4/4✓ Branch 0 taken 4095 times.
✓ Branch 1 taken 4387 times.
✓ Branch 2 taken 4092 times.
✓ Branch 3 taken 3 times.
|
8482 | if (cpy && cdef->base.type) c->base.type = cdef->base.type; |
| 531 |
2/2✓ Branch 0 taken 406 times.
✓ Branch 1 taken 8076 times.
|
8482 | if(env->context) { |
| 532 |
4/4✓ Branch 1 taken 356 times.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 354 times.
|
406 | if(!tmpl_base(c->base.tmpl) && env->context->extend) |
| 533 | 2 | cdef->body = spread_class(env, cdef->body); | |
| 534 | 406 | env->context->extend = old_extend; | |
| 535 | } | ||
| 536 |
2/2✓ Branch 1 taken 30 times.
✓ Branch 2 taken 8452 times.
|
8482 | if(cflag(cdef, cflag_struct)) scan0_struct_assign(env, cdef->base.type); |
| 537 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 8475 times.
|
8482 | if (GET_FLAG(cdef, global)) env_pop(env, 0); |
| 538 | 8482 | return ret; | |
| 539 | } | ||
| 540 | |||
| 541 | 647 | ANN m_bool scan0_ast(const Env env, Ast *ast) { | |
| 542 | 647 | Ast a = *ast; | |
| 543 |
2/2✓ Branch 0 taken 1075 times.
✓ Branch 1 taken 584 times.
|
1659 | for(m_uint i = 0; i < a->len; i++) { |
| 544 | 1075 | Section * section = mp_vector_at(a, Section, i); | |
| 545 |
2/2✓ Branch 1 taken 63 times.
✓ Branch 2 taken 1012 times.
|
1075 | CHECK_BB(scan0_section(env, section)); |
| 546 | } | ||
| 547 | 584 | return GW_OK; | |
| 548 | } | ||
| 549 |