GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/lib/opfunc.c Lines: 59 65 90.8 %
Date: 2020-10-03 11:19:27 Branches: 21 28 75.0 %

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 "object.h"
7
#include "emit.h"
8
#include "traverse.h"
9
#include "parse.h"
10
#include "operator.h"
11
#include "import.h"
12
13
OP_CHECK(opck_basic_cast) {
14
  const Exp_Cast* cast = (Exp_Cast*)data;
15
  return isa(cast->exp->info->type, exp_self(cast)->info->type) > 0 ?
16
     exp_self(cast)->info->type : env->gwion->type[et_null];
17
}
18
19
1
OP_CHECK(opck_usr_implicit) {
20
1
  struct Implicit* imp = (struct Implicit*)data;
21
1
  imp->e->info->cast_to = imp->t;
22
1
  return imp->t;
23
}
24
25
192
OP_CHECK(opck_const_rhs) {
26
192
  const Exp_Binary* bin = (Exp_Binary*)data;
27
192
  const m_str access = exp_access(bin->rhs);
28
192
  if(access)
29
6
    ERR_N(bin->rhs->pos, _("cannot assign '%s' on types '%s' and '%s'.\n"
30
         "  ...  (reason: --- right-side operand is %s.)"),
31
         s_name(bin->op), bin->lhs->info->type->name, bin->rhs->info->type->name,
32
         access)
33
186
  return bin->rhs->info->type;
34
}
35
36
172
OP_CHECK(opck_rassign) {
37
172
  const Exp_Binary* bin = (Exp_Binary*)data;
38
172
  if(opck_const_rhs(env, data, mut) == env->gwion->type[et_null])
39
5
    return env->gwion->type[et_null];
40
167
  exp_setvar(bin->rhs, 1);
41
167
  return bin->rhs->info->type;
42
}
43
44
27
OP_CHECK(opck_unary_meta) {
45
27
  const Exp_Unary* unary = (Exp_Unary*)data;
46
27
  exp_setmeta(exp_self(unary), 1);
47
27
  return unary->exp->info->type;
48
}
49
50
4
OP_CHECK(opck_unary_meta2) {
51
4
  const Exp_Unary* unary = (Exp_Unary*)data;
52
4
  exp_setmeta(exp_self(unary), 1);
53
4
  return env->gwion->type[et_bool];
54
}
55
56
14
OP_CHECK(opck_unary) {
57
14
  const Exp_Unary* unary = (Exp_Unary*)data;
58
14
  const m_str access = exp_access(unary->exp);
59
14
  if(access)
60
1
    ERR_N(unary->exp->pos,
61
          _("unary operator '%s' cannot be used on %s data-types."),
62
          s_name(unary->op), access);
63
13
  exp_setvar(unary->exp, 1);
64
13
  return unary->exp->info->type;
65
}
66
67
34
OP_CHECK(opck_post) {
68
34
  const Exp_Postfix* post = (Exp_Postfix*)data;
69
34
  const m_str access = exp_access(post->exp);
70
34
  if(access)
71
1
    ERR_N(post->exp->pos, _("post operator '%s' cannot be used on %s data-type."),
72
          s_name(post->op), access)
73
33
  exp_setvar(post->exp, 1);
74
33
  return post->exp->info->type;
75
}
76
77
ANN Type check_td(const Env env, Type_Decl *td);
78
28
ANN static inline Type check_new_td(const Env env, Type_Decl *td) {
79
28
  if(!td->exp)
80
28
    return known_type(env, td);
81
  DECL_OO(const Type, t, = check_exp(env, td->exp))
82
  return actual_type(env->gwion, t);
83
}
84
85
28
OP_CHECK(opck_new) {
86
28
  const Exp_Unary* unary = (Exp_Unary*)data;
87
28
  SET_FLAG(unary->td, ref);
88
28
  DECL_ON(const Type, t, = check_new_td(env, unary->td))
89
27
  if(isa(t, env->gwion->type[et_object]) < 0)
90
1
    ERR_N(exp_self(unary)->pos, _("can't use 'new' on non-object types...\n"))
91
26
  if(type_ref(t))
92
1
    ERR_N(td_pos(unary->td), _("can't use 'new' on ref type '%s'\n"), t->name)
93
25
  if(GET_FLAG(t, abstract))
94
1
    ERR_N(td_pos(unary->td), _("can't use 'new' on abstract type '%s'\n"), t->name)
95
24
  UNSET_FLAG(unary->td, ref);
96
24
  if(unary->td->array)
97
3
    CHECK_BN(check_subscripts(env, unary->td->array, 1))
98
24
  return t;
99
}
100
101
19
OP_EMIT(opem_new) {
102
19
  const Exp_Unary* unary = (Exp_Unary*)data;
103
19
  CHECK_BO(emit_instantiate_object(emit, exp_self(unary)->info->type,
104
    unary->td->array, GET_FLAG(unary->td, ref)))
105
19
  return emit_gc(emit, -SZ_INT);
106
}