v2 / vlib / v / gen / js / infix.v
474 lines · 458 sloc · 11.51 KB · 3c0c27933ec8efde92625344dbfb286f4e7407bc
Raw
1module js
2
3import v.util
4import v.ast
5
6fn (mut g JsGen) gen_plain_infix_expr(node ast.InfixExpr) {
7 it := node
8 l_sym := g.table.final_sym(it.left_type)
9 r_sym := g.table.final_sym(it.right_type)
10 greater_typ := g.greater_typ(it.left_type, it.right_type)
11 cast_ty := if greater_typ == it.left_type { l_sym.cname } else { r_sym.cname }
12 g.write('new ${g.js_name(cast_ty)}( ')
13 g.cast_stack << greater_typ
14 if node.op == .power {
15 if !g.pref.output_es5 && ((l_sym.kind == .i64 || l_sym.kind == .u64)
16 || (r_sym.kind == .i64 || r_sym.kind == .u64)) {
17 g.write('BigInt(')
18 g.expr(node.left)
19 g.gen_deref_ptr(node.left_type)
20 g.write('.valueOf()) ** BigInt(')
21 g.expr(node.right)
22 g.gen_deref_ptr(node.right_type)
23 g.write('.valueOf())')
24 } else {
25 g.write('Math.pow(')
26 g.expr(node.left)
27 g.gen_deref_ptr(node.left_type)
28 g.write('.valueOf(), ')
29 g.expr(node.right)
30 g.gen_deref_ptr(node.right_type)
31 g.write('.valueOf())')
32 }
33 g.cast_stack.delete_last()
34 g.write(')')
35 return
36 }
37 if !g.pref.output_es5 && ((l_sym.kind == .i64 || l_sym.kind == .u64)
38 || (r_sym.kind == .i64 || r_sym.kind == .u64)) {
39 g.write('BigInt(')
40 g.expr(node.left)
41 g.gen_deref_ptr(node.left_type)
42 g.write('.valueOf())')
43 g.write(' ${node.op.str()} ')
44 g.write('BigInt(')
45 g.expr(node.right)
46 g.gen_deref_ptr(node.left_type)
47 g.write('.valueOf())')
48 } else {
49 g.expr(node.left)
50 g.gen_deref_ptr(node.left_type)
51 g.write('.valueOf()')
52 g.write(' ${node.op.str()} ')
53 g.expr(node.right)
54 g.gen_deref_ptr(node.left_type)
55 g.write('.valueOf()')
56 }
57
58 g.cast_stack.delete_last()
59 g.write(')')
60}
61
62fn (mut g JsGen) infix_expr_arithmetic_op(node ast.InfixExpr) {
63 left := g.unwrap(node.left_type)
64 right := g.unwrap(node.right_type)
65 method := g.table.find_method(left.sym, node.op.str()) or {
66 g.gen_plain_infix_expr(node)
67 return
68 }
69 left_styp := g.styp(left.typ.set_nr_muls(0))
70 g.write(left_styp)
71 g.write('_')
72 g.write(util.replace_op(node.op.str()))
73 g.write('(')
74 g.op_arg(node.left, method.params[0].typ, left.typ)
75 g.write(', ')
76 g.op_arg(node.right, method.params[1].typ, right.typ)
77 g.write(')')
78}
79
80fn (mut g JsGen) op_arg(expr ast.Expr, expected ast.Type, got ast.Type) {
81 mut needs_closing := 0
82 mut nr_muls := got.nr_muls()
83 if expected.is_ptr() {
84 if nr_muls > 0 {
85 nr_muls--
86 } else {
87 g.write('new \$ref(')
88 needs_closing++
89 }
90 }
91 g.expr(expr)
92 g.write('.val'.repeat(nr_muls))
93 for i := 0; i < needs_closing; i++ {
94 g.write(')')
95 }
96}
97
98fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
99 left := g.unwrap(node.left_type)
100 right := g.unwrap(node.right_type)
101 has_operator_overloading := g.table.has_method(left.sym, '==')
102 g.write('new bool(')
103 if (left.typ.is_ptr() && right.typ.is_int()) || (right.typ.is_ptr() && left.typ.is_int()) {
104 g.gen_plain_infix_expr(node)
105 } else if has_operator_overloading {
106 if node.op == .ne {
107 g.write('!')
108 }
109 g.write(g.styp(left.unaliased.set_nr_muls(0)))
110 g.write('__eq(')
111 g.expr(node.left)
112 g.gen_deref_ptr(node.left_type)
113 g.write(',')
114 g.expr(node.right)
115 g.gen_deref_ptr(node.right_type)
116 g.write(')')
117 if node.op == .ne {
118 g.write('.valueOf()')
119 }
120 } else if left.typ.idx() == right.typ.idx()
121 && left.sym.kind in [.array, .array_fixed, .alias, .map, .struct, .sum_type] {
122 match left.sym.kind {
123 .alias {
124 ptr_typ := g.gen_alias_equality_fn(left.typ)
125 if node.op == .ne {
126 g.write('!')
127 }
128 g.write('${ptr_typ}_alias_eq(')
129 g.expr(node.left)
130 g.gen_deref_ptr(node.left_type)
131 g.write(', ')
132 g.expr(node.right)
133 g.gen_deref_ptr(node.right_type)
134 g.write(')')
135 if node.op == .ne {
136 g.write('.valueOf()')
137 }
138 }
139 .array {
140 ptr_typ := g.gen_array_equality_fn(left.unaliased.clear_flag(.shared_f))
141 if node.op == .ne {
142 g.write('!')
143 }
144 g.write('${ptr_typ}_arr_eq(')
145 g.expr(node.left)
146 g.gen_deref_ptr(node.left_type)
147 g.write(', ')
148 g.expr(node.right)
149 g.gen_deref_ptr(node.right_type)
150 g.write(')')
151 if node.op == .ne {
152 g.write('.valueOf()')
153 }
154 }
155 .array_fixed {
156 ptr_typ := g.gen_fixed_array_equality_fn(left.unaliased)
157 if node.op == .ne {
158 g.write('!')
159 }
160 g.write('${ptr_typ}_arr_eq(')
161 g.expr(node.left)
162 g.gen_deref_ptr(node.left_type)
163 g.write(', ')
164 g.expr(node.right)
165 g.gen_deref_ptr(node.right_type)
166 g.write(')')
167 if node.op == .ne {
168 g.write('.valueOf()')
169 }
170 }
171 .map {
172 ptr_typ := g.gen_map_equality_fn(left.unaliased)
173 if node.op == .ne {
174 g.write('!')
175 }
176 g.write('${ptr_typ}_map_eq(')
177 g.expr(node.left)
178 g.gen_deref_ptr(node.left_type)
179 g.write(', ')
180 g.expr(node.right)
181 g.gen_deref_ptr(node.right_type)
182 g.write(')')
183 if node.op == .ne {
184 g.write('.valueOf()')
185 }
186 }
187 .struct {
188 ptr_typ := g.gen_struct_equality_fn(left.unaliased)
189 if node.op == .ne {
190 g.write('!')
191 }
192 g.write('${ptr_typ}_struct_eq(')
193 g.expr(node.left)
194 g.gen_deref_ptr(node.left_type)
195 g.write(', ')
196 g.expr(node.right)
197 g.gen_deref_ptr(node.right_type)
198 g.write(')')
199 if node.op == .ne {
200 g.write('.valueOf()')
201 }
202 }
203 .sum_type {
204 ptr_typ := g.gen_sumtype_equality_fn(left.unaliased)
205 if node.op == .ne {
206 g.write('!')
207 }
208 g.write('${ptr_typ}_sumtype_eq(')
209
210 g.expr(node.left)
211 g.gen_deref_ptr(node.left_type)
212 g.write(', ')
213 g.expr(node.right)
214 g.gen_deref_ptr(node.right_type)
215 g.write(')')
216 if node.op == .ne {
217 g.write('.valueOf()')
218 }
219 }
220 else {}
221 }
222 } else if !g.pref.output_es5
223 && (left.sym.kind in [.i64, .u64] || right.sym.kind in [.i64, .u64]) {
224 if left.sym.kind in [.i64, .u64] && node.right is ast.IntegerLiteral {
225 g.expr(node.left)
226 g.gen_deref_ptr(node.left_type)
227 g.write('.valueOf() ${node.op.str()} ')
228 g.cast_stack << left.typ
229 g.expr(node.right)
230 g.cast_stack.delete_last()
231 g.gen_deref_ptr(node.right_type)
232 g.write('.valueOf()')
233 } else if right.sym.kind in [.i64, .u64] && node.left is ast.IntegerLiteral {
234 g.cast_stack << right.typ
235 g.expr(node.left)
236 g.cast_stack.delete_last()
237 g.gen_deref_ptr(node.left_type)
238 g.write('.valueOf() ${node.op.str()} ')
239 g.expr(node.right)
240 g.gen_deref_ptr(node.right_type)
241 g.write('.valueOf()')
242 } else {
243 g.expr(node.left)
244 g.gen_deref_ptr(node.left_type)
245 g.write('.valueOf() ${node.op.str()} ')
246 g.expr(node.right)
247 g.gen_deref_ptr(node.right_type)
248 g.write('.valueOf()')
249 }
250 } else {
251 g.expr(node.left)
252 g.gen_deref_ptr(node.left_type)
253 g.write('.valueOf() ${node.op.str()} ')
254 g.expr(node.right)
255 g.gen_deref_ptr(node.right_type)
256 g.write('.valueOf()')
257 }
258 g.write(')')
259}
260
261fn (mut g JsGen) infix_expr_cmp_op(node ast.InfixExpr) {
262 left := g.unwrap(node.left_type)
263 right := g.unwrap(node.right_type)
264 has_operator_overloading := g.table.has_method(left.sym, '<')
265 g.write('new bool(')
266 if left.sym.kind == right.sym.kind && has_operator_overloading {
267 if node.op in [.le, .ge] {
268 g.write('!')
269 }
270 g.write(g.styp(left.typ.set_nr_muls(0)))
271 g.write('__lt')
272 if node.op in [.lt, .ge] {
273 g.write('(')
274
275 g.expr(node.left)
276 g.gen_deref_ptr(left.typ)
277 g.write(', ')
278 g.expr(node.right)
279 g.gen_deref_ptr(right.typ)
280 g.write(')')
281 } else {
282 g.write('(')
283 g.expr(node.right)
284 g.gen_deref_ptr(left.typ)
285 g.write(', ')
286 g.expr(node.left)
287 g.gen_deref_ptr(right.typ)
288 g.write(')')
289 }
290 } else if !g.pref.output_es5
291 && (left.sym.kind in [.i64, .u64] || right.sym.kind in [.i64, .u64]) {
292 if left.sym.kind in [.i64, .u64] && node.right is ast.IntegerLiteral {
293 g.expr(node.left)
294 g.gen_deref_ptr(node.left_type)
295 g.write('.valueOf() ${node.op.str()} ')
296 g.cast_stack << left.typ
297 g.expr(node.right)
298 g.cast_stack.delete_last()
299 g.gen_deref_ptr(node.right_type)
300 g.write('.valueOf()')
301 } else if right.sym.kind in [.i64, .u64] && node.left is ast.IntegerLiteral {
302 g.cast_stack << right.typ
303 g.expr(node.left)
304 g.cast_stack.delete_last()
305 g.gen_deref_ptr(node.left_type)
306 g.write('.valueOf() ${node.op.str()} ')
307 g.expr(node.right)
308 g.gen_deref_ptr(node.right_type)
309 g.write('.valueOf()')
310 } else {
311 g.expr(node.left)
312 g.gen_deref_ptr(node.left_type)
313 g.write('.valueOf() ${node.op.str()} ')
314 g.expr(node.right)
315 g.gen_deref_ptr(node.right_type)
316 g.write('.valueOf()')
317 }
318 } else {
319 g.expr(node.left)
320 g.gen_deref_ptr(node.left_type)
321 g.write('.valueOf() ${node.op.str()} ')
322 g.expr(node.right)
323 g.gen_deref_ptr(node.right_type)
324 g.write('.valueOf()')
325 }
326
327 g.write(')')
328}
329
330fn (mut g JsGen) infix_expr_left_shift_op(node ast.InfixExpr) {
331 left := g.unwrap(node.left_type)
332 right := g.unwrap(node.right_type)
333 if left.unaliased_sym.kind == .array {
334 // arr << val
335 array_info := left.unaliased_sym.info as ast.Array
336 g.write('array_push(')
337 old_inside_left_shift := g.inside_left_shift
338 g.inside_left_shift = true
339 defer {
340 g.inside_left_shift = old_inside_left_shift
341 }
342 //&& array_info.elem_type != g.unwrap_generic(node.right_type)
343 if right.unaliased_sym.kind == .array && array_info.elem_type != right.typ {
344 g.expr(node.left)
345 g.gen_deref_ptr(left.typ)
346 g.write(',')
347 g.expr(node.right)
348 g.gen_deref_ptr(right.typ)
349 g.write('.arr.arr')
350 g.write(',true)')
351 } else {
352 g.expr(node.left)
353 g.gen_deref_ptr(left.typ)
354 g.write(',')
355 g.expr(node.right)
356 g.write(',false)')
357 }
358 } else {
359 g.gen_plain_infix_expr(node)
360 }
361}
362
363fn (mut g JsGen) infix_in_not_in_op(node ast.InfixExpr) {
364 l_sym := g.unwrap(node.left_type)
365 r_sym := g.unwrap(node.right_type)
366 if node.op == .not_in {
367 g.write('!')
368 }
369 if r_sym.unaliased_sym.kind in [.array, .array_fixed] {
370 fn_name := g.gen_array_contains_method(node.right_type)
371 g.write('(${fn_name}(')
372 g.expr(node.right)
373 g.gen_deref_ptr(node.right_type)
374 g.write(',')
375 g.expr(node.left)
376 g.write(')')
377 if node.op == .not_in {
378 g.write('.valueOf()')
379 }
380 g.write(')')
381 return
382 } else if r_sym.unaliased_sym.kind == .map {
383 g.expr(node.right)
384 g.gen_deref_ptr(node.right_type)
385 g.write('.has(')
386 g.expr(node.left)
387 /*
388 if l_sym.sym.kind == .string {
389 g.write('.str')
390 } else {
391 g.write('.valueOf()')
392 }*/
393 g.write('.\$toJS()')
394 g.write(')')
395 } else {
396 g.write('.str.includes(')
397 g.expr(node.right)
398 g.gen_deref_ptr(node.right_type)
399 g.expr(node.left)
400 if l_sym.sym.kind == .string {
401 g.write('.str')
402 } else {
403 g.write('.valueOf()')
404 }
405 g.write(')')
406 }
407
408 /*
409 if r_sym.kind == .map {
410 g.write('.map.has(')
411 } else if r_sym.kind == .string {
412 g.write('.str.includes(')
413 } else {
414 g.write('.\$includes(')
415 }
416 g.expr(node.left)
417 if l_sym.kind == .string {
418 g.write('.str')
419 }
420 g.write(')')*/
421}
422
423fn (mut g JsGen) infix_is_not_is_op(node ast.InfixExpr) {
424 rsym := g.unwrap(node.right_type).unaliased_sym
425
426 if rsym.info is ast.SumType {
427 g.write('[')
428 variants := g.unwrap_sum_type(node.right_type)
429 for i, v in variants {
430 g.write(g.js_name(v.unaliased_sym.name))
431 if i < variants.len - 1 {
432 g.write(', ')
433 }
434 }
435 g.write('].some(t => ')
436 g.expr(node.left)
437 g.gen_deref_ptr(node.left_type)
438 g.write(' instanceof t.valueOf())')
439 } else {
440 g.expr(node.left)
441 g.gen_deref_ptr(node.left_type)
442 g.write(' instanceof ')
443 g.write(g.js_name(rsym.name))
444 }
445}
446
447fn (mut g JsGen) infix_expr(node ast.InfixExpr) {
448 match node.op {
449 .plus, .minus, .mul, .power, .div, .mod {
450 g.infix_expr_arithmetic_op(node)
451 }
452 .eq, .ne {
453 g.infix_expr_eq_op(node)
454 }
455 .gt, .ge, .lt, .le {
456 g.infix_expr_cmp_op(node)
457 }
458 .logical_or, .and {
459 g.gen_plain_infix_expr(node)
460 }
461 .left_shift {
462 g.infix_expr_left_shift_op(node)
463 }
464 .not_in, .key_in {
465 g.infix_in_not_in_op(node)
466 }
467 .key_is, .not_is {
468 g.infix_is_not_is_op(node)
469 }
470 else {
471 g.gen_plain_infix_expr(node)
472 }
473 }
474}
475