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('pos', t.pos(node.pos))
obj.add_terse('args', t.array_node_call_arg(node.args))
obj.add_terse('or_block', t.or_expr(node.or_block))
return obj
}

View File

@ -1845,6 +1845,7 @@ pub:
is_env bool
env_pos token.Pos
is_pkgconfig bool
or_block OrExpr
pub mut:
left_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
node.args[i].typ = c.expr(arg.expr)
}
c.stmts_ending_with_expression(node.or_block.stmts)
// assume string for now
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.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)}*)')
}
// TODO: check argument types
@ -222,9 +223,20 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
}
}
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)')
}
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
}
mut j := 0

View File

@ -357,9 +357,13 @@ fn (mut p Parser) comptime_selector(left ast.Expr) ast.Expr {
p.check(.lpar)
args := p.call_args()
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 {
p.next()
p.check(.lcbr)
// `$method() or {}``
or_kind = .block
or_stmts, or_pos = p.or_block(.with_err_var)
}
return ast.ComptimeCall{
left: left
@ -369,6 +373,11 @@ fn (mut p Parser) comptime_selector(left ast.Expr) ast.Expr {
args_var: ''
args: args
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

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'
}