v,ast,fmt,parser: support @[tag] for hash statements, like #define and #flag (#23210)

This commit is contained in:
Delyan Angelov 2024-12-20 08:49:03 +02:00 committed by GitHub
parent 30ececc2a3
commit 9ae0a9db9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 45 additions and 9 deletions

View file

@ -592,7 +592,7 @@ fn (t Tree) fn_decl(node ast.FnDecl) &Node {
obj.add_terse('return_type', t.type_node(node.return_type)) obj.add_terse('return_type', t.type_node(node.return_type))
obj.add('source_file', t.number_node(int(node.source_file))) obj.add('source_file', t.number_node(int(node.source_file)))
obj.add('scope', t.number_node(int(node.scope))) obj.add('scope', t.number_node(int(node.scope)))
obj.add('attrs', t.array_node_attr(node.attrs)) obj.add_terse('attrs', t.array_node_attr(node.attrs))
obj.add_terse('params', t.array_node_arg(node.params)) obj.add_terse('params', t.array_node_arg(node.params))
obj.add_terse('generic_names', t.array_node_string(node.generic_names)) obj.add_terse('generic_names', t.array_node_string(node.generic_names))
obj.add_terse('stmts', t.array_node_stmt(node.stmts)) obj.add_terse('stmts', t.array_node_stmt(node.stmts))
@ -756,8 +756,10 @@ fn (t Tree) hash_stmt(node ast.HashStmt) &Node {
obj.add_terse('kind', t.string_node(node.kind)) obj.add_terse('kind', t.string_node(node.kind))
obj.add_terse('main', t.string_node(node.main)) obj.add_terse('main', t.string_node(node.main))
obj.add_terse('msg', t.string_node(node.msg)) obj.add_terse('msg', t.string_node(node.msg))
obj.add_terse('is_use_once', t.bool_node(node.is_use_once))
obj.add_terse('ct_conds', t.array_node_expr(node.ct_conds)) obj.add_terse('ct_conds', t.array_node_expr(node.ct_conds))
obj.add_terse('source_file', t.string_node(node.source_file)) obj.add_terse('source_file', t.string_node(node.source_file))
obj.add_terse('attrs', t.array_node_attr(node.attrs))
obj.add('pos', t.pos(node.pos)) obj.add('pos', t.pos(node.pos))
return obj return obj
} }
@ -778,11 +780,11 @@ fn (t Tree) global_decl(node ast.GlobalDecl) &Node {
mut obj := new_object() mut obj := new_object()
obj.add_terse('ast_type', t.string_node('GlobalDecl')) obj.add_terse('ast_type', t.string_node('GlobalDecl'))
obj.add_terse('mod', t.string_node(node.mod)) obj.add_terse('mod', t.string_node(node.mod))
obj.add('pos', t.pos(node.pos)) obj.add_terse('attrs', t.array_node_attr(node.attrs))
obj.add_terse('is_block', t.bool_node(node.is_block)) obj.add_terse('is_block', t.bool_node(node.is_block))
obj.add_terse('fields', t.array_node_global_field(node.fields)) obj.add_terse('fields', t.array_node_global_field(node.fields))
obj.add('pos', t.pos(node.pos))
obj.add('end_comments', t.array_node_comment(node.end_comments)) obj.add('end_comments', t.array_node_comment(node.end_comments))
obj.add('attrs', t.array_node_attr(node.attrs))
return obj return obj
} }

View file

@ -1,6 +1,8 @@
module fontstash module fontstash
#flag -I @VEXEROOT/thirdparty/fontstash #flag -I @VEXEROOT/thirdparty/fontstash
@[use_once]
#define FONTSTASH_IMPLEMENTATION #define FONTSTASH_IMPLEMENTATION
$if gcboehm ? { $if gcboehm ? {
#define FONTSTASH_MALLOC GC_MALLOC #define FONTSTASH_MALLOC GC_MALLOC

View file

@ -10,6 +10,8 @@ $if linux {
#flag -I @VEXEROOT/thirdparty/sokol #flag -I @VEXEROOT/thirdparty/sokol
// FreeBSD requires the audio/alsa-lib to be installed // FreeBSD requires the audio/alsa-lib to be installed
#flag freebsd -I/usr/local/include #flag freebsd -I/usr/local/include
@[use_once]
#define SOKOL_IMPL #define SOKOL_IMPL
#include "sokol_audio.h" #include "sokol_audio.h"
#flag linux -lasound -lpthread #flag linux -lasound -lpthread

View file

@ -56,6 +56,8 @@ $if emscripten ? {
//#flag windows -DSOKOL_D3D11 //#flag windows -DSOKOL_D3D11
// for simplicity, all header includes are here because import order matters and we dont have any way // for simplicity, all header includes are here because import order matters and we dont have any way
// to ensure import order with V yet // to ensure import order with V yet
@[use_once]
#define SOKOL_IMPL #define SOKOL_IMPL
// TODO: should not be defined for android graphic (apk/aab using sokol) builds, but we have no ways to undefine // TODO: should not be defined for android graphic (apk/aab using sokol) builds, but we have no ways to undefine
//#define SOKOL_NO_ENTRY //#define SOKOL_NO_ENTRY
@ -75,9 +77,13 @@ $if emscripten ? {
$if !no_sokol_app ? { $if !no_sokol_app ? {
#include "sokol_app.h" #include "sokol_app.h"
} }
@[use_once]
#define SOKOL_IMPL #define SOKOL_IMPL
#define SOKOL_NO_DEPRECATED #define SOKOL_NO_DEPRECATED
#include "sokol_gfx.h" #include "sokol_gfx.h"
@[use_once]
#define SOKOL_GL_IMPL #define SOKOL_GL_IMPL
#include "util/sokol_gl.h" #include "util/sokol_gl.h"
#include "sokol_v.post.h" #include "sokol_v.post.h"

View file

@ -7,5 +7,6 @@ import sokol.c as _
//#include "ft2build.h" //#include "ft2build.h"
@[use_once]
#define SOKOL_FONTSTASH_IMPL #define SOKOL_FONTSTASH_IMPL
#include "util/sokol_fontstash.h" #include "util/sokol_fontstash.h"

View file

@ -1365,6 +1365,7 @@ pub:
mod string mod string
pos token.Pos pos token.Pos
source_file string source_file string
is_use_once bool // true for @[use_once]
pub mut: pub mut:
val string // example: 'include <openssl/rand.h> # please install openssl // comment' val string // example: 'include <openssl/rand.h> # please install openssl // comment'
kind string // : 'include' kind string // : 'include'
@ -1372,6 +1373,7 @@ pub mut:
msg string // : 'please install openssl' msg string // : 'please install openssl'
ct_conds []Expr // *all* comptime conditions, that must be true, for the hash to be processed ct_conds []Expr // *all* comptime conditions, that must be true, for the hash to be processed
// ct_conds is filled by the checker, based on the current nesting of `$if cond1 {}` blocks // ct_conds is filled by the checker, based on the current nesting of `$if cond1 {}` blocks
attrs []Attr
} }
// variable assign statement // variable assign statement

View file

@ -1361,6 +1361,7 @@ pub fn (mut f Fmt) goto_stmt(node ast.GotoStmt) {
} }
pub fn (mut f Fmt) hash_stmt(node ast.HashStmt) { pub fn (mut f Fmt) hash_stmt(node ast.HashStmt) {
f.attrs(node.attrs)
f.writeln('#${node.val}') f.writeln('#${node.val}')
} }

View file

@ -10,3 +10,9 @@
// comment between without newlines // comment between without newlines
#include "sqlite3.h" #include "sqlite3.h"
// comment directly after the HsahStmt // comment directly after the HsahStmt
@[another; use_once]
#define SOME_SINGLE_HEADER_IMPL 1
@[custom_tag; use_once]
#flag -I @VMODROOT/c/something/else

View file

@ -78,6 +78,7 @@ fn (mut p Parser) hash() ast.HashStmt {
pos := p.tok.pos() pos := p.tok.pos()
val := p.tok.lit val := p.tok.lit
kind := val.all_before(' ') kind := val.all_before(' ')
attrs := p.attrs
p.next() p.next()
mut main_str := '' mut main_str := ''
mut msg := '' mut msg := ''
@ -89,6 +90,15 @@ fn (mut p Parser) hash() ast.HashStmt {
main_str = content.trim_space() main_str = content.trim_space()
msg = '' msg = ''
} }
mut is_use_once := false
for fna in attrs {
match fna.name {
'use_once' { is_use_once = true }
else {}
}
}
return ast.HashStmt{ return ast.HashStmt{
mod: p.mod mod: p.mod
source_file: p.file_path source_file: p.file_path
@ -97,6 +107,8 @@ fn (mut p Parser) hash() ast.HashStmt {
main: main_str main: main_str
msg: msg msg: msg
pos: pos pos: pos
attrs: attrs
is_use_once: is_use_once
} }
} }

View file

@ -203,7 +203,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
mut is_markused := false mut is_markused := false
mut is_expand_simple_interpolation := false mut is_expand_simple_interpolation := false
mut comments := []ast.Comment{} mut comments := []ast.Comment{}
for fna in p.attrs { fn_attrs := p.attrs
p.attrs = []
for fna in fn_attrs {
match fna.name { match fna.name {
'noreturn' { 'noreturn' {
is_noreturn = true is_noreturn = true
@ -271,7 +273,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
else {} else {}
} }
} }
conditional_ctdefine_idx := p.attrs.find_comptime_define() or { -1 } conditional_ctdefine_idx := fn_attrs.find_comptime_define() or { -1 }
is_pub := p.tok.kind == .key_pub is_pub := p.tok.kind == .key_pub
if is_pub { if is_pub {
p.next() p.next()
@ -286,7 +288,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
mut language := p.parse_language() mut language := p.parse_language()
p.fn_language = language p.fn_language = language
if language != .v { if language != .v {
for fna in p.attrs { for fna in fn_attrs {
if fna.name == 'export' { if fna.name == 'export' {
p.error_with_pos('interop function cannot be exported', fna.pos) p.error_with_pos('interop function cannot be exported', fna.pos)
break break
@ -555,7 +557,7 @@ run them via `v file.v` instead',
is_method: true is_method: true
receiver_type: rec.typ receiver_type: rec.typ
// //
attrs: p.attrs attrs: fn_attrs
is_conditional: conditional_ctdefine_idx != ast.invalid_type_idx is_conditional: conditional_ctdefine_idx != ast.invalid_type_idx
ctdefine_idx: conditional_ctdefine_idx ctdefine_idx: conditional_ctdefine_idx
// //
@ -611,7 +613,7 @@ run them via `v file.v` instead',
receiver_type: if is_static_type_method { rec.typ } else { 0 } // used only if is static type method receiver_type: if is_static_type_method { rec.typ } else { 0 } // used only if is static type method
is_file_translated: p.is_translated is_file_translated: p.is_translated
// //
attrs: p.attrs attrs: fn_attrs
is_conditional: conditional_ctdefine_idx != ast.invalid_type_idx is_conditional: conditional_ctdefine_idx != ast.invalid_type_idx
ctdefine_idx: conditional_ctdefine_idx ctdefine_idx: conditional_ctdefine_idx
// //
@ -686,7 +688,7 @@ run them via `v file.v` instead',
is_markused: is_markused is_markused: is_markused
is_file_translated: p.is_translated is_file_translated: p.is_translated
// //
attrs: p.attrs attrs: fn_attrs
is_conditional: conditional_ctdefine_idx != ast.invalid_type_idx is_conditional: conditional_ctdefine_idx != ast.invalid_type_idx
ctdefine_idx: conditional_ctdefine_idx ctdefine_idx: conditional_ctdefine_idx
// //