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

v: support for [if expr], part 2 (old [if ident] is not yet deprecated)

This commit is contained in:
Delyan Angelov
2021-06-17 11:38:42 +03:00
parent 0918c130ee
commit 39e7290416
9 changed files with 149 additions and 44 deletions

View File

@@ -197,7 +197,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
else {}
}
}
conditional_ctdefine := p.attrs.find_comptime_define() or { '' }
conditional_ctdefine_idx := p.attrs.find_comptime_define() or { -1 }
is_pub := p.tok.kind == .key_pub
if is_pub {
p.next()
@@ -376,12 +376,14 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
is_unsafe: is_unsafe
is_main: is_main
is_test: is_test
is_conditional: conditional_ctdefine != ''
is_keep_alive: is_keep_alive
ctdefine: conditional_ctdefine
//
attrs: p.attrs
is_conditional: conditional_ctdefine_idx != -1
ctdefine_idx: conditional_ctdefine_idx
//
no_body: no_body
mod: p.mod
attrs: p.attrs
})
} else {
if language == .c {
@@ -405,12 +407,14 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
is_unsafe: is_unsafe
is_main: is_main
is_test: is_test
is_conditional: conditional_ctdefine != ''
is_keep_alive: is_keep_alive
ctdefine: conditional_ctdefine
//
attrs: p.attrs
is_conditional: conditional_ctdefine_idx != -1
ctdefine_idx: conditional_ctdefine_idx
//
no_body: no_body
mod: p.mod
attrs: p.attrs
language: language
})
}
@@ -449,8 +453,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
is_variadic: is_variadic
is_main: is_main
is_test: is_test
is_conditional: conditional_ctdefine != ''
is_keep_alive: is_keep_alive
//
attrs: p.attrs
is_conditional: conditional_ctdefine_idx != -1
ctdefine_idx: conditional_ctdefine_idx
//
receiver: ast.StructField{
name: rec.name
typ: rec.typ
@@ -467,7 +475,6 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
body_pos: body_start_pos
file: p.file_name
is_builtin: p.builtin_mod || p.mod in util.builtin_module_parts
attrs: p.attrs
scope: p.scope
label_names: p.label_names
}

View File

@@ -1520,17 +1520,24 @@ fn (mut p Parser) parse_attr() ast.Attr {
mut name := ''
mut has_arg := false
mut arg := ''
mut comptime_cond := ast.empty_expr()
mut comptime_cond_opt := false
if p.tok.kind == .key_if {
kind = .comptime_define
p.next()
p.check(.name)
// TODO: remove this check after bootstrapping
// it is only for compatibility with the new
// [if user_defined?] syntax.
if p.tok.kind == .question {
p.next()
p.comp_if_cond = true
p.inside_if_expr = true
p.inside_ct_if_expr = true
comptime_cond = p.expr(0)
p.comp_if_cond = false
p.inside_if_expr = false
p.inside_ct_if_expr = false
if comptime_cond is ast.PostfixExpr {
x := comptime_cond as ast.PostfixExpr
comptime_cond_opt = true
comptime_cond = x.expr
}
name = p.prev_tok.lit
name = comptime_cond.str()
} else if p.tok.kind == .string {
name = p.tok.lit
kind = .string
@@ -1562,6 +1569,8 @@ fn (mut p Parser) parse_attr() ast.Attr {
has_arg: has_arg
arg: arg
kind: kind
ct_expr: comptime_cond
ct_opt: comptime_cond_opt
pos: apos.extend(p.tok.position())
}
}

View File

@@ -447,8 +447,10 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden
// Postfix
// detect `f(x++)`, `a[x++]`
if p.peek_tok.kind in [.rpar, .rsbr] {
p.warn_with_pos('`$p.tok.kind` operator can only be used as a statement',
p.peek_tok.position())
if !p.inside_ct_if_expr {
p.warn_with_pos('`$p.tok.kind` operator can only be used as a statement',
p.peek_tok.position())
}
}
if p.tok.kind in [.inc, .dec] && p.prev_tok.line_nr != p.tok.line_nr {
p.error_with_pos('$p.tok must be on the same line as the previous token',