js: fix break and continue in or blocks (#13165)
parent
9329b6c8c8
commit
104e0c5692
|
@ -97,6 +97,11 @@ fn (mut g JsGen) js_call(node ast.CallExpr) {
|
||||||
}
|
}
|
||||||
if call_return_is_optional {
|
if call_return_is_optional {
|
||||||
g.write(';\n')
|
g.write(';\n')
|
||||||
|
prev_inside_or := g.inside_or
|
||||||
|
g.inside_or = true
|
||||||
|
defer {
|
||||||
|
g.inside_or = prev_inside_or
|
||||||
|
}
|
||||||
g.writeln('if (tmp === null) throw "none";')
|
g.writeln('if (tmp === null) throw "none";')
|
||||||
g.writeln('return tmp;')
|
g.writeln('return tmp;')
|
||||||
g.writeln('} catch(err) {')
|
g.writeln('} catch(err) {')
|
||||||
|
@ -151,6 +156,11 @@ fn (mut g JsGen) js_method_call(node ast.CallExpr) {
|
||||||
// end method call
|
// end method call
|
||||||
g.write(')')
|
g.write(')')
|
||||||
if call_return_is_optional {
|
if call_return_is_optional {
|
||||||
|
prev_inside_or := g.inside_or
|
||||||
|
g.inside_or = true
|
||||||
|
defer {
|
||||||
|
g.inside_or = prev_inside_or
|
||||||
|
}
|
||||||
g.write(';\n')
|
g.write(';\n')
|
||||||
g.writeln('if (tmp === null) throw "none";')
|
g.writeln('if (tmp === null) throw "none";')
|
||||||
g.writeln('return tmp;')
|
g.writeln('return tmp;')
|
||||||
|
@ -339,6 +349,11 @@ fn (mut g JsGen) method_call(node ast.CallExpr) {
|
||||||
// end unwrap
|
// end unwrap
|
||||||
g.writeln(')')
|
g.writeln(')')
|
||||||
g.dec_indent()
|
g.dec_indent()
|
||||||
|
prev_inside_or := g.inside_or
|
||||||
|
g.inside_or = true
|
||||||
|
defer {
|
||||||
|
g.inside_or = prev_inside_or
|
||||||
|
}
|
||||||
// begin catch block
|
// begin catch block
|
||||||
g.writeln('} catch(err) {')
|
g.writeln('} catch(err) {')
|
||||||
g.inc_indent()
|
g.inc_indent()
|
||||||
|
@ -432,6 +447,11 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
if call_return_is_optional {
|
if call_return_is_optional {
|
||||||
// end unwrap
|
// end unwrap
|
||||||
|
prev_inside_or := g.inside_or
|
||||||
|
g.inside_or = true
|
||||||
|
defer {
|
||||||
|
g.inside_or = prev_inside_or
|
||||||
|
}
|
||||||
g.writeln(')')
|
g.writeln(')')
|
||||||
g.dec_indent()
|
g.dec_indent()
|
||||||
// begin catch block
|
// begin catch block
|
||||||
|
|
|
@ -54,6 +54,7 @@ mut:
|
||||||
file &ast.File
|
file &ast.File
|
||||||
tmp_count int
|
tmp_count int
|
||||||
inside_ternary bool
|
inside_ternary bool
|
||||||
|
inside_or bool
|
||||||
inside_loop bool
|
inside_loop bool
|
||||||
inside_map_set bool // map.set(key, value)
|
inside_map_set bool // map.set(key, value)
|
||||||
inside_builtin bool
|
inside_builtin bool
|
||||||
|
@ -478,6 +479,9 @@ pub fn (mut g JsGen) init() {
|
||||||
g.definitions.writeln('function checkDefine(key) {')
|
g.definitions.writeln('function checkDefine(key) {')
|
||||||
g.definitions.writeln('\tif (globalThis.hasOwnProperty(key)) { return !!globalThis[key]; } return false;')
|
g.definitions.writeln('\tif (globalThis.hasOwnProperty(key)) { return !!globalThis[key]; } return false;')
|
||||||
g.definitions.writeln('}')
|
g.definitions.writeln('}')
|
||||||
|
|
||||||
|
g.definitions.writeln('function BreakException() {}')
|
||||||
|
g.definitions.writeln('function ContinueException() {}')
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (g JsGen) hashes() string {
|
pub fn (g JsGen) hashes() string {
|
||||||
|
@ -1500,6 +1504,20 @@ fn (mut g JsGen) gen_block(it ast.Block) {
|
||||||
|
|
||||||
fn (mut g JsGen) gen_branch_stmt(it ast.BranchStmt) {
|
fn (mut g JsGen) gen_branch_stmt(it ast.BranchStmt) {
|
||||||
// continue or break
|
// continue or break
|
||||||
|
if g.inside_or {
|
||||||
|
match it.kind {
|
||||||
|
.key_break {
|
||||||
|
g.writeln('throw new BreakException();')
|
||||||
|
}
|
||||||
|
.key_continue {
|
||||||
|
g.writeln('throw new ContinueException();')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
verror('unexpected branch stmt: $it.kind')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
g.write(it.kind.str())
|
g.write(it.kind.str())
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
}
|
}
|
||||||
|
@ -1606,7 +1624,12 @@ fn (mut g JsGen) gen_for_c_stmt(it ast.ForCStmt) {
|
||||||
g.stmt_no_semi(it.inc)
|
g.stmt_no_semi(it.inc)
|
||||||
}
|
}
|
||||||
g.writeln(') {')
|
g.writeln(') {')
|
||||||
|
g.writeln('try { ')
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
|
g.writeln('} catch (e) {')
|
||||||
|
g.writeln(' if (e instanceof BreakException) { break; }')
|
||||||
|
g.writeln(' else if (e instanceof ContinueException) { continue; }')
|
||||||
|
g.writeln(' else { throw e; } }')
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
g.inside_loop = false
|
g.inside_loop = false
|
||||||
}
|
}
|
||||||
|
@ -1625,7 +1648,12 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
|
||||||
g.expr(it.high)
|
g.expr(it.high)
|
||||||
g.writeln('; $i = new int($i + 1)) {')
|
g.writeln('; $i = new int($i + 1)) {')
|
||||||
g.inside_loop = false
|
g.inside_loop = false
|
||||||
|
g.writeln('try { ')
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
|
g.writeln('} catch (e) {')
|
||||||
|
g.writeln(' if (e instanceof BreakException) { break; }')
|
||||||
|
g.writeln(' else if (e instanceof ContinueException) { continue; }')
|
||||||
|
g.writeln(' else { throw e; } }')
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
} else if it.kind in [.array, .string] || 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 {`
|
||||||
|
@ -1670,7 +1698,12 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.writeln(') {')
|
g.writeln(') {')
|
||||||
|
g.writeln('try { ')
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
|
g.writeln('} catch (e) {')
|
||||||
|
g.writeln(' if (e instanceof BreakException) { break; }')
|
||||||
|
g.writeln(' else if (e instanceof ContinueException) { continue; }')
|
||||||
|
g.writeln(' else { throw e; } }')
|
||||||
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 {`
|
||||||
|
@ -1695,7 +1728,12 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
|
||||||
g.writeln('\tlet $key = $tmp[$tmp3];')
|
g.writeln('\tlet $key = $tmp[$tmp3];')
|
||||||
g.writeln('\tlet $val = ${tmp2}.map[$tmp[$tmp3]];')
|
g.writeln('\tlet $val = ${tmp2}.map[$tmp[$tmp3]];')
|
||||||
g.inc_indent()
|
g.inc_indent()
|
||||||
|
g.writeln('try { ')
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
|
g.writeln('} catch (e) {')
|
||||||
|
g.writeln(' if (e instanceof BreakException) { break; }')
|
||||||
|
g.writeln(' else if (e instanceof ContinueException) { continue; }')
|
||||||
|
g.writeln(' else { throw e; } }')
|
||||||
g.dec_indent()
|
g.dec_indent()
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
} else {
|
} else {
|
||||||
|
@ -1710,7 +1748,12 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
|
||||||
g.inc_indent()
|
g.inc_indent()
|
||||||
g.writeln('let $val = ${tmp}.map[$tmp2];')
|
g.writeln('let $val = ${tmp}.map[$tmp2];')
|
||||||
g.writeln('let $key = $tmp2;')
|
g.writeln('let $key = $tmp2;')
|
||||||
|
g.writeln('try { ')
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
|
g.writeln('} catch (e) {')
|
||||||
|
g.writeln(' if (e instanceof BreakException) { break; }')
|
||||||
|
g.writeln(' else if (e instanceof ContinueException) { continue; }')
|
||||||
|
g.writeln(' else { throw e; } } ')
|
||||||
g.dec_indent()
|
g.dec_indent()
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
|
@ -1726,7 +1769,12 @@ fn (mut g JsGen) gen_for_stmt(it ast.ForStmt) {
|
||||||
g.expr(it.cond)
|
g.expr(it.cond)
|
||||||
}
|
}
|
||||||
g.writeln(') {')
|
g.writeln(') {')
|
||||||
|
g.writeln('try { ')
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
|
g.writeln('} catch (e) {')
|
||||||
|
g.writeln(' if (e instanceof BreakException) { break; }')
|
||||||
|
g.writeln(' else if (e instanceof ContinueException) { continue; }')
|
||||||
|
g.writeln(' else { throw e; } }')
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ fn main() {
|
||||||
println('Hello from V.js!')
|
println('Hello from V.js!')
|
||||||
println(JS.Math.atan2(1, 0))
|
println(JS.Math.atan2(1, 0))
|
||||||
non := JS.eval("console.log('Hello!')".str)
|
non := JS.eval("console.log('Hello!')".str)
|
||||||
if isnil (non) {
|
if isnil(non) {
|
||||||
println('non=nil')
|
println('non=nil')
|
||||||
}
|
}
|
||||||
ren := int(JS.eval('3'.str))
|
ren := int(JS.eval('3'.str))
|
||||||
|
|
Loading…
Reference in New Issue