jsgen: optional "or blocks" (#6938)
parent
23c9563600
commit
96b73acad7
|
@ -0,0 +1,6 @@
|
|||
module builtin
|
||||
|
||||
// used to generate JS throw statements.
|
||||
pub fn js_throw(s any) {
|
||||
#throw (s instanceof Error ? s : new Error(s))
|
||||
}
|
|
@ -35,13 +35,13 @@ pub fn eprint(s any) {
|
|||
// a 'real' way to exit in the browser.
|
||||
pub fn exit(c int) {
|
||||
JS.process.exit(c)
|
||||
js_throw('exit($c)')
|
||||
}
|
||||
|
||||
pub fn unwrap(opt any) any {
|
||||
o := &Option(opt)
|
||||
if o.not_ok {
|
||||
panic(o.error)
|
||||
return o.error
|
||||
js_throw(o.error)
|
||||
}
|
||||
return opt
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ const (
|
|||
'public', 'return', 'static', 'super', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'void',
|
||||
'while', 'with', 'yield']
|
||||
tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t',
|
||||
'\t\t\t\t\t\t\t\t',
|
||||
'\t\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t\t'
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -1011,6 +1011,10 @@ fn (mut g JsGen) gen_go_stmt(node ast.GoStmt) {
|
|||
receiver_sym := g.table.get_type_symbol(node.call_expr.receiver_type)
|
||||
name = receiver_sym.name + '.' + name
|
||||
}
|
||||
// todo: please add a name feild without the mod name for ast.CallExpr
|
||||
if name.starts_with('$node.call_expr.mod\.') {
|
||||
name = name[node.call_expr.mod.len+1..]
|
||||
}
|
||||
g.writeln('await new Promise(function(resolve){')
|
||||
g.inc_indent()
|
||||
g.write('${name}(')
|
||||
|
@ -1048,7 +1052,7 @@ fn (mut g JsGen) gen_interface_decl(it ast.InterfaceDecl) {
|
|||
fn (mut g JsGen) gen_return_stmt(it ast.Return) {
|
||||
if it.exprs.len == 0 {
|
||||
// Returns nothing
|
||||
g.write('return;')
|
||||
g.writeln('return;')
|
||||
return
|
||||
}
|
||||
g.write('return ')
|
||||
|
@ -1173,7 +1177,11 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
|||
}
|
||||
call_return_is_optional := it.return_type.has_flag(.optional)
|
||||
if call_return_is_optional {
|
||||
g.write('builtin.unwrap(')
|
||||
g.writeln('(function(){')
|
||||
g.inc_indent()
|
||||
g.writeln('try {')
|
||||
g.inc_indent()
|
||||
g.write('return builtin.unwrap(')
|
||||
}
|
||||
g.expr(it.left)
|
||||
if it.is_method { // foo.bar.baz()
|
||||
|
@ -1224,10 +1232,40 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
|||
g.write(', ')
|
||||
}
|
||||
}
|
||||
if call_return_is_optional {
|
||||
g.write('))')
|
||||
} else {
|
||||
// end method call
|
||||
g.write(')')
|
||||
if call_return_is_optional {
|
||||
// end unwrap
|
||||
g.writeln(')')
|
||||
g.dec_indent()
|
||||
// begin catch block
|
||||
g.writeln('} catch(err) {')
|
||||
g.inc_indent()
|
||||
// gen or block contents
|
||||
match it.or_block.kind {
|
||||
.block {
|
||||
if it.or_block.stmts.len > 1 {
|
||||
g.stmts(it.or_block.stmts[..it.or_block.stmts.len-1])
|
||||
}
|
||||
g.write('return ')
|
||||
g.stmt(it.or_block.stmts.last())
|
||||
}
|
||||
.propagate {
|
||||
panicstr := '`optional not set (\${err})`'
|
||||
if g.file.mod.name == 'main' && g.fn_decl.name == 'main.main' {
|
||||
g.writeln('return builtin.panic($panicstr)')
|
||||
} else {
|
||||
g.writeln('builtin.js_throw(err)')
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
// end catch
|
||||
g.dec_indent()
|
||||
g.writeln('}')
|
||||
// end anon fn
|
||||
g.dec_indent()
|
||||
g.write('})()')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,8 +59,12 @@ fn main() {
|
|||
}
|
||||
for i, x in 'hello' {
|
||||
}
|
||||
mut evens := []int{}
|
||||
for x in 1 .. 10 {
|
||||
y := error_if_even(x) or { x + 1 }
|
||||
evens << y
|
||||
}
|
||||
println(evens)
|
||||
arr := [1, 2, 3, 4, 5]
|
||||
for i in arr {
|
||||
}
|
||||
|
@ -81,6 +85,7 @@ fn main() {
|
|||
println(message)
|
||||
})
|
||||
hl.raw_js_log()
|
||||
propagation() or { println(err) }
|
||||
}
|
||||
|
||||
fn anon_consumer(greeting string, anon fn (message string)) {
|
||||
|
@ -120,3 +125,13 @@ fn (it Companies) method() int {
|
|||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
fn error_if_even(num int) ?int {
|
||||
if num % 2 == 0 { return error('number is even') }
|
||||
return num
|
||||
}
|
||||
|
||||
fn propagation() ? {
|
||||
println('Propagation test:')
|
||||
return error('"Task failed successfully" - Windows XP')
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
module main
|
||||
|
||||
fn main() {
|
||||
try_propagation() or { println("captured: $err") }
|
||||
}
|
||||
|
||||
fn try_propagation() ? {
|
||||
try_numbers()?
|
||||
}
|
||||
|
||||
fn try_numbers() ? {
|
||||
for x in 1 .. 10 {
|
||||
y := error_if_even(x) or { x + 1 }
|
||||
println("$x rounded to $y")
|
||||
error_if_prime(y)?
|
||||
}
|
||||
}
|
||||
|
||||
fn error_if_even(num int) ?int {
|
||||
if num % 2 == 0 { return error('number is even') }
|
||||
return num
|
||||
}
|
||||
|
||||
fn error_if_prime(num int) ?int {
|
||||
for i in 2..num {
|
||||
if num % i == 0 {
|
||||
return error('$num is prime')
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
Loading…
Reference in New Issue