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