Skip to content

Commit

Permalink
jsgen: cleanup dead code, add TODOs, reduce nesting, use smartcasting (
Browse files Browse the repository at this point in the history
  • Loading branch information
juan-db authored Jun 1, 2024
1 parent d750528 commit bb3505f
Showing 1 changed file with 107 additions and 181 deletions.
288 changes: 107 additions & 181 deletions vlib/v/gen/js/js.v
Original file line number Diff line number Diff line change
Expand Up @@ -1258,7 +1258,11 @@ fn (mut g JsGen) gen_assert_stmt(mut node ast.AssertStmt) {

fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
if stmt.left.len > stmt.right.len {
// multi return
// multi return, e.g.
// fn foo() (int, int, int) { return 0, 1, 2 }
// a, _, c := foo()

// TODO: const
g.write('let [')
for i, left in stmt.left {
if !left.is_blank_ident() {
Expand All @@ -1274,16 +1278,9 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
g.writeln(';')
}
} else {
// `a := 1` | `a,b := 1,2`
for i, left in stmt.left {
mut op := stmt.op
if stmt.op == .decl_assign {
op = .assign
}
is_assign := stmt.op in [.plus_assign, .minus_assign, .mult_assign, .div_assign,
.xor_assign, .mod_assign, .or_assign, .and_assign, .right_shift_assign,
.left_shift_assign]
// e.g. `a := 1`, `a,b := 1,2`, `o['foo'] = 'bar'`

for i, left in stmt.left {
val := stmt.right[i]
mut is_mut := false
if left is ast.Ident {
Expand All @@ -1304,107 +1301,66 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
g.doc.gen_typ(styp)
}
if stmt.op == .decl_assign {
if g.inside_loop || is_mut {
g.write('let ')
g.write(if g.inside_loop || is_mut {
'let '
} else {
g.write('const ')
}
'const '
})
}

mut array_set := false
mut map_set := false
match left {
ast.IndexExpr {
g.expr(left.left)
if left.left_type.is_ptr() {
g.write('.valueOf()')
}
array_set = true

if g.table.sym(left.left_type).kind == .map {
g.writeln('.length++;')
g.expr(left.left)
g.write('.map[')
map_set = true
} else {
g.write('.arr.set(')
}
if map_set {
g.expr(left.index)
g.write('.\$toJS()] = ')
} else {
g.write('new int(')
g.cast_stack << ast.int_type_idx
g.expr(left.index)
g.write('.valueOf()')
g.cast_stack.delete_last()
g.write('),')
}
if left is ast.IndexExpr {
g.expr(left.left)
if left.left_type.is_ptr() {
g.write('.valueOf()')
}
else {
g.expr(left)
array_set = true

if left.is_map {
map_set = true
// FIXME: if you update a key already in the map, it will still
// increment length, which it shouldn't since length should match
// the actual amount of elements in the map
// using a getter that calls JS Object.entries().length or
// Object.values().length to get the real length would probably
// work, but I'm hesitant about the amount of overhead this will
// introduce since those functions return arrays and not iterables,
// which might consume a lot of memory and cycles to set up
g.writeln('.length++;')
g.expr(left.left)
g.write('.map[')
g.expr(left.index)
g.write('.\$toJS()] = ')
} else {
g.write('.arr.set(')
g.write('new int(')
g.cast_stack << ast.int_type_idx
g.expr(left.index)
g.write('.valueOf()')
g.cast_stack.delete_last()
g.write('),')
}
} else {
g.expr(left)
}
mut is_ptr := false
if stmt.op == .assign && stmt.left_types[i].is_ptr() && !array_set {
is_ptr = true

is_ptr := stmt.op == .assign && stmt.left_types[i].is_ptr() && !array_set
if is_ptr {
g.write('.val')
}
mut floor := false
if false && g.inside_map_set && op == .assign {
g.inside_map_set = false
g.write('] = ')
g.expr(val)
if is_ptr {
g.write('.val')
}
} else {
if is_assign && array_set {
g.write('new ${styp}(')

g.expr(left)
l_sym := g.table.sym(stmt.left_types[i])
if l_sym.kind == .string {
g.write('.str')
} else {
g.write('.val')
mut floor := false
mut is_special_assign := false
match stmt.op {
.plus_assign, .minus_assign, .mult_assign, .div_assign, .xor_assign, .mod_assign,
.or_assign, .and_assign, .right_shift_assign, .left_shift_assign {
is_special_assign = true
if array_set {
g.write('new ${styp}(')
g.expr(left)
}

match op {
.plus_assign {
g.write(' + ')
}
.minus_assign {
g.write(' - ')
}
.mult_assign {
g.write(' * ')
}
.div_assign {
g.write(' / ')
}
.mod_assign {
g.write(' % ')
}
.xor_assign {
g.write(' ^ ')
}
.and_assign {
g.write(' & ')
}
.right_shift_assign {
g.write(' >> ')
}
.left_shift_assign {
g.write(' << ')
}
.or_assign {
g.write(' | ')
}
else {
panic('unexpected op ${op}')
}
}
} else if is_assign && !array_set {
l_sym := g.table.sym(stmt.left_types[i])
if l_sym.kind == .string {
g.write('.str')
Expand All @@ -1414,83 +1370,61 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {

if !array_set {
g.write(' = ')
}
if (l_sym.name != 'f64' || l_sym.name != 'f32')
&& (l_sym.name != 'i64' && l_sym.name != 'u64') && l_sym.name != 'string' {
g.write('Math.floor(')
floor = true
}
g.expr(left)

match op {
.plus_assign {
g.write(' + ')
}
.minus_assign {
g.write(' - ')
}
.mult_assign {
g.write(' * ')
}
.div_assign {
g.write(' / ')
}
.mod_assign {
g.write(' % ')
}
.xor_assign {
g.write(' ^ ')
}
.and_assign {
g.write(' & ')
}
.right_shift_assign {
g.write(' >> ')
}
.left_shift_assign {
g.write(' << ')
}
.or_assign {
g.write(' | ')
}
else {
panic('unexpected op ${op}')
if (l_sym.name != 'f64' || l_sym.name != 'f32')
&& (l_sym.name != 'i64' && l_sym.name != 'u64')
&& l_sym.name != 'string' {
g.write('Math.floor(')
floor = true
}
g.expr(left)
}
} else {
if op == .assign && array_set {
} else {
g.write(' ${op} ')

g.write(match stmt.op {
.plus_assign { ' + ' }
.minus_assign { ' - ' }
.mult_assign { ' * ' }
.div_assign { ' / ' }
.mod_assign { ' % ' }
.xor_assign { ' ^ ' }
.and_assign { ' & ' }
.right_shift_assign { ' >> ' }
.left_shift_assign { ' << ' }
.or_assign { ' | ' }
else { panic('unexpected op ${stmt.op}') }
})
}
.assign, .decl_assign {
if !array_set {
g.write(' = ')
}
}
// TODO: Multiple types??

should_cast := if stmt.left_types.len == 0 {
false
} else {
g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables
&& (g.cast_stack.len <= 0 || stmt.left_types.first() != g.cast_stack.last())
else {
panic('unsupported assignment operator provided: ${stmt.op}')
}
}

if should_cast {
g.cast_stack << stmt.left_types.first()
g.write('new ')
g.write('${g.typ(stmt.left_types.first())}(')
}
g.expr(val)
if is_ptr {
g.write('.val')
}
if should_cast {
g.write(')')
g.cast_stack.delete_last()
}
if is_assign && array_set {
g.write(')')
}
if floor {
g.write(')')
}
// TODO: Multiple types??

should_cast := stmt.left_types.len != 0
&& g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables
&& (g.cast_stack.len <= 0 || stmt.left_types.first() != g.cast_stack.last())
if should_cast {
g.cast_stack << stmt.left_types.first()
g.write('new ${g.typ(stmt.left_types.first())}(')
}
g.expr(val)
if is_ptr {
g.write('.val')
}
if should_cast {
g.write(')')
g.cast_stack.delete_last()
}
if is_special_assign && array_set {
g.write(')')
}
if floor {
g.write(')')
}
if array_set && !map_set {
g.write(')')
Expand Down Expand Up @@ -3382,14 +3316,8 @@ fn (mut g JsGen) gen_string_inter_literal(it ast.StringInterLiteral) {
}

fn (mut g JsGen) gen_string_literal(it ast.StringLiteral) {
mut text := it.val.replace("'", "'")
text = text.replace('"', '\\"')
should_cast := !(g.cast_stack.len > 0 && g.cast_stack.last() == ast.string_type_idx)
if true || should_cast {
g.write('new ')

g.write('string(')
}
text := it.val.replace("'", "'").replace('"', '\\"')
g.write('new string(')
if it.is_raw {
g.writeln('(function() { let s = String(); ')
for x in text {
Expand All @@ -3407,9 +3335,7 @@ fn (mut g JsGen) gen_string_literal(it ast.StringLiteral) {
}
g.write('"')
}
if true || should_cast {
g.write(')')
}
g.write(')')
}

fn (mut g JsGen) gen_struct_init(it ast.StructInit) {
Expand Down

0 comments on commit bb3505f

Please sign in to comment.