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