GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/import/cdef.c Lines: 74 82 90.2 %
Date: 2020-09-14 09:03:05 Branches: 36 48 75.0 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#include <ctype.h>
4
#include "gwion_util.h"
5
#include "gwion_ast.h"
6
#include "gwion_env.h"
7
#include "vm.h"
8
#include "traverse.h"
9
#include "instr.h"
10
#include "object.h"
11
#include "emit.h"
12
#include "gwion.h"
13
#include "operator.h"
14
#include "import.h"
15
#include "gwi.h"
16
#include "mpool.h"
17
#include "specialid.h"
18
#include "template.h"
19
20
16355
ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_flag e) {
21
16355
  VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
22
16355
  const m_str name = type->name;
23
16355
  *code = new_vm_code(p, NULL, SZ_INT, e | ae_flag_member | ae_flag_builtin, name);
24
16355
  (*code)->native_func = (m_uint)d;
25
16355
  type->flag |= e;
26
16355
  return GW_OK;
27
}
28
29
12818
ANN2(1,2) static inline m_bool class_parent(const Env env, Type t) {
30

37044
  while(t && !GET_FLAG(t, valid)) {
31
11408
    if(t->e->def)
32
      CHECK_BB(traverse_class_def(env, t->e->def))
33
11408
    t = t->e->parent;
34
  }
35
12818
  return GW_OK;
36
}
37
38
12818
ANN2(1,2) static void import_class_ini(const Env env, const Type t) {
39
12818
  t->nspc = new_nspc(env->gwion->mp, t->name);
40
12818
  t->nspc->parent = env->curr;
41
12818
  if(isa(t, env->gwion->type[et_object]) > 0)
42
12818
    inherit(t);
43
12818
  t->e->owner = env->curr;
44
12818
  t->e->owner_class = env->class_def;
45
12818
  SET_FLAG(t, valid);
46
12818
  env_push_type(env, t);
47
12818
}
48
49
9956
ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) {
50
9956
  const Type t = gwi->gwion->env->class_def;
51
9956
  if(ctor)
52
7112
    mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, ae_flag_ctor);
53
9956
  if(dtor)
54
9243
    mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, ae_flag_dtor);
55
9956
}
56
57
11395
ANN static inline void gwi_type_flag(const Type t) {
58
11395
  SET_FLAG(t, scan1 | ae_flag_scan2 | ae_flag_check | ae_flag_emit);
59
11395
}
60
61
12818
ANN static Type type_finish(const Gwi gwi, const Type t) {
62
12818
  gwi_add_type(gwi, t);
63
12818
  import_class_ini(gwi->gwion->env, t);
64
12818
  return t;
65
}
66
67
12818
ANN2(1,2) Type handle_class(const Gwi gwi, Type_Decl *td) {
68
12818
  DECL_OO(const Type, p, = known_type(gwi->gwion->env, td))
69
12818
  CHECK_BO(class_parent(gwi->gwion->env, p))
70
12818
  return p;
71
}
72
73
12820
ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent) {
74
12820
  struct ImportCK ck = { .name=name };
75
12820
  CHECK_BO(check_typename_def(gwi, &ck))
76

12818
  DECL_OO(Type_Decl *,td, = str2decl(gwi, parent ?: "Object"))
77
12818
  Tmpl* tmpl = ck.tmpl ? new_tmpl_base(gwi->gwion->mp, ck.tmpl) : NULL;
78
12818
  if(tmpl)
79
1423
    CHECK_BO(template_push_types(gwi->gwion->env, tmpl))
80
12818
  const Type base = find_type(gwi->gwion->env, td);
81
12818
  const Type_List tl = td->types;
82
12818
  if(GET_FLAG(base, unary))
83
711
    td->types = NULL;
84
12818
  const Type p = !td->types ? handle_class(gwi, td) : NULL;
85
12818
  td->types = tl;
86
12818
  if(tmpl)
87
1423
    nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
88
12818
  CHECK_OO(p)
89
12818
  const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, s_name(ck.sym), p);
90
12818
  t->e->def = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
91
12818
  t->e->def->base.tmpl = tmpl;
92
12818
  t->e->def->base.type = t;
93
12818
  t->e->tuple = new_tupleform(gwi->gwion->mp, p);
94
12818
  t->e->parent = p;
95
12818
  if(td->array)
96
1
    SET_FLAG(t, typedef);
97
12818
  if(ck.tmpl)
98
1423
    SET_FLAG(t, template);
99
  else
100
11395
    gwi_type_flag(t);
101
12818
  return type_finish(gwi, t);
102
}
103
104
ANN Type gwi_struct_ini(const Gwi gwi, const m_str name) {
105
  CHECK_OO(str2sym(gwi, name))
106
  const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, name, gwi->gwion->type[et_compound]);
107
  t->e->tuple = new_tupleform(gwi->gwion->mp, NULL);
108
  gwi_type_flag(t);
109
  SET_FLAG(t, struct);
110
  return type_finish(gwi, t);
111
}
112
113
12811
ANN m_int gwi_class_end(const Gwi gwi) {
114
12811
  if(!gwi->gwion->env->class_def)
115
1
    GWI_ERR_B(_("import: too many class_end called."))
116
12810
  nspc_allocdata(gwi->gwion->mp, gwi->gwion->env->class_def->nspc);
117
12810
  env_pop(gwi->gwion->env, 0);
118
12810
  return GW_OK;
119
}