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