1 |
|
|
#include "gwion_util.h" |
2 |
|
|
#include "gwion_ast.h" |
3 |
|
|
#include "gwion_env.h" |
4 |
|
|
#include "vm.h" |
5 |
|
|
#include "gwion.h" |
6 |
|
|
|
7 |
|
|
static m_str const special_name[] = { "^nonnull", "^force" }; |
8 |
|
|
#define SPECIAL_LEN strlen(special_name[0]) + strlen(special_name[1]) |
9 |
|
|
static const ae_flag special_flag[] = { ae_flag_nonnull, ae_flag_force }; |
10 |
|
|
|
11 |
|
|
typedef struct { |
12 |
|
|
const Type type; |
13 |
|
|
Symbol name; |
14 |
|
|
ae_flag flag; |
15 |
|
|
uint st_type; |
16 |
|
|
} SpecialType; |
17 |
|
|
|
18 |
|
|
|
19 |
|
4333 |
ANN static Type specialtype_create(const Env env, const SpecialType *s) { |
20 |
|
4333 |
const Type t = type_copy(env->gwion->mp, s->type); |
21 |
✓✓ |
4333 |
if(t->nspc) |
22 |
|
4287 |
ADD_REF(t->nspc) |
23 |
|
4333 |
t->name = s_name(s->name); |
24 |
|
4333 |
t->flag = s->type->flag | s->flag; |
25 |
|
4333 |
t->e->parent = unflag_type(s->type); |
26 |
|
4333 |
nspc_add_type_front(s->type->e->owner, s->name, t); |
27 |
|
4333 |
mk_class(env, t); |
28 |
|
4333 |
return t; |
29 |
|
|
} |
30 |
|
|
|
31 |
|
17926 |
static inline int get_flag(const Type t, const ae_flag flag) { |
32 |
|
17926 |
return (t->flag & flag) == flag; |
33 |
|
|
} |
34 |
|
|
|
35 |
|
|
|
36 |
|
35852 |
ANN static void specialtype_flag(SpecialType *s, m_str c, const uint i) { |
37 |
|
35852 |
const ae_flag flag = special_flag[i]; |
38 |
✓✓✓✓
|
35852 |
if(i == s->st_type || get_flag(s->type, flag)) { |
39 |
|
17931 |
strcat(c, special_name[i]); |
40 |
|
17931 |
s->flag |= flag; |
41 |
|
|
} |
42 |
|
35852 |
} |
43 |
|
|
|
44 |
|
17926 |
ANN static void specialtype_init(SymTable *st, SpecialType *s) { |
45 |
|
17926 |
const size_t sz = strlen(s->type->name); |
46 |
|
17926 |
char c[sz + SPECIAL_LEN + 1]; |
47 |
|
17926 |
strcpy(c, s->type->name); |
48 |
|
17926 |
m_str flagged = strchr(c, '^'); |
49 |
✓✓ |
17926 |
if(flagged) |
50 |
|
5 |
*flagged = '\0'; |
51 |
|
17926 |
specialtype_flag(s, c, 0); |
52 |
|
17926 |
specialtype_flag(s, c, 1); |
53 |
|
17926 |
s->name = insert_symbol(st, c); |
54 |
|
17926 |
} |
55 |
|
|
|
56 |
|
17926 |
ANN Type special_type(const Env env, const Type t, const uint st_type) { |
57 |
|
17926 |
SpecialType s = { .type=t, .st_type=st_type }; |
58 |
|
17926 |
specialtype_init(env->gwion->st, &s); |
59 |
✓✓ |
17926 |
return nspc_lookup_type1(t->e->owner, s.name) ?: |
60 |
|
|
specialtype_create(env, &s); |
61 |
|
|
} |