GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/import/import_cdef.c Lines: 75 83 90.4 %
Date: 2020-09-14 20:46:08 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
16378
ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_flag e) {
21
16378
  VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
22
16378
  const m_str name = type->name;
23
16378
  *code = new_vm_code(p, NULL, SZ_INT, e | ae_flag_member | ae_flag_builtin, name);
24
16378
  (*code)->native_func = (m_uint)d;
25
16378
  type->flag |= e;
26
16378
  return GW_OK;
27
}
28
29
18548
ANN2(1,2) static inline m_bool class_parent(const Env env, Type t) {
30
  do {
31
18548
    if(GET_FLAG(t, valid))
32
7124
      break;
33
11424
    if(t->e->def)
34
      CHECK_BB(traverse_class_def(env, t->e->def))
35
11424
  } while((t = t->e->parent));
36
12836
  return GW_OK;
37
}
38
39
12836
ANN2(1,2) static void import_class_ini(const Env env, const Type t) {
40
12836
  t->nspc = new_nspc(env->gwion->mp, t->name);
41
12836
  t->nspc->parent = env->curr;
42
12836
  if(isa(t, env->gwion->type[et_object]) > 0)
43
12836
    inherit(t);
44
12836
  t->e->owner = env->curr;
45
12836
  t->e->owner_class = env->class_def;
46
12836
  SET_FLAG(t, valid);
47
12836
  env_push_type(env, t);
48
12836
}
49
50
9970
ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) {
51
9970
  const Type t = gwi->gwion->env->class_def;
52
9970
  if(ctor)
53
7122
    mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, ae_flag_ctor);
54
9970
  if(dtor)
55
9256
    mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, ae_flag_dtor);
56
9970
}
57
58
11411
ANN static inline void gwi_type_flag(const Type t) {
59
11411
  SET_FLAG(t, scan1 | ae_flag_scan2 | ae_flag_check | ae_flag_emit);
60
11411
}
61
62
12836
ANN static Type type_finish(const Gwi gwi, const Type t) {
63
12836
  gwi_add_type(gwi, t);
64
12836
  import_class_ini(gwi->gwion->env, t);
65
12836
  return t;
66
}
67
68
12836
ANN2(1,2) Type handle_class(const Gwi gwi, Type_Decl *td) {
69
12836
  DECL_OO(const Type, p, = known_type(gwi->gwion->env, td))
70
12836
  CHECK_BO(class_parent(gwi->gwion->env, p))
71
12836
  return p;
72
}
73
74
12838
ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent) {
75
12838
  struct ImportCK ck = { .name=name };
76
12838
  CHECK_BO(check_typename_def(gwi, &ck))
77

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