diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 631fd7737f..023b864cc5 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -672,7 +672,11 @@ fn (mut g JsGen) gen_assign_stmt(it ast.AssignStmt) { // multi return g.write('const [') for i, ident in it.left { - g.write(g.js_name(ident.name)) + if ident.name in ['', '_'] { + g.write('') + } else { + g.write(g.js_name(ident.name)) + } if i < it.left.len - 1 { g.write(', ') } @@ -684,6 +688,16 @@ fn (mut g JsGen) gen_assign_stmt(it ast.AssignStmt) { // `a := 1` | `a,b := 1,2` for i, ident in it.left { val := it.right[i] + + if ident.kind == .blank_ident || ident.name in ['', '_'] { + tmp_var := g.new_tmp_var() + // TODO: Can the tmp_var declaration be omitted? + g.write('const $tmp_var = ') + g.expr(val) + g.writeln(';') + continue + } + ident_var_info := ident.var_info() mut styp := g.typ(ident_var_info.typ) @@ -898,7 +912,9 @@ fn (mut g JsGen) gen_for_c_stmt(it ast.ForCStmt) { fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) { if it.is_range { // `for x in 1..10 {` - i := it.val_var + mut i := it.val_var + if i in ['', '_'] { i = g.new_tmp_var() } + g.inside_loop = true g.write('for (let $i = ') g.expr(it.cond) @@ -908,43 +924,34 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) { g.inside_loop = false g.stmts(it.stmts) g.writeln('}') - } else if it.kind == .array || it.cond_type.has_flag(.variadic) { + } else if it.kind in [.array, .string] || it.cond_type.has_flag(.variadic) { // `for num in nums {` - i := if it.key_var == '' { g.new_tmp_var() } else { it.key_var } + i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var } + val := if it.val_var in ['', '_'] { '' } else { it.val_var } // styp := g.typ(it.val_type) g.inside_loop = true g.write('for (let $i = 0; $i < ') g.expr(it.cond) g.writeln('.length; ++$i) {') g.inside_loop = false - g.write('\tlet $it.val_var = ') - g.expr(it.cond) - g.writeln('[$i];') + if val !in ['', '_'] { + g.write('\tconst $val = ') + g.expr(it.cond) + g.writeln('[$i];') + } g.stmts(it.stmts) g.writeln('}') } else if it.kind == .map { // `for key, val in map[string]int {` // key_styp := g.typ(it.key_type) // val_styp := g.typ(it.val_type) - key := if it.key_var == '' { g.new_tmp_var() } else { it.key_var } - g.write('for (let [$key, $it.val_var] of ') + key := if it.key_var in ['', '_'] { '' } else { it.key_var } + val := if it.val_var in ['', '_'] { '' } else { it.val_var } + g.write('for (let [$key, $val] of ') g.expr(it.cond) g.writeln(') {') g.stmts(it.stmts) g.writeln('}') - } else if it.kind == .string { - // `for x in 'hello' {` - i := if it.key_var == '' { g.new_tmp_var() } else { it.key_var } - g.inside_loop = true - g.write('for (let $i = 0; $i < ') - g.expr(it.cond) - g.writeln('.length; ++$i) {') - g.inside_loop = false - g.write('\tlet $it.val_var = ') - g.expr(it.cond) - g.writeln('[$i];') - g.stmts(it.stmts) - g.writeln('}') } } @@ -1081,6 +1088,14 @@ fn (mut g JsGen) gen_array_init_expr(it ast.ArrayInit) { } fn (mut g JsGen) gen_assign_expr(it ast.AssignExpr) { + if it.left_type == table.void_type && it.op == .assign { + // _ = 1 + tmp_var := g.new_tmp_var() + g.write('const $tmp_var = ') + g.expr(it.val) + } + + // NB: The expr has to go *before* inside_map_set as it's defined there g.expr(it.left) if g.inside_map_set && it.op == .assign { g.inside_map_set = false @@ -1120,7 +1135,10 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { } fn (mut g JsGen) gen_ident(node ast.Ident) { - name := g.js_name(node.name) + mut name := g.js_name(node.name) + if node.kind == .blank_ident || name in ['', '_']{ + name = g.new_tmp_var() + } // TODO `is` // TODO handle optionals g.write(name) diff --git a/vlib/v/gen/js/tests/array.js b/vlib/v/gen/js/tests/array.js index 7b37a7f376..1e73715e7c 100644 --- a/vlib/v/gen/js/tests/array.js +++ b/vlib/v/gen/js/tests/array.js @@ -1,5 +1,5 @@ -// V_COMMIT_HASH 2943bdc -// V_CURRENT_COMMIT_HASH ad5deef +// V_COMMIT_HASH 808975f +// V_CURRENT_COMMIT_HASH 564545d // Generated by the V compiler "use strict"; @@ -27,7 +27,7 @@ const builtin = (function () { /* module exports */ return { println, - print, + print }; })(); @@ -73,11 +73,14 @@ const main = (function () { arr2.push(6); arr2.push(...[7, 8, 9]); builtin.println(arr2); + builtin.println("\n\n"); /** @type {string} */ let slice4 = idx1.slice(0, 4); + builtin.print("Back\t=> "); builtin.println(slice4); /** @type {number} */ - const idx2 = slice4.charCodeAt(0); + const idx2 = "😀".charCodeAt(0); + builtin.print("66\t=> "); builtin.println(idx2); /** @type {Map} */ let m = new Map(); @@ -86,11 +89,30 @@ const main = (function () { m.set(key, "value"); /** @type {string} */ const val = m.get("key"); + builtin.print("value\t=> "); builtin.println(val); + builtin.print("true\t=> "); builtin.println(arr1.includes("JS")); + builtin.print("false\t=> "); builtin.println(!(arr2.includes(3))); + builtin.print("true\t=> "); builtin.println(m.has("key")); + builtin.print("true\t=> "); builtin.println(!(m.has("badkey"))); + for (let _tmp1 = 0; _tmp1 < arr1.length; ++_tmp1) { + } + + builtin.println("0 to 8\t=>"); + for (let i = 0; i < arr2.length; ++i) { + builtin.println(i); + } + + builtin.println("\n\n4 to 5\t=> "); + for (let _tmp2 = 0; _tmp2 < slice3.length; ++_tmp2) { + const v = slice3[_tmp2]; + builtin.println(v); + } + })(); /* module exports */ diff --git a/vlib/v/gen/js/tests/array.v b/vlib/v/gen/js/tests/array.v index 797e1fb5e0..33447e3c88 100644 --- a/vlib/v/gen/js/tests/array.v +++ b/vlib/v/gen/js/tests/array.v @@ -32,13 +32,16 @@ println(arr2) arr2 << 6 arr2 << [7, 8, 9] println(arr2) +println('\n\n') // String slices mut slice4 := idx1[..4] +print('Back\t=> ') println(slice4) // 'Back' // String indexes idx2 := slice4[0] +print('66\t=> ') println(idx2) // TODO: // slice4[3] = `c` @@ -48,10 +51,22 @@ mut m := map[string]string key := 'key' m[key] = 'value' val := m['key'] +print('value\t=> ') println(val) // 'in' / '!in' +print('true\t=> ') println('JS' in arr1) +print('false\t=> ') println(3 !in arr2) +print('true\t=> ') println('key' in m) +print('true\t=> ') println('badkey' !in m) + +// for in +for _ in arr1 {} +println('0 to 8\t=>') +for i, _ in arr2 { println(i) } +println('\n\n4 to 5\t=> ') +for _, v in slice3 { println(v) } diff --git a/vlib/v/gen/js/tests/js.js b/vlib/v/gen/js/tests/js.js index 9dd4129647..ef2c001925 100644 --- a/vlib/v/gen/js/tests/js.js +++ b/vlib/v/gen/js/tests/js.js @@ -1,5 +1,5 @@ -// V_COMMIT_HASH 11e6734 -// V_CURRENT_COMMIT_HASH 99c70cf +// V_COMMIT_HASH 808975f +// V_CURRENT_COMMIT_HASH 564545d // Generated by the V compiler "use strict"; @@ -27,7 +27,7 @@ const builtin = (function () { /* module exports */ return { println, - print, + print }; })(); @@ -106,7 +106,7 @@ const hello = (function () { Aaa, Ccc, v_debugger, - excited, + excited }; })(); @@ -182,6 +182,7 @@ const main = (function (hl) { function v_class(v_extends, v_instanceof) { /** @type {number} */ const v_delete = v_instanceof; + const _tmp1 = v_delete; } /* program entry point */ @@ -203,17 +204,13 @@ const main = (function (hl) { }); c.a.update("another update"); builtin.println(c); - /** @type {string} */ - const v = "done"; + const _tmp2 = "done"; { - /** @type {string} */ - const _ = "block"; + const _tmp3 = "block"; } - /** @type {number} */ - const pos = POSITION.go_back; - /** @type {number} */ - const enum2 = hl.Ccc.a; + const _tmp4 = POSITION.go_back; + const _tmp5 = hl.Ccc.a; /** @type {string} */ const v_debugger = "JS keywords"; /** @type {string} */ @@ -237,8 +234,8 @@ const main = (function (hl) { /** @type {number[]} */ const arr = [1, 2, 3, 4, 5]; - for (let _tmp1 = 0; _tmp1 < arr.length; ++_tmp1) { - let i = arr[_tmp1]; + for (let _tmp6 = 0; _tmp6 < arr.length; ++_tmp6) { + let i = arr[_tmp6]; } /** @type {Map} */ @@ -296,8 +293,8 @@ const main = (function (hl) { * @returns {[number, number]} */ function hello(game_on, ...dummy) { - for (let _tmp2 = 0; _tmp2 < dummy.length; ++_tmp2) { - let dd = dummy[_tmp2]; + for (let _tmp7 = 0; _tmp7 < dummy.length; ++_tmp7) { + let dd = dummy[_tmp7]; /** @type {string} */ const l = dd; } diff --git a/vlib/v/gen/js/tests/js.v b/vlib/v/gen/js/tests/js.v index c9a5f14281..07b7ac3eff 100644 --- a/vlib/v/gen/js/tests/js.v +++ b/vlib/v/gen/js/tests/js.v @@ -26,6 +26,7 @@ enum POSITION { fn class(extends string, instanceof int) { delete := instanceof + _ = delete } @@ -46,13 +47,13 @@ fn main() { c.a.update('another update') println(c) - v := "done" + _ := "done" { _ = "block" } - pos := POSITION.go_back - enum2 := hl.Ccc.a + _ = POSITION.go_back + _ = hl.Ccc.a debugger := 'JS keywords' // TODO: Implement interpolation diff --git a/vlib/v/tests/blank_ident_test.v b/vlib/v/tests/blank_ident_test.v index 104b7a9e93..5c6094bc6c 100644 --- a/vlib/v/tests/blank_ident_test.v +++ b/vlib/v/tests/blank_ident_test.v @@ -258,3 +258,17 @@ fn test_nested_for_in_string_both() { } } } + +fn multi_return() (int, int, string) { + return 1, 2, '3' +} + +fn test_blank_multi_return() { + _, a, b := multi_return() + c, _, d := multi_return() + e, f, _ := multi_return() + _, _, g := multi_return() + _, h, _ := multi_return() + i, _, _ := multi_return() + _, _, _ := multi_return() +}