jsgen: improve handling of `blank_ident`

pull/5297/head
spaceface777 2020-06-09 09:45:50 +02:00 committed by GitHub
parent 2799a6f065
commit 895c7624e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 113 additions and 46 deletions

View File

@ -672,7 +672,11 @@ fn (mut g JsGen) gen_assign_stmt(it ast.AssignStmt) {
// multi return // multi return
g.write('const [') g.write('const [')
for i, ident in it.left { 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 { if i < it.left.len - 1 {
g.write(', ') g.write(', ')
} }
@ -684,6 +688,16 @@ fn (mut g JsGen) gen_assign_stmt(it ast.AssignStmt) {
// `a := 1` | `a,b := 1,2` // `a := 1` | `a,b := 1,2`
for i, ident in it.left { for i, ident in it.left {
val := it.right[i] 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() ident_var_info := ident.var_info()
mut styp := g.typ(ident_var_info.typ) 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) { fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
if it.is_range { if it.is_range {
// `for x in 1..10 {` // `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.inside_loop = true
g.write('for (let $i = ') g.write('for (let $i = ')
g.expr(it.cond) g.expr(it.cond)
@ -908,43 +924,34 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
g.inside_loop = false g.inside_loop = false
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') 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 {` // `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) // styp := g.typ(it.val_type)
g.inside_loop = true g.inside_loop = true
g.write('for (let $i = 0; $i < ') g.write('for (let $i = 0; $i < ')
g.expr(it.cond) g.expr(it.cond)
g.writeln('.length; ++$i) {') g.writeln('.length; ++$i) {')
g.inside_loop = false g.inside_loop = false
g.write('\tlet $it.val_var = ') if val !in ['', '_'] {
g.expr(it.cond) g.write('\tconst $val = ')
g.writeln('[$i];') g.expr(it.cond)
g.writeln('[$i];')
}
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') g.writeln('}')
} else if it.kind == .map { } else if it.kind == .map {
// `for key, val in map[string]int {` // `for key, val in map[string]int {`
// key_styp := g.typ(it.key_type) // key_styp := g.typ(it.key_type)
// val_styp := g.typ(it.val_type) // val_styp := g.typ(it.val_type)
key := if it.key_var == '' { g.new_tmp_var() } else { it.key_var } key := if it.key_var in ['', '_'] { '' } else { it.key_var }
g.write('for (let [$key, $it.val_var] of ') val := if it.val_var in ['', '_'] { '' } else { it.val_var }
g.write('for (let [$key, $val] of ')
g.expr(it.cond) g.expr(it.cond)
g.writeln(') {') g.writeln(') {')
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') 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) { 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) g.expr(it.left)
if g.inside_map_set && it.op == .assign { if g.inside_map_set && it.op == .assign {
g.inside_map_set = false 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) { 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 `is`
// TODO handle optionals // TODO handle optionals
g.write(name) g.write(name)

View File

@ -1,5 +1,5 @@
// V_COMMIT_HASH 2943bdc // V_COMMIT_HASH 808975f
// V_CURRENT_COMMIT_HASH ad5deef // V_CURRENT_COMMIT_HASH 564545d
// Generated by the V compiler // Generated by the V compiler
"use strict"; "use strict";
@ -27,7 +27,7 @@ const builtin = (function () {
/* module exports */ /* module exports */
return { return {
println, println,
print, print
}; };
})(); })();
@ -73,11 +73,14 @@ const main = (function () {
arr2.push(6); arr2.push(6);
arr2.push(...[7, 8, 9]); arr2.push(...[7, 8, 9]);
builtin.println(arr2); builtin.println(arr2);
builtin.println("\n\n");
/** @type {string} */ /** @type {string} */
let slice4 = idx1.slice(0, 4); let slice4 = idx1.slice(0, 4);
builtin.print("Back\t=> ");
builtin.println(slice4); builtin.println(slice4);
/** @type {number} */ /** @type {number} */
const idx2 = slice4.charCodeAt(0); const idx2 = "😀".charCodeAt(0);
builtin.print("66\t=> ");
builtin.println(idx2); builtin.println(idx2);
/** @type {Map<string, string>} */ /** @type {Map<string, string>} */
let m = new Map(); let m = new Map();
@ -86,11 +89,30 @@ const main = (function () {
m.set(key, "value"); m.set(key, "value");
/** @type {string} */ /** @type {string} */
const val = m.get("key"); const val = m.get("key");
builtin.print("value\t=> ");
builtin.println(val); builtin.println(val);
builtin.print("true\t=> ");
builtin.println(arr1.includes("JS")); builtin.println(arr1.includes("JS"));
builtin.print("false\t=> ");
builtin.println(!(arr2.includes(3))); builtin.println(!(arr2.includes(3)));
builtin.print("true\t=> ");
builtin.println(m.has("key")); builtin.println(m.has("key"));
builtin.print("true\t=> ");
builtin.println(!(m.has("badkey"))); 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 */ /* module exports */

View File

@ -32,13 +32,16 @@ println(arr2)
arr2 << 6 arr2 << 6
arr2 << [7, 8, 9] arr2 << [7, 8, 9]
println(arr2) println(arr2)
println('\n\n')
// String slices // String slices
mut slice4 := idx1[..4] mut slice4 := idx1[..4]
print('Back\t=> ')
println(slice4) // 'Back' println(slice4) // 'Back'
// String indexes // String indexes
idx2 := slice4[0] idx2 := slice4[0]
print('66\t=> ')
println(idx2) println(idx2)
// TODO: // TODO:
// slice4[3] = `c` // slice4[3] = `c`
@ -48,10 +51,22 @@ mut m := map[string]string
key := 'key' key := 'key'
m[key] = 'value' m[key] = 'value'
val := m['key'] val := m['key']
print('value\t=> ')
println(val) println(val)
// 'in' / '!in' // 'in' / '!in'
print('true\t=> ')
println('JS' in arr1) println('JS' in arr1)
print('false\t=> ')
println(3 !in arr2) println(3 !in arr2)
print('true\t=> ')
println('key' in m) println('key' in m)
print('true\t=> ')
println('badkey' !in m) 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) }

View File

@ -1,5 +1,5 @@
// V_COMMIT_HASH 11e6734 // V_COMMIT_HASH 808975f
// V_CURRENT_COMMIT_HASH 99c70cf // V_CURRENT_COMMIT_HASH 564545d
// Generated by the V compiler // Generated by the V compiler
"use strict"; "use strict";
@ -27,7 +27,7 @@ const builtin = (function () {
/* module exports */ /* module exports */
return { return {
println, println,
print, print
}; };
})(); })();
@ -106,7 +106,7 @@ const hello = (function () {
Aaa, Aaa,
Ccc, Ccc,
v_debugger, v_debugger,
excited, excited
}; };
})(); })();
@ -182,6 +182,7 @@ const main = (function (hl) {
function v_class(v_extends, v_instanceof) { function v_class(v_extends, v_instanceof) {
/** @type {number} */ /** @type {number} */
const v_delete = v_instanceof; const v_delete = v_instanceof;
const _tmp1 = v_delete;
} }
/* program entry point */ /* program entry point */
@ -203,17 +204,13 @@ const main = (function (hl) {
}); });
c.a.update("another update"); c.a.update("another update");
builtin.println(c); builtin.println(c);
/** @type {string} */ const _tmp2 = "done";
const v = "done";
{ {
/** @type {string} */ const _tmp3 = "block";
const _ = "block";
} }
/** @type {number} */ const _tmp4 = POSITION.go_back;
const pos = POSITION.go_back; const _tmp5 = hl.Ccc.a;
/** @type {number} */
const enum2 = hl.Ccc.a;
/** @type {string} */ /** @type {string} */
const v_debugger = "JS keywords"; const v_debugger = "JS keywords";
/** @type {string} */ /** @type {string} */
@ -237,8 +234,8 @@ const main = (function (hl) {
/** @type {number[]} */ /** @type {number[]} */
const arr = [1, 2, 3, 4, 5]; const arr = [1, 2, 3, 4, 5];
for (let _tmp1 = 0; _tmp1 < arr.length; ++_tmp1) { for (let _tmp6 = 0; _tmp6 < arr.length; ++_tmp6) {
let i = arr[_tmp1]; let i = arr[_tmp6];
} }
/** @type {Map<string, string>} */ /** @type {Map<string, string>} */
@ -296,8 +293,8 @@ const main = (function (hl) {
* @returns {[number, number]} * @returns {[number, number]}
*/ */
function hello(game_on, ...dummy) { function hello(game_on, ...dummy) {
for (let _tmp2 = 0; _tmp2 < dummy.length; ++_tmp2) { for (let _tmp7 = 0; _tmp7 < dummy.length; ++_tmp7) {
let dd = dummy[_tmp2]; let dd = dummy[_tmp7];
/** @type {string} */ /** @type {string} */
const l = dd; const l = dd;
} }

View File

@ -26,6 +26,7 @@ enum POSITION {
fn class(extends string, instanceof int) { fn class(extends string, instanceof int) {
delete := instanceof delete := instanceof
_ = delete
} }
@ -46,13 +47,13 @@ fn main() {
c.a.update('another update') c.a.update('another update')
println(c) println(c)
v := "done" _ := "done"
{ {
_ = "block" _ = "block"
} }
pos := POSITION.go_back _ = POSITION.go_back
enum2 := hl.Ccc.a _ = hl.Ccc.a
debugger := 'JS keywords' debugger := 'JS keywords'
// TODO: Implement interpolation // TODO: Implement interpolation

View File

@ -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()
}