mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
v: virtual C consts with custom types (const C.MY_CONST u8)
This commit is contained in:
parent
3725576729
commit
9ef51ee714
5 changed files with 58 additions and 16 deletions
|
@ -404,6 +404,7 @@ pub:
|
|||
is_markused bool // an explicit `@[markused]` tag; the const will NOT be removed by `-skip-unused`, no matter what
|
||||
pos token.Pos
|
||||
attrs []Attr // same value as `attrs` of the ConstDecl to which it belongs
|
||||
is_virtual_c bool // `const C.MY_CONST u8`
|
||||
pub mut:
|
||||
expr Expr // the value expr of field; everything after `=`
|
||||
typ Type // the type of the const field, it can be any type in V
|
||||
|
|
|
@ -4297,6 +4297,10 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
|||
if node.name == 'C.NULL' {
|
||||
return ast.voidptr_type
|
||||
}
|
||||
// TODO remove main. to avoid extra concats
|
||||
if x := c.table.global_scope.find_const('main.' + node.name) {
|
||||
return x.typ
|
||||
}
|
||||
return ast.int_type
|
||||
}
|
||||
if c.inside_sql {
|
||||
|
|
|
@ -968,9 +968,17 @@ pub fn (mut f Fmt) const_decl(node ast.ConstDecl) {
|
|||
}
|
||||
f.write('const ')
|
||||
}
|
||||
if field.is_virtual_c {
|
||||
f.write('C.')
|
||||
}
|
||||
f.write('${name} ')
|
||||
if field.is_virtual_c {
|
||||
// f.typ(field.typ)
|
||||
f.write(f.table.type_to_str(field.typ))
|
||||
} else {
|
||||
f.write('= ')
|
||||
f.expr(field.expr)
|
||||
}
|
||||
f.comments(field.end_comments, same_line: true)
|
||||
if node.is_block && fidx < node.fields.len - 1 && node.fields.len > 1 {
|
||||
// old style grouped consts, converted to the new style ungrouped const
|
||||
|
|
|
@ -2368,10 +2368,20 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
|||
break
|
||||
}
|
||||
pos := p.tok.pos()
|
||||
name := p.check_name()
|
||||
mut name := p.check_name()
|
||||
end_comments << p.eat_comments()
|
||||
if !p.pref.translated && !p.is_translated && util.contains_capital(name) {
|
||||
p.error_with_pos('const names cannot contain uppercase letters, use snake_case instead',
|
||||
// Handle `const C.MY_CONST u16`
|
||||
mut is_virtual_c_const := false
|
||||
mut typ := ast.void_type
|
||||
if name == 'C' && p.tok.kind == .dot {
|
||||
p.next()
|
||||
name += '.' + p.check_name()
|
||||
typ = p.parse_type()
|
||||
is_virtual_c_const = true
|
||||
}
|
||||
if !p.pref.translated && !p.is_translated && util.contains_capital(name)
|
||||
&& !is_virtual_c_const {
|
||||
p.error_with_pos('${name} const names cannot contain uppercase letters, use snake_case instead',
|
||||
pos)
|
||||
}
|
||||
full_name := p.prepend_mod(name)
|
||||
|
@ -2379,14 +2389,17 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
|||
p.error_with_pos('const declaration do not support multiple assign yet', p.tok.pos())
|
||||
}
|
||||
// Allow for `const x := 123`, and for `const x = 123` too.
|
||||
// Supporting `const x := 123` in addition to `const x = 123`, makes extracting local variables to constants much less annoying, while prototyping:
|
||||
// Supporting `const x := 123` in addition to `const x = 123`, makes extracting local variables to constants
|
||||
// much less annoying, while prototyping:
|
||||
if p.tok.kind == .decl_assign {
|
||||
p.check(.decl_assign)
|
||||
} else {
|
||||
if !is_virtual_c_const {
|
||||
p.check(.assign)
|
||||
}
|
||||
}
|
||||
end_comments << p.eat_comments()
|
||||
if p.tok.kind == .key_fn {
|
||||
if p.tok.kind == .key_fn && !is_virtual_c_const {
|
||||
p.error('const initializer fn literal is not a constant')
|
||||
return ast.ConstDecl{}
|
||||
}
|
||||
|
@ -2394,11 +2407,14 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
|||
p.unexpected(got: 'eof', expecting: 'an expression')
|
||||
return ast.ConstDecl{}
|
||||
}
|
||||
expr := p.expr(0)
|
||||
mut expr := ast.Expr{}
|
||||
if !is_virtual_c_const {
|
||||
expr = p.expr(0)
|
||||
}
|
||||
if is_block {
|
||||
end_comments << p.eat_comments(same_line: true)
|
||||
}
|
||||
field := ast.ConstField{
|
||||
mut field := ast.ConstField{
|
||||
name: full_name
|
||||
mod: p.mod
|
||||
is_pub: is_pub
|
||||
|
@ -2408,6 +2424,10 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
|||
comments: comments
|
||||
end_comments: end_comments
|
||||
is_markused: is_markused
|
||||
is_virtual_c: is_virtual_c_const
|
||||
}
|
||||
if is_virtual_c_const {
|
||||
field.typ = typ
|
||||
}
|
||||
fields << field
|
||||
p.table.global_scope.register(field)
|
||||
|
|
9
vlib/v/tests/c_const_u8_test.v
Normal file
9
vlib/v/tests/c_const_u8_test.v
Normal file
|
@ -0,0 +1,9 @@
|
|||
const C.AF_INET u16
|
||||
|
||||
fn x(n u16) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
fn test_const() {
|
||||
assert x(C.AF_INET) == true
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue