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 |
|
195 |
OP_CHECK(opck_const_rhs) { |
26 |
|
195 |
const Exp_Binary* bin = (Exp_Binary*)data; |
27 |
|
195 |
const m_str access = exp_access(bin->rhs); |
28 |
✓✓ |
195 |
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 |
|
189 |
return bin->rhs->info->type; |
34 |
|
|
} |
35 |
|
|
|
36 |
|
176 |
OP_CHECK(opck_rassign) { |
37 |
|
176 |
const Exp_Binary* bin = (Exp_Binary*)data; |
38 |
✓✓ |
176 |
if(opck_const_rhs(env, data, mut) == env->gwion->type[et_null]) |
39 |
|
5 |
return env->gwion->type[et_null]; |
40 |
|
171 |
exp_setvar(bin->rhs, 1); |
41 |
|
171 |
return bin->rhs->info->type; |
42 |
|
|
} |
43 |
|
|
|
44 |
|
31 |
OP_CHECK(opck_unary_meta) { |
45 |
|
31 |
const Exp_Unary* unary = (Exp_Unary*)data; |
46 |
|
31 |
exp_setmeta(exp_self(unary), 1); |
47 |
|
31 |
return unary->exp->info->type; |
48 |
|
|
} |
49 |
|
|
|
50 |
|
5 |
OP_CHECK(opck_unary_meta2) { |
51 |
|
5 |
const Exp_Unary* unary = (Exp_Unary*)data; |
52 |
|
5 |
exp_setmeta(exp_self(unary), 1); |
53 |
|
5 |
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 |
|
27 |
OP_CHECK(opck_new) { |
78 |
|
27 |
const Exp_Unary* unary = (Exp_Unary*)data; |
79 |
|
27 |
SET_FLAG(unary->td, ref); |
80 |
✓✓ |
27 |
DECL_ON(const Type, t, = known_type(env, unary->td)) |
81 |
✓✓ |
26 |
if(isa(t, env->gwion->type[et_object]) < 0) |
82 |
|
1 |
ERR_N(exp_self(unary)->pos, _("can't use 'new' on non-object types...\n")) |
83 |
✓✓ |
25 |
if(type_ref(t)) |
84 |
|
1 |
ERR_N(td_pos(unary->td), _("can't use 'new' on ref type '%s'\n"), t->name) |
85 |
✓✓ |
24 |
if(GET_FLAG(t, abstract)) |
86 |
|
1 |
ERR_N(td_pos(unary->td), _("can't use 'new' on abstract type '%s'\n"), t->name) |
87 |
|
23 |
UNSET_FLAG(unary->td, ref); |
88 |
✓✓ |
23 |
if(unary->td->array) |
89 |
✗✓ |
3 |
CHECK_BN(check_subscripts(env, unary->td->array, 1)) |
90 |
|
23 |
return t; |
91 |
|
|
} |
92 |
|
|
|
93 |
|
19 |
OP_EMIT(opem_new) { |
94 |
|
19 |
const Exp_Unary* unary = (Exp_Unary*)data; |
95 |
✗✓ |
19 |
CHECK_BO(emit_instantiate_object(emit, exp_self(unary)->info->type, |
96 |
|
|
unary->td->array, GET_FLAG(unary->td, ref))) |
97 |
|
19 |
return emit_add_instr(emit, GcAdd); |
98 |
|
|
} |