Gwion coverage report


Directory: src/
File: src/lib/opfunc.c
Date: 2023-01-30 18:32:28
Exec Total Coverage
Lines: 82 96 85.4%
Functions: 10 12 83.3%
Branches: 38 54 70.4%

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