1 |
|
|
#include "gwion_util.h" |
2 |
|
|
#include "gwion_ast.h" |
3 |
|
|
#include "gwion_env.h" |
4 |
|
|
#include "vm.h" |
5 |
|
|
#include "gwion.h" |
6 |
|
|
#include "instr.h" |
7 |
|
|
#include "object.h" |
8 |
|
|
#include "emit.h" |
9 |
|
|
#include "operator.h" |
10 |
|
|
#include "import.h" |
11 |
|
|
#include "gwi.h" |
12 |
|
|
#include "driver.h" |
13 |
|
|
#include "traverse.h" |
14 |
|
|
#include "parse.h" |
15 |
|
|
#include "specialid.h" |
16 |
|
|
#include "array.h" |
17 |
|
|
#include "gack.h" |
18 |
|
|
|
19 |
|
|
#define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func) |
20 |
|
|
|
21 |
|
711 |
GWION_IMPORT(int_op) { |
22 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "int", "int", "int")) |
23 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "+", int_plus)) |
24 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "-", int_minus)) |
25 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "*", int_mul)) |
26 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "/", int_div)) |
27 |
|
711 |
return gwi_oper_end(gwi, "%", int_modulo); |
28 |
|
|
} |
29 |
|
|
|
30 |
|
711 |
static GWION_IMPORT(int_logical) { |
31 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "&&", int_and)) |
32 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "||", int_or)) |
33 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "==", int_eq)) |
34 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "!=", int_neq)) |
35 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">", int_gt)) |
36 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">=", int_ge)) |
37 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<", int_lt)) |
38 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<=", int_le)) |
39 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">>", int_sr)) |
40 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<<", int_sl)) |
41 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "&", int_sand)) |
42 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "|", int_sor)) |
43 |
|
711 |
return gwi_oper_end(gwi, "^", int_xor); |
44 |
|
|
} |
45 |
|
|
|
46 |
|
711 |
static GWION_IMPORT(int_r) { |
47 |
|
711 |
CHECK_OP("=>", rassign, r_assign) |
48 |
|
711 |
CHECK_OP("+=>", rassign, r_plus) |
49 |
|
711 |
CHECK_OP("-=>", rassign, r_minus) |
50 |
|
711 |
CHECK_OP("*=>", rassign, r_mul) |
51 |
|
711 |
CHECK_OP("/=>", rassign, r_div) |
52 |
|
711 |
CHECK_OP("%=>", rassign, r_modulo) |
53 |
|
711 |
CHECK_OP("<<=>", rassign, r_sl) |
54 |
|
711 |
CHECK_OP(">>=>", rassign, r_sr) |
55 |
|
711 |
CHECK_OP("&=>", rassign, r_sand) |
56 |
|
711 |
CHECK_OP("|=>", rassign, r_sor) |
57 |
|
711 |
CHECK_OP("^=>", rassign, r_sxor) |
58 |
|
711 |
return GW_OK; |
59 |
|
|
} |
60 |
|
|
|
61 |
|
2 |
static INSTR(IntRange) { |
62 |
|
2 |
shred->reg -= SZ_INT *2; |
63 |
|
2 |
const m_int start = *(m_int*)REG(0); |
64 |
|
2 |
const m_int end = *(m_int*)REG(SZ_INT); |
65 |
✓✓ |
2 |
const m_int op = start < end ? 1 : -1; |
66 |
✓✓ |
2 |
const m_uint sz = op > 0 ? end - start : start - end; |
67 |
|
2 |
const M_Object array = new_array(shred->info->vm->gwion->mp, (Type)instr->m_val, sz); |
68 |
✓✓ |
9 |
for(m_int i = start, j = 0; i != end; i += op, ++j) |
69 |
|
7 |
m_vector_set(ARRAY(array), j, &i); |
70 |
|
2 |
*(M_Object*)REG(0) = array; |
71 |
|
2 |
PUSH_REG(shred, SZ_INT); |
72 |
|
2 |
} |
73 |
|
|
|
74 |
|
2 |
static OP_CHECK(opck_int_range) { |
75 |
|
2 |
const Exp exp = (Exp)data; |
76 |
|
2 |
const Range *range = exp->d.prim.d.range; |
77 |
✓✗ |
2 |
const Exp e = range->start ?: range->end; |
78 |
|
2 |
return array_type(env, e->info->type, 1); |
79 |
|
|
} |
80 |
|
|
|
81 |
|
2 |
static OP_EMIT(opem_int_range) { |
82 |
|
2 |
const Exp exp = (Exp)data; |
83 |
|
2 |
const Instr instr = emit_add_instr(emit, IntRange); |
84 |
|
2 |
instr->m_val = (m_uint)exp->info->type; |
85 |
|
2 |
return instr; |
86 |
|
|
} |
87 |
|
|
|
88 |
|
711 |
static GWION_IMPORT(int_unary) { |
89 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, NULL, "int", "int")) |
90 |
|
711 |
GWI_BB(gwi_oper_add(gwi, opck_unary_meta)) |
91 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "-", int_negate)) |
92 |
|
711 |
CHECK_OP("++", unary, pre_inc) |
93 |
|
711 |
CHECK_OP("--", unary, pre_dec) |
94 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "~", int_cmp)) |
95 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, NULL, "int", NULL)) |
96 |
|
711 |
GWI_BB(gwi_oper_add(gwi, opck_int_range)) |
97 |
|
711 |
GWI_BB(gwi_oper_emi(gwi, opem_int_range)) |
98 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "@range", NULL)) |
99 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "int", NULL, "int")) |
100 |
|
711 |
CHECK_OP("++", post, post_inc) |
101 |
|
711 |
GWI_BB(gwi_oper_add(gwi, opck_post)) |
102 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "--", int_post_dec)) |
103 |
|
711 |
return GW_OK; |
104 |
|
|
} |
105 |
|
11 |
static GACK(gack_bool) { |
106 |
|
|
// gw_out("%s", *(m_uint*)VALUE ? "true" : "false"); |
107 |
✓✓ |
11 |
INTERP_PRINTF("%s", *(m_uint*)VALUE ? "true" : "false"); |
108 |
|
11 |
} |
109 |
|
|
|
110 |
|
711 |
static GWION_IMPORT(int_values) { |
111 |
|
711 |
GWI_BB(gwi_enum_ini(gwi, "bool")) |
112 |
|
711 |
GWI_BB(gwi_enum_add(gwi, "false", 0)) |
113 |
|
711 |
GWI_BB(gwi_enum_add(gwi, "true", 1)) |
114 |
|
711 |
const Type t_bool = gwi_enum_end(gwi); |
115 |
|
711 |
GWI_BB(gwi_gack(gwi, t_bool, gack_bool)) |
116 |
|
711 |
gwi->gwion->type[et_bool] = t_bool; |
117 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, NULL, "int", "bool")) |
118 |
|
711 |
GWI_BB(gwi_oper_add(gwi, opck_unary_meta)) // should return bool |
119 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "!", IntNot)) |
120 |
|
711 |
struct SpecialId_ spid = { .type=t_bool, .exec=RegPushMaybe, .is_const=1 }; |
121 |
|
711 |
gwi_specialid(gwi, "maybe", &spid); |
122 |
|
711 |
return GW_OK; |
123 |
|
|
} |
124 |
|
|
|
125 |
|
711 |
static GWION_IMPORT(int) { |
126 |
|
711 |
GWI_BB(import_int_values(gwi)) |
127 |
|
711 |
GWI_BB(gwi_oper_cond(gwi, "int", BranchEqInt, BranchNeqInt)) |
128 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "int", "int", "int")) |
129 |
|
711 |
GWI_BB(import_int_op(gwi)) |
130 |
|
711 |
GWI_BB(import_int_logical(gwi)) |
131 |
|
711 |
GWI_BB(import_int_r(gwi)) |
132 |
|
711 |
GWI_BB(import_int_unary(gwi)) |
133 |
|
711 |
return GW_OK; |
134 |
|
|
} |
135 |
|
|
|
136 |
|
3 |
static OP_CHECK(opck_cast_f2i) { |
137 |
|
3 |
return env->gwion->type[et_int]; |
138 |
|
|
} |
139 |
|
|
|
140 |
|
5 |
static OP_CHECK(opck_implicit_f2i) { |
141 |
|
5 |
return env->gwion->type[et_null]; |
142 |
|
|
} |
143 |
|
|
|
144 |
|
2 |
static OP_CHECK(opck_cast_i2f) { |
145 |
|
2 |
return env->gwion->type[et_float]; |
146 |
|
|
} |
147 |
|
|
|
148 |
|
15 |
static OP_CHECK(opck_implicit_i2f) { |
149 |
|
15 |
struct Implicit* imp = (struct Implicit*)data; |
150 |
|
15 |
return imp->e->info->cast_to = env->gwion->type[et_float]; |
151 |
|
|
} |
152 |
|
|
|
153 |
|
|
#define CHECK_FF(op, check, func) _CHECK_OP(op, check, float_##func) |
154 |
|
|
#define CHECK_IF(op, check, func) _CHECK_OP(op, check, int_float_##func) |
155 |
|
|
#define CHECK_FI(op, check, func) _CHECK_OP(op, check, float_int_##func) |
156 |
|
|
|
157 |
|
711 |
static GWION_IMPORT(intfloat) { |
158 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "int", "float", "int")) |
159 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "&&", int_float_and)) |
160 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "||", int_float_or)) |
161 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "==", int_float_eq)) |
162 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "!=", int_float_neq)) |
163 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">", int_float_gt)) |
164 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">=", int_float_ge)) |
165 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<", int_float_lt)) |
166 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<=", int_float_le)) |
167 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "int", "float", "float")) |
168 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "+", int_float_plus)) |
169 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "*", int_float_mul)) |
170 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "-", int_float_minus)) |
171 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "/", int_float_div)) |
172 |
|
711 |
CHECK_IF("=>", rassign, r_assign) |
173 |
|
711 |
CHECK_IF("+=>", rassign, r_plus) |
174 |
|
711 |
CHECK_IF("-=>", rassign, r_minus) |
175 |
|
711 |
CHECK_IF("*=>", rassign, r_mul) |
176 |
|
711 |
CHECK_IF("/=>", rassign, r_div) |
177 |
|
711 |
_CHECK_OP("$", cast_i2f, CastI2F) |
178 |
|
711 |
_CHECK_OP("@implicit", implicit_i2f, CastI2F) |
179 |
|
711 |
return GW_OK; |
180 |
|
|
} |
181 |
|
|
|
182 |
|
711 |
static GWION_IMPORT(floatint) { |
183 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "float", "int", "float")) |
184 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "+", float_int_plus)) |
185 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "-", float_int_minus)) |
186 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "*", float_int_mul)) |
187 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "/", float_int_div)) |
188 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "float", "int", "int")) |
189 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "&&", float_int_and)) |
190 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "||", float_int_or)) |
191 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "==", float_int_eq)) |
192 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "!=", float_int_neq)) |
193 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">", float_int_gt)) |
194 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">=", float_int_ge)) |
195 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<", float_int_lt)) |
196 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<=", float_int_le)) |
197 |
|
711 |
CHECK_FI("=>", rassign, r_assign) |
198 |
|
711 |
CHECK_FI("+=>", rassign, r_plus) |
199 |
|
711 |
CHECK_FI("-=>", rassign, r_minus) |
200 |
|
711 |
CHECK_FI("*=>", rassign, r_mul) |
201 |
|
711 |
CHECK_FI("/=>", rassign, r_div) |
202 |
|
711 |
_CHECK_OP("$", cast_f2i, CastF2I) |
203 |
|
711 |
_CHECK_OP("@implicit", implicit_f2i, CastF2I) |
204 |
|
711 |
return GW_OK; |
205 |
|
|
} |
206 |
|
|
|
207 |
|
711 |
static GWION_IMPORT(dur) { |
208 |
|
711 |
GWI_BB(gwi_oper_cond(gwi, "dur", BranchEqFloat, BranchNeqFloat)) |
209 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "dur")) |
210 |
|
711 |
CHECK_FF("=>", rassign, r_assign) |
211 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "+", FloatPlus)) |
212 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "-", FloatMinus)) |
213 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "*", FloatTimes)) |
214 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "float")) |
215 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "/", FloatDivide)) |
216 |
|
|
|
217 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "int")) |
218 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">", float_gt)) |
219 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">=", float_ge)) |
220 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<", float_lt)) |
221 |
|
711 |
return gwi_oper_end(gwi, "<=", float_le); |
222 |
|
|
} |
223 |
|
|
|
224 |
|
|
|
225 |
|
68 |
static inline int is_now(const Env env, const Exp exp) { |
226 |
✓✗ |
136 |
return exp->exp_type == ae_exp_primary && |
227 |
✓✗✓✗
|
136 |
exp->d.prim.prim_type == ae_prim_id && |
228 |
|
68 |
exp->d.prim.d.var == insert_symbol("now"); |
229 |
|
|
} |
230 |
|
|
|
231 |
|
68 |
static OP_CHECK(opck_now) { |
232 |
|
68 |
const Exp_Binary* bin = (Exp_Binary*)data; |
233 |
✗✓ |
68 |
if(!is_now(env, bin->rhs)) |
234 |
|
|
CHECK_NN(opck_const_rhs(env, data, mut)) |
235 |
|
68 |
exp_setvar(bin->rhs, 1); |
236 |
|
68 |
return bin->rhs->info->type; |
237 |
|
|
} |
238 |
|
|
|
239 |
|
711 |
static GWION_IMPORT(time) { |
240 |
|
711 |
GWI_BB(gwi_oper_cond(gwi, "time", BranchEqFloat, BranchNeqFloat)) |
241 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "time", "time", "time")) |
242 |
|
711 |
CHECK_FF("=>", rassign, r_assign) |
243 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "time", "dur", "time")) |
244 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "+", FloatPlus)) |
245 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "dur", "time", "time")) |
246 |
|
711 |
CHECK_FF("=>", rassign, r_assign) |
247 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "+", FloatPlus)) |
248 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "dur", "@now", "time")) |
249 |
|
711 |
_CHECK_OP("=>", now, Time_Advance) |
250 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "time", "time", "int")) |
251 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">", float_gt)) |
252 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">=", float_ge)) |
253 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<", float_lt)) |
254 |
|
711 |
return gwi_oper_end(gwi, "<=", float_le); |
255 |
|
|
} |
256 |
|
|
|
257 |
|
711 |
static GWION_IMPORT(float) { |
258 |
|
711 |
GWI_BB(gwi_oper_cond(gwi, "float", BranchEqFloat, BranchNeqFloat)) |
259 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "float", "float", "float")) |
260 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "+", FloatPlus)) |
261 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "-", FloatMinus)) |
262 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "*", FloatTimes)) |
263 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "/", FloatDivide)) |
264 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) |
265 |
|
711 |
CHECK_FF("=>", rassign, r_assign) |
266 |
|
711 |
CHECK_FF("+=>", rassign, r_plus) |
267 |
|
711 |
CHECK_FF("-=>", rassign, r_minus) |
268 |
|
711 |
CHECK_FF("*=>", rassign, r_mul) |
269 |
|
711 |
CHECK_FF("/=>", rassign, r_div) |
270 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "float", "float", "int")) |
271 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "&&", float_and)) |
272 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "||", float_or)) |
273 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "==", float_eq)) |
274 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "!=", float_neq)) |
275 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">", float_gt)) |
276 |
|
711 |
GWI_BB(gwi_oper_end(gwi, ">=", float_ge)) |
277 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<", float_lt)) |
278 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "<=", float_le)) |
279 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, NULL, "float", "float")) |
280 |
|
711 |
CHECK_FF("-", unary_meta, negate) |
281 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, NULL, "float", "int")) |
282 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, NULL, "time", "int")) |
283 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, NULL, "dur", "int")) |
284 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "int", "dur", "dur")) |
285 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "::", int_float_mul)) |
286 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, "float", "dur", "dur")) |
287 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "::", FloatTimes)) |
288 |
|
711 |
GWI_BB(gwi_oper_ini(gwi, NULL, "float", "bool")) |
289 |
|
711 |
GWI_BB(gwi_oper_add(gwi, opck_unary_meta2)) // should return bool |
290 |
|
711 |
GWI_BB(gwi_oper_end(gwi, "!", float_not)) |
291 |
|
711 |
return GW_OK; |
292 |
|
|
} |
293 |
|
|
|
294 |
|
711 |
GWION_IMPORT(prim) { |
295 |
|
711 |
GWI_BB(import_int(gwi)) |
296 |
|
711 |
GWI_BB(import_float(gwi)) |
297 |
|
711 |
GWI_BB(import_intfloat(gwi)) |
298 |
|
711 |
GWI_BB(import_floatint(gwi)) |
299 |
|
711 |
GWI_BB(import_dur(gwi)) |
300 |
|
711 |
return import_time(gwi); |
301 |
|
|
} |