GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/lib/prim.c Lines: 233 234 99.6 %
Date: 2020-09-14 09:03:05 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
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
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
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
}