| 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 "instr.h" | ||
| 6 | #include "gwion.h" | ||
| 7 | #include "object.h" | ||
| 8 | #include "emit.h" | ||
| 9 | #include "traverse.h" | ||
| 10 | #include "parse.h" | ||
| 11 | #include "operator.h" | ||
| 12 | #include "import.h" | ||
| 13 | #include "array.h" | ||
| 14 | |||
| 15 | ✗ | OP_CHECK(opck_basic_cast) { | |
| 16 | ✗ | const Exp_Cast *cast = (Exp_Cast *)data; | |
| 17 | ✗ | return isa(cast->exp->type, exp_self(cast)->type) > 0 | |
| 18 | ✗ | ? exp_self(cast)->type | |
| 19 | ✗ | : env->gwion->type[et_error]; | |
| 20 | } | ||
| 21 | |||
| 22 | 3 | OP_CHECK(opck_similar_cast) { | |
| 23 | 3 | const Exp_Cast *cast = (Exp_Cast *)data; | |
| 24 | 3 | return exp_self(cast)->type; | |
| 25 | } | ||
| 26 | |||
| 27 | 3 | OP_CHECK(opck_usr_implicit) { | |
| 28 | 3 | struct Implicit *imp = (struct Implicit *)data; | |
| 29 | /* | ||
| 30 | // in use for refinement types | ||
| 31 | const Value v = nspc_lookup_value1(imp->t->info->owner, | ||
| 32 | insert_symbol("@implicit")); if(v) { Func f = v->d.func_ref; while(f) { | ||
| 33 | if(f->def->base->ret_type == imp->t) | ||
| 34 | break; | ||
| 35 | f = f->next; | ||
| 36 | } | ||
| 37 | if(f) { | ||
| 38 | // TODO: add call exp | ||
| 39 | struct Exp_ call = { .exp_type=ae_exp_call, | ||
| 40 | .d={.exp_call={.args=imp->e}}, .pos=imp->e->pos, .type=f->value_ref->type }; | ||
| 41 | struct Op_Import opi = { .op=insert_symbol("@func_check"), | ||
| 42 | .rhs=f->value_ref->type, .pos=imp->e->pos, .data=(uintptr_t)&call }; | ||
| 43 | CHECK_NN(op_check(env, &opi)); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | */ | ||
| 47 | 3 | return imp->t; | |
| 48 | } | ||
| 49 | |||
| 50 | //#include "emit.h" | ||
| 51 | // contracts only | ||
| 52 | ✗ | OP_EMIT(opem_contract_similar) { | |
| 53 | ✗ | const Exp_Cast *cast = (Exp_Cast *)data; | |
| 54 | ✗ | const Env env = emit->env; | |
| 55 | ✗ | struct Implicit imp = { .t=exp_self(cast)->type, .e=cast->exp}; | |
| 56 | ✗ | struct Op_Import opi = { | |
| 57 | ✗ | .op = insert_symbol("@implicit"), .lhs = cast->exp->type, .rhs = exp_self(cast)->type, .data=(m_uint)&imp }; | |
| 58 | ✗ | return op_emit(emit, &opi); | |
| 59 | } | ||
| 60 | |||
| 61 | 185 | OP_CHECK(opck_const_rhs) { | |
| 62 | 185 | const Exp_Binary *bin = (Exp_Binary *)data; | |
| 63 | 185 | const m_str access = exp_access(bin->rhs); | |
| 64 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 176 times.
|
185 | if (access) |
| 65 | 9 | ERR_N(bin->rhs->pos, | |
| 66 | _("cannot assign '%s' on types '%s' and '%s'.\n" | ||
| 67 | " ... (reason: --- right-side operand is %s.)"), | ||
| 68 | s_name(bin->op), bin->lhs->type->name, bin->rhs->type->name, access); | ||
| 69 | 176 | return bin->rhs->type; | |
| 70 | } | ||
| 71 | |||
| 72 | 180 | OP_CHECK(opck_rassign) { | |
| 73 | 180 | const Exp_Binary *bin = (Exp_Binary *)data; | |
| 74 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 172 times.
|
180 | if (opck_const_rhs(env, data) == env->gwion->type[et_error]) |
| 75 | 8 | return env->gwion->type[et_error]; | |
| 76 | 172 | exp_setvar(bin->rhs, 1); | |
| 77 | 172 | return bin->rhs->type; | |
| 78 | } | ||
| 79 | |||
| 80 | 29 | OP_CHECK(opck_unary_meta) { | |
| 81 | 29 | const Exp_Unary *unary = (Exp_Unary *)data; | |
| 82 | 29 | exp_setmeta(exp_self(unary), 1); | |
| 83 | 29 | return unary->exp->type; | |
| 84 | } | ||
| 85 | |||
| 86 | 1 | OP_CHECK(opck_unary_meta2) { | |
| 87 | 1 | const Exp_Unary *unary = (Exp_Unary *)data; | |
| 88 | 1 | exp_setmeta(exp_self(unary), 1); | |
| 89 | 1 | return env->gwion->type[et_bool]; | |
| 90 | } | ||
| 91 | |||
| 92 | 10 | OP_CHECK(opck_unary) { | |
| 93 | 10 | const Exp_Unary *unary = (Exp_Unary *)data; | |
| 94 | 10 | const m_str access = exp_access(unary->exp); | |
| 95 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
|
10 | if (access) |
| 96 | 1 | ERR_N(unary->exp->pos, | |
| 97 | _("unary operator '%s' cannot be used on %s data-types."), | ||
| 98 | s_name(unary->op), access); | ||
| 99 | 9 | exp_setvar(unary->exp, 1); | |
| 100 | 9 | exp_setmeta(exp_self(unary), 1); | |
| 101 | 9 | return unary->exp->type; | |
| 102 | } | ||
| 103 | |||
| 104 | 30 | OP_CHECK(opck_post) { | |
| 105 | 30 | const Exp_Postfix *post = (Exp_Postfix *)data; | |
| 106 | 30 | const m_str access = exp_access(post->exp); | |
| 107 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 29 times.
|
30 | if (access) |
| 108 | 1 | ERR_N(post->exp->pos, | |
| 109 | _("post operator '%s' cannot be used on %s data-type."), | ||
| 110 | s_name(post->op), access); | ||
| 111 | 29 | exp_setvar(post->exp, 1); | |
| 112 | 29 | exp_setmeta(exp_self(post), 1); | |
| 113 | 29 | return post->exp->type; | |
| 114 | } | ||
| 115 | |||
| 116 | ANN Type check_td(const Env env, Type_Decl *td); | ||
| 117 | |||
| 118 | 38 | OP_CHECK(opck_new) { | |
| 119 | 38 | Exp_Unary *unary = (Exp_Unary *)data; | |
| 120 | 38 | const Array_Sub array = unary->ctor.td->array; | |
| 121 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 37 times.
|
38 | DECL_ON(const Type, t, = known_type(env, unary->ctor.td)); |
| 122 |
3/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
37 | if(array && !unary->ctor.exp) { |
| 123 | 3 | const Type base = array_base(t); | |
| 124 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if(GET_FLAG(base, abstract)) |
| 125 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | CHECK_BN(abstract_array(env, array)); |
| 126 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if(GET_FLAG(base, abstract)) |
| 127 | ✗ | CHECK_BN(check_array_instance(env, unary->ctor.td, unary->ctor.exp)); | |
| 128 | } | ||
| 129 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
|
36 | CHECK_BN(ensure_traverse(env, t)); |
| 130 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 35 times.
|
36 | if (type_ref(t)) |
| 131 | 1 | ERR_N(unary->ctor.td->pos, _("can't use 'new' on ref type '%s'\n"), t->name); | |
| 132 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 33 times.
|
35 | if (tflag(t, tflag_infer)) |
| 133 | 2 | ERR_N(unary->ctor.td->pos, _("can't use 'new' on '%s'\n"), | |
| 134 | t->name); | ||
| 135 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 31 times.
|
33 | if (array) { |
| 136 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | CHECK_BN(check_subscripts(env, array, 1)); |
| 137 | } | ||
| 138 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 15 times.
|
33 | if(unary->ctor.exp) { |
| 139 | 18 | const Exp self = exp_self(unary); | |
| 140 | 18 | const Exp args = cpy_exp(env->gwion->mp, unary->ctor.exp); | |
| 141 | 18 | const Exp base = new_exp_unary2(env->gwion->mp, unary->op, unary->ctor.td, unary->ctor.exp, self->pos); | |
| 142 | 18 | base->type = t; | |
| 143 | 18 | const Exp func = new_exp_dot(env->gwion->mp, base, insert_symbol("new"), self->pos); | |
| 144 | 18 | self->d.exp_call.func = func; | |
| 145 | 18 | self->d.exp_call.args = args; | |
| 146 | 18 | self->d.exp_call.tmpl = NULL; | |
| 147 | 18 | self->exp_type = ae_exp_call; | |
| 148 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 2 taken 13 times.
|
18 | CHECK_BN(traverse_exp(env, self)); |
| 149 | 13 | return self->type; | |
| 150 | } | ||
| 151 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
15 | if (GET_FLAG(t, abstract) && |
| 152 | ✗ | (!array || (array->exp && exp_is_zero(array->exp)))) | |
| 153 | 1 | ERR_N(unary->ctor.td->pos, _("can't use 'new' on abstract type '%s'\n"), | |
| 154 | t->name); | ||
| 155 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
|
14 | if (isa(t, env->gwion->type[et_object]) < 0) |
| 156 | 1 | ERR_N(exp_self(unary)->pos, _("can't use 'new' on non-object types...\n")); | |
| 157 | 13 | return t; | |
| 158 | } | ||
| 159 | |||
| 160 | 17 | OP_EMIT(opem_new) { | |
| 161 | 17 | const Exp_Unary *unary = (Exp_Unary *)data; | |
| 162 |
1/2✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
|
17 | if(!tflag(exp_self(unary)->type, tflag_struct)) |
| 163 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
|
17 | CHECK_BB(emit_instantiate_object(emit, exp_self(unary)->type, |
| 164 | unary->ctor.td->array, 0)); | ||
| 165 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 8 times.
|
17 | if(!unary->ctor.exp) |
| 166 | 9 | emit_local_exp(emit, exp_self(unary)); | |
| 167 | 17 | return GW_OK; | |
| 168 | } | ||
| 169 |