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
|
@ -398,12 +398,13 @@ pub fn (f &StructField) equals(o &StructField) bool {
|
||||||
// const field in const declaration group
|
// const field in const declaration group
|
||||||
pub struct ConstField {
|
pub struct ConstField {
|
||||||
pub:
|
pub:
|
||||||
mod string
|
mod string
|
||||||
name string
|
name string
|
||||||
is_pub bool
|
is_pub bool
|
||||||
is_markused bool // an explicit `@[markused]` tag; the const will NOT be removed by `-skip-unused`, no matter what
|
is_markused bool // an explicit `@[markused]` tag; the const will NOT be removed by `-skip-unused`, no matter what
|
||||||
pos token.Pos
|
pos token.Pos
|
||||||
attrs []Attr // same value as `attrs` of the ConstDecl to which it belongs
|
attrs []Attr // same value as `attrs` of the ConstDecl to which it belongs
|
||||||
|
is_virtual_c bool // `const C.MY_CONST u8`
|
||||||
pub mut:
|
pub mut:
|
||||||
expr Expr // the value expr of field; everything after `=`
|
expr Expr // the value expr of field; everything after `=`
|
||||||
typ Type // the type of the const field, it can be any type in V
|
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' {
|
if node.name == 'C.NULL' {
|
||||||
return ast.voidptr_type
|
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
|
return ast.int_type
|
||||||
}
|
}
|
||||||
if c.inside_sql {
|
if c.inside_sql {
|
||||||
|
|
|
@ -968,9 +968,17 @@ pub fn (mut f Fmt) const_decl(node ast.ConstDecl) {
|
||||||
}
|
}
|
||||||
f.write('const ')
|
f.write('const ')
|
||||||
}
|
}
|
||||||
|
if field.is_virtual_c {
|
||||||
|
f.write('C.')
|
||||||
|
}
|
||||||
f.write('${name} ')
|
f.write('${name} ')
|
||||||
f.write('= ')
|
if field.is_virtual_c {
|
||||||
f.expr(field.expr)
|
// 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)
|
f.comments(field.end_comments, same_line: true)
|
||||||
if node.is_block && fidx < node.fields.len - 1 && node.fields.len > 1 {
|
if node.is_block && fidx < node.fields.len - 1 && node.fields.len > 1 {
|
||||||
// old style grouped consts, converted to the new style ungrouped const
|
// old style grouped consts, converted to the new style ungrouped const
|
||||||
|
|
|
@ -2368,10 +2368,20 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
pos := p.tok.pos()
|
pos := p.tok.pos()
|
||||||
name := p.check_name()
|
mut name := p.check_name()
|
||||||
end_comments << p.eat_comments()
|
end_comments << p.eat_comments()
|
||||||
if !p.pref.translated && !p.is_translated && util.contains_capital(name) {
|
// Handle `const C.MY_CONST u16`
|
||||||
p.error_with_pos('const names cannot contain uppercase letters, use snake_case instead',
|
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)
|
pos)
|
||||||
}
|
}
|
||||||
full_name := p.prepend_mod(name)
|
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())
|
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.
|
// 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 {
|
if p.tok.kind == .decl_assign {
|
||||||
p.check(.decl_assign)
|
p.check(.decl_assign)
|
||||||
} else {
|
} else {
|
||||||
p.check(.assign)
|
if !is_virtual_c_const {
|
||||||
|
p.check(.assign)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
end_comments << p.eat_comments()
|
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')
|
p.error('const initializer fn literal is not a constant')
|
||||||
return ast.ConstDecl{}
|
return ast.ConstDecl{}
|
||||||
}
|
}
|
||||||
|
@ -2394,11 +2407,14 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
||||||
p.unexpected(got: 'eof', expecting: 'an expression')
|
p.unexpected(got: 'eof', expecting: 'an expression')
|
||||||
return ast.ConstDecl{}
|
return ast.ConstDecl{}
|
||||||
}
|
}
|
||||||
expr := p.expr(0)
|
mut expr := ast.Expr{}
|
||||||
|
if !is_virtual_c_const {
|
||||||
|
expr = p.expr(0)
|
||||||
|
}
|
||||||
if is_block {
|
if is_block {
|
||||||
end_comments << p.eat_comments(same_line: true)
|
end_comments << p.eat_comments(same_line: true)
|
||||||
}
|
}
|
||||||
field := ast.ConstField{
|
mut field := ast.ConstField{
|
||||||
name: full_name
|
name: full_name
|
||||||
mod: p.mod
|
mod: p.mod
|
||||||
is_pub: is_pub
|
is_pub: is_pub
|
||||||
|
@ -2408,6 +2424,10 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
||||||
comments: comments
|
comments: comments
|
||||||
end_comments: end_comments
|
end_comments: end_comments
|
||||||
is_markused: is_markused
|
is_markused: is_markused
|
||||||
|
is_virtual_c: is_virtual_c_const
|
||||||
|
}
|
||||||
|
if is_virtual_c_const {
|
||||||
|
field.typ = typ
|
||||||
}
|
}
|
||||||
fields << field
|
fields << field
|
||||||
p.table.global_scope.register(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