GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/lib/prim.c Lines: 233 234 99.6 %
Date: 2020-09-22 13:02:15 Branches: 13 20 65.0 %

Line Branch Exec Source
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
712
GWION_IMPORT(int_op) {
22
712
  GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
23
712
  GWI_BB(gwi_oper_end(gwi, "+", int_plus))
24
712
  GWI_BB(gwi_oper_end(gwi, "-", int_minus))
25
712
  GWI_BB(gwi_oper_end(gwi, "*", int_mul))
26
712
  GWI_BB(gwi_oper_end(gwi, "/", int_div))
27
712
  return gwi_oper_end(gwi, "%", int_modulo);
28
}
29
30
712
static GWION_IMPORT(int_logical) {
31
712
  GWI_BB(gwi_oper_end(gwi, "&&",  int_and))
32
712
  GWI_BB(gwi_oper_end(gwi, "||",   int_or))
33
712
  GWI_BB(gwi_oper_end(gwi, "==",   int_eq))
34
712
  GWI_BB(gwi_oper_end(gwi, "!=",   int_neq))
35
712
  GWI_BB(gwi_oper_end(gwi, ">",   int_gt))
36
712
  GWI_BB(gwi_oper_end(gwi, ">=",   int_ge))
37
712
  GWI_BB(gwi_oper_end(gwi, "<",   int_lt))
38
712
  GWI_BB(gwi_oper_end(gwi, "<=",   int_le))
39
712
  GWI_BB(gwi_oper_end(gwi, ">>",  int_sr))
40
712
  GWI_BB(gwi_oper_end(gwi, "<<",  int_sl))
41
712
  GWI_BB(gwi_oper_end(gwi, "&", int_sand))
42
712
  GWI_BB(gwi_oper_end(gwi, "|",  int_sor))
43
712
  return   gwi_oper_end(gwi, "^", int_xor);
44
}
45
46
712
static GWION_IMPORT(int_r) {
47
712
  CHECK_OP("=>", rassign, r_assign)
48
712
  CHECK_OP("+=>",  rassign, r_plus)
49
712
  CHECK_OP("-=>",  rassign, r_minus)
50
712
  CHECK_OP("*=>",  rassign, r_mul)
51
712
  CHECK_OP("/=>",  rassign, r_div)
52
712
  CHECK_OP("%=>",  rassign, r_modulo)
53
712
  CHECK_OP("<<=>",   rassign, r_sl)
54
712
  CHECK_OP(">>=>",   rassign, r_sr)
55
712
  CHECK_OP("&=>", rassign, r_sand)
56
712
  CHECK_OP("|=>",  rassign, r_sor)
57
712
  CHECK_OP("^=>", rassign, r_sxor)
58
712
  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
712
static GWION_IMPORT(int_unary) {
89
712
  GWI_BB(gwi_oper_ini(gwi, NULL, "int", "int"))
90
712
  GWI_BB(gwi_oper_add(gwi, opck_unary_meta))
91
712
  GWI_BB(gwi_oper_end(gwi, "-", int_negate))
92
712
  CHECK_OP("++", unary, pre_inc)
93
712
  CHECK_OP("--", unary, pre_dec)
94
712
  GWI_BB(gwi_oper_end(gwi,  "~", int_cmp))
95
712
  GWI_BB(gwi_oper_ini(gwi, NULL, "int", NULL))
96
712
  GWI_BB(gwi_oper_add(gwi, opck_int_range))
97
712
  GWI_BB(gwi_oper_emi(gwi, opem_int_range))
98
712
  GWI_BB(gwi_oper_end(gwi, "@range", NULL))
99
712
  GWI_BB(gwi_oper_ini(gwi, "int", NULL, "int"))
100
712
  CHECK_OP("++", post, post_inc)
101
712
  GWI_BB(gwi_oper_add(gwi, opck_post))
102
712
  GWI_BB(gwi_oper_end(gwi, "--", int_post_dec))
103
712
  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
712
static GWION_IMPORT(int_values) {
111
712
  GWI_BB(gwi_enum_ini(gwi, "bool"))
112
712
  GWI_BB(gwi_enum_add(gwi, "false", 0))
113
712
  GWI_BB(gwi_enum_add(gwi, "true", 1))
114
712
  const Type t_bool = gwi_enum_end(gwi);
115
712
  GWI_BB(gwi_gack(gwi, t_bool, gack_bool))
116
712
  gwi->gwion->type[et_bool] = t_bool;
117
712
  GWI_BB(gwi_oper_ini(gwi, NULL, "int", "bool"))
118
712
  GWI_BB(gwi_oper_add(gwi, opck_unary_meta)) // should return bool
119
712
  GWI_BB(gwi_oper_end(gwi,  "!", IntNot))
120
712
  struct SpecialId_ spid = { .type=t_bool, .exec=RegPushMaybe, .is_const=1 };
121
712
  gwi_specialid(gwi, "maybe", &spid);
122
712
  return GW_OK;
123
}
124
125
712
static GWION_IMPORT(int) {
126
712
  GWI_BB(import_int_values(gwi))
127
712
  GWI_BB(gwi_oper_cond(gwi, "int", BranchEqInt, BranchNeqInt))
128
712
  GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
129
712
  GWI_BB(import_int_op(gwi))
130
712
  GWI_BB(import_int_logical(gwi))
131
712
  GWI_BB(import_int_r(gwi))
132
712
  GWI_BB(import_int_unary(gwi))
133
712
  return GW_OK;
134
}
135
136
2
static OP_CHECK(opck_cast_f2i) {
137
2
  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
14
static OP_CHECK(opck_implicit_i2f) {
149
14
  struct Implicit* imp = (struct Implicit*)data;
150
14
  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
712
static GWION_IMPORT(intfloat) {
158
712
  GWI_BB(gwi_oper_ini(gwi, "int", "float", "int"))
159
712
  GWI_BB(gwi_oper_end(gwi, "&&",           int_float_and))
160
712
  GWI_BB(gwi_oper_end(gwi, "||",            int_float_or))
161
712
  GWI_BB(gwi_oper_end(gwi, "==", 			 int_float_eq))
162
712
  GWI_BB(gwi_oper_end(gwi, "!=", 			 int_float_neq))
163
712
  GWI_BB(gwi_oper_end(gwi, ">", 			 int_float_gt))
164
712
  GWI_BB(gwi_oper_end(gwi, ">=", 			 int_float_ge))
165
712
  GWI_BB(gwi_oper_end(gwi, "<", 			 int_float_lt))
166
712
  GWI_BB(gwi_oper_end(gwi, "<=", 			 int_float_le))
167
712
  GWI_BB(gwi_oper_ini(gwi, "int", "float", "float"))
168
712
  GWI_BB(gwi_oper_end(gwi, "+",          int_float_plus))
169
712
  GWI_BB(gwi_oper_end(gwi, "*",         int_float_mul))
170
712
  GWI_BB(gwi_oper_end(gwi, "-",         int_float_minus))
171
712
  GWI_BB(gwi_oper_end(gwi, "/",        int_float_div))
172
712
  CHECK_IF("=>", rassign, r_assign)
173
712
  CHECK_IF("+=>", rassign, r_plus)
174
712
  CHECK_IF("-=>", rassign, r_minus)
175
712
  CHECK_IF("*=>", rassign, r_mul)
176
712
  CHECK_IF("/=>", rassign, r_div)
177
712
  _CHECK_OP("$", cast_i2f, CastI2F)
178
712
  _CHECK_OP("@implicit", implicit_i2f, CastI2F)
179
712
  return GW_OK;
180
}
181
182
712
static GWION_IMPORT(floatint) {
183
712
  GWI_BB(gwi_oper_ini(gwi, "float", "int", "float"))
184
712
  GWI_BB(gwi_oper_end(gwi, "+",         float_int_plus))
185
712
  GWI_BB(gwi_oper_end(gwi, "-",        float_int_minus))
186
712
  GWI_BB(gwi_oper_end(gwi, "*",        float_int_mul))
187
712
  GWI_BB(gwi_oper_end(gwi, "/",       float_int_div))
188
712
  GWI_BB(gwi_oper_ini(gwi, "float", "int", "int"))
189
712
  GWI_BB(gwi_oper_end(gwi, "&&",          float_int_and))
190
712
  GWI_BB(gwi_oper_end(gwi, "||",           float_int_or))
191
712
  GWI_BB(gwi_oper_end(gwi, "==", 			float_int_eq))
192
712
  GWI_BB(gwi_oper_end(gwi, "!=", 			float_int_neq))
193
712
  GWI_BB(gwi_oper_end(gwi, ">", 			float_int_gt))
194
712
  GWI_BB(gwi_oper_end(gwi, ">=", 			float_int_ge))
195
712
  GWI_BB(gwi_oper_end(gwi, "<", 			float_int_lt))
196
712
  GWI_BB(gwi_oper_end(gwi, "<=", 			float_int_le))
197
712
  CHECK_FI("=>", rassign, r_assign)
198
712
  CHECK_FI("+=>", rassign, r_plus)
199
712
  CHECK_FI("-=>", rassign, r_minus)
200
712
  CHECK_FI("*=>", rassign, r_mul)
201
712
  CHECK_FI("/=>", rassign, r_div)
202
712
  _CHECK_OP("$", cast_f2i, CastF2I)
203
712
  _CHECK_OP("@implicit", implicit_f2i, CastF2I)
204
712
  return GW_OK;
205
}
206
207
712
static GWION_IMPORT(dur) {
208
712
  GWI_BB(gwi_oper_cond(gwi, "dur", BranchEqFloat, BranchNeqFloat))
209
712
  GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "dur"))
210
712
  CHECK_FF("=>", rassign, r_assign)
211
712
  GWI_BB(gwi_oper_end(gwi, "+",         FloatPlus))
212
712
  GWI_BB(gwi_oper_end(gwi, "-",        FloatMinus))
213
712
  GWI_BB(gwi_oper_end(gwi, "*",        FloatTimes))
214
712
  GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "float"))
215
712
  GWI_BB(gwi_oper_end(gwi, "/",       FloatDivide))
216
217
712
  GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "int"))
218
712
  GWI_BB(gwi_oper_end(gwi, ">",           float_gt))
219
712
  GWI_BB(gwi_oper_end(gwi, ">=",           float_ge))
220
712
  GWI_BB(gwi_oper_end(gwi, "<",           float_lt))
221
712
  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
712
static GWION_IMPORT(time) {
240
712
  GWI_BB(gwi_oper_cond(gwi, "time", BranchEqFloat, BranchNeqFloat))
241
712
  GWI_BB(gwi_oper_ini(gwi, "time", "time", "time"))
242
712
  CHECK_FF("=>", rassign, r_assign)
243
712
  GWI_BB(gwi_oper_ini(gwi, "time", "dur", "time"))
244
712
  GWI_BB(gwi_oper_end(gwi, "+",         FloatPlus))
245
712
  GWI_BB(gwi_oper_ini(gwi, "dur", "time", "time"))
246
712
  CHECK_FF("=>", rassign, r_assign)
247
712
  GWI_BB(gwi_oper_end(gwi, "+",         FloatPlus))
248
712
  GWI_BB(gwi_oper_ini(gwi,  "dur",  "@now", "time"))
249
712
  _CHECK_OP("=>", now, Time_Advance)
250
712
  GWI_BB(gwi_oper_ini(gwi, "time", "time", "int"))
251
712
  GWI_BB(gwi_oper_end(gwi, ">",           float_gt))
252
712
  GWI_BB(gwi_oper_end(gwi, ">=", 	      float_ge))
253
712
  GWI_BB(gwi_oper_end(gwi, "<", 		  float_lt))
254
712
  return gwi_oper_end(gwi, "<=",           float_le);
255
}
256
257
712
static GWION_IMPORT(float) {
258
712
  GWI_BB(gwi_oper_cond(gwi, "float", BranchEqFloat, BranchNeqFloat))
259
712
  GWI_BB(gwi_oper_ini(gwi, "float", "float", "float"))
260
712
  GWI_BB(gwi_oper_end(gwi, "+",          FloatPlus))
261
712
  GWI_BB(gwi_oper_end(gwi, "-",         FloatMinus))
262
712
  GWI_BB(gwi_oper_end(gwi, "*",         FloatTimes))
263
712
  GWI_BB(gwi_oper_end(gwi, "/",        FloatDivide))
264
712
  GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
265
712
  CHECK_FF("=>", rassign, r_assign)
266
712
  CHECK_FF("+=>", rassign, r_plus)
267
712
  CHECK_FF("-=>", rassign, r_minus)
268
712
  CHECK_FF("*=>", rassign, r_mul)
269
712
  CHECK_FF("/=>", rassign, r_div)
270
712
  GWI_BB(gwi_oper_ini(gwi, "float", "float", "int"))
271
712
  GWI_BB(gwi_oper_end(gwi, "&&",           float_and))
272
712
  GWI_BB(gwi_oper_end(gwi, "||",            float_or))
273
712
  GWI_BB(gwi_oper_end(gwi, "==", 			 float_eq))
274
712
  GWI_BB(gwi_oper_end(gwi, "!=", 			 float_neq))
275
712
  GWI_BB(gwi_oper_end(gwi, ">", 			 float_gt))
276
712
  GWI_BB(gwi_oper_end(gwi, ">=", 			 float_ge))
277
712
  GWI_BB(gwi_oper_end(gwi, "<", 			 float_lt))
278
712
  GWI_BB(gwi_oper_end(gwi, "<=", 			 float_le))
279
712
  GWI_BB(gwi_oper_ini(gwi, NULL,   "float", "float"))
280
712
  CHECK_FF("-", unary_meta, negate)
281
712
  GWI_BB(gwi_oper_ini(gwi, NULL,   "float", "int"))
282
712
  GWI_BB(gwi_oper_ini(gwi, NULL,   "time", "int"))
283
712
  GWI_BB(gwi_oper_ini(gwi, NULL,   "dur", "int"))
284
712
  GWI_BB(gwi_oper_ini(gwi, "int", "dur", "dur"))
285
712
  GWI_BB(gwi_oper_end(gwi, "::",         int_float_mul))
286
712
  GWI_BB(gwi_oper_ini(gwi, "float", "dur", "dur"))
287
712
  GWI_BB(gwi_oper_end(gwi, "::",         FloatTimes))
288
712
  GWI_BB(gwi_oper_ini(gwi, NULL,   "float", "bool"))
289
712
  GWI_BB(gwi_oper_add(gwi, opck_unary_meta2)) // should return bool
290
712
  GWI_BB(gwi_oper_end(gwi,  "!", float_not))
291
712
  return GW_OK;
292
}
293
294
712
GWION_IMPORT(prim) {
295
712
  GWI_BB(import_int(gwi))
296
712
  GWI_BB(import_float(gwi))
297
712
  GWI_BB(import_intfloat(gwi))
298
712
  GWI_BB(import_floatint(gwi))
299
712
  GWI_BB(import_dur(gwi))
300
712
  return import_time(gwi);
301
}