1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: make comptime call works with or-block (#18215)

This commit is contained in:
Felipe Pena 2023-05-21 10:22:40 -03:00 committed by GitHub
parent 30e02cfa3d
commit 38a155ac81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 50 additions and 4 deletions

View File

@ -1001,6 +1001,7 @@ fn (t Tree) comptime_call(node ast.ComptimeCall) &Node {
obj.add_terse('env_value', t.string_node(node.env_value)) obj.add_terse('env_value', t.string_node(node.env_value))
obj.add('pos', t.pos(node.pos)) obj.add('pos', t.pos(node.pos))
obj.add_terse('args', t.array_node_call_arg(node.args)) obj.add_terse('args', t.array_node_call_arg(node.args))
obj.add_terse('or_block', t.or_expr(node.or_block))
return obj return obj
} }

View File

@ -1845,6 +1845,7 @@ pub:
is_env bool is_env bool
env_pos token.Pos env_pos token.Pos
is_pkgconfig bool is_pkgconfig bool
or_block OrExpr
pub mut: pub mut:
left_type Type left_type Type
result_type Type result_type Type

View File

@ -141,6 +141,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
// check each arg expression // check each arg expression
node.args[i].typ = c.expr(arg.expr) node.args[i].typ = c.expr(arg.expr)
} }
c.stmts_ending_with_expression(node.or_block.stmts)
// assume string for now // assume string for now
return ast.string_type return ast.string_type
} }

View File

@ -1968,6 +1968,7 @@ pub fn (mut f Fmt) comptime_call(node ast.ComptimeCall) {
} }
f.expr(node.left) f.expr(node.left)
f.write('.$${method_expr}') f.write('.$${method_expr}')
f.or_expr(node.or_block)
} }
} }
} }

View File

@ -161,7 +161,8 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
} }
} }
if !g.inside_call && (m.return_type.has_flag(.option) || m.return_type.has_flag(.result)) { if !g.inside_call && node.or_block.kind != .block
&& (m.return_type.has_flag(.option) || m.return_type.has_flag(.result)) {
g.write('(*(${g.base_type(m.return_type)}*)') g.write('(*(${g.base_type(m.return_type)}*)')
} }
// TODO: check argument types // TODO: check argument types
@ -222,9 +223,20 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
} }
} }
g.write(')') g.write(')')
if !g.inside_call && (m.return_type.has_flag(.option) || m.return_type.has_flag(.result)) { if !g.inside_call && node.or_block.kind != .block
&& (m.return_type.has_flag(.option) || m.return_type.has_flag(.result)) {
g.write('.data)') g.write('.data)')
} }
if node.or_block.kind != .absent
&& (m.return_type.has_flag(.option) || m.return_type.has_flag(.result)) {
if !g.inside_assign {
cur_line := g.go_before_stmt(0)
tmp_var := g.new_tmp_var()
g.write('${g.typ(m.return_type)} ${tmp_var} = ')
g.write(cur_line)
g.or_block(tmp_var, node.or_block, m.return_type)
}
}
return return
} }
mut j := 0 mut j := 0

View File

@ -357,9 +357,13 @@ fn (mut p Parser) comptime_selector(left ast.Expr) ast.Expr {
p.check(.lpar) p.check(.lpar)
args := p.call_args() args := p.call_args()
p.check(.rpar) p.check(.rpar)
mut or_kind := ast.OrKind.absent
mut or_pos := p.tok.pos()
mut or_stmts := []ast.Stmt{}
if p.tok.kind == .key_orelse { if p.tok.kind == .key_orelse {
p.next() // `$method() or {}``
p.check(.lcbr) or_kind = .block
or_stmts, or_pos = p.or_block(.with_err_var)
} }
return ast.ComptimeCall{ return ast.ComptimeCall{
left: left left: left
@ -369,6 +373,11 @@ fn (mut p Parser) comptime_selector(left ast.Expr) ast.Expr {
args_var: '' args_var: ''
args: args args: args
pos: start_pos.extend(p.prev_tok.pos()) pos: start_pos.extend(p.prev_tok.pos())
or_block: ast.OrExpr{
stmts: or_stmts
kind: or_kind
pos: or_pos
}
} }
} }
mut has_parens := false mut has_parens := false

View File

@ -0,0 +1,21 @@
pub struct App {
}
pub fn (mut app App) app_index() ! {
return error('hhh')
}
pub fn (mut app App) no_error() {
}
fn test_main() {
mut app := App{}
mut ret2 := ''
$for method in App.methods {
$if method.is_pub {
app.$method() or { ret2 = err.msg() }
dump(ret2)
}
}
assert ret2 == 'hhh'
}