mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
v,ast,fmt,parser: support @[tag]
for hash statements, like #define
and #flag
(#23210)
This commit is contained in:
parent
30ececc2a3
commit
9ae0a9db9b
10 changed files with 45 additions and 9 deletions
|
@ -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('source_file', t.number_node(int(node.source_file)))
|
||||
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('generic_names', t.array_node_string(node.generic_names))
|
||||
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('main', t.string_node(node.main))
|
||||
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('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))
|
||||
return obj
|
||||
}
|
||||
|
@ -778,11 +780,11 @@ fn (t Tree) global_decl(node ast.GlobalDecl) &Node {
|
|||
mut obj := new_object()
|
||||
obj.add_terse('ast_type', t.string_node('GlobalDecl'))
|
||||
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('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('attrs', t.array_node_attr(node.attrs))
|
||||
return obj
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
module fontstash
|
||||
|
||||
#flag -I @VEXEROOT/thirdparty/fontstash
|
||||
|
||||
@[use_once]
|
||||
#define FONTSTASH_IMPLEMENTATION
|
||||
$if gcboehm ? {
|
||||
#define FONTSTASH_MALLOC GC_MALLOC
|
||||
|
|
|
@ -10,6 +10,8 @@ $if linux {
|
|||
#flag -I @VEXEROOT/thirdparty/sokol
|
||||
// FreeBSD requires the audio/alsa-lib to be installed
|
||||
#flag freebsd -I/usr/local/include
|
||||
|
||||
@[use_once]
|
||||
#define SOKOL_IMPL
|
||||
#include "sokol_audio.h"
|
||||
#flag linux -lasound -lpthread
|
||||
|
|
|
@ -56,6 +56,8 @@ $if emscripten ? {
|
|||
//#flag windows -DSOKOL_D3D11
|
||||
// for simplicity, all header includes are here because import order matters and we dont have any way
|
||||
// to ensure import order with V yet
|
||||
|
||||
@[use_once]
|
||||
#define SOKOL_IMPL
|
||||
// TODO: should not be defined for android graphic (apk/aab using sokol) builds, but we have no ways to undefine
|
||||
//#define SOKOL_NO_ENTRY
|
||||
|
@ -75,9 +77,13 @@ $if emscripten ? {
|
|||
$if !no_sokol_app ? {
|
||||
#include "sokol_app.h"
|
||||
}
|
||||
|
||||
@[use_once]
|
||||
#define SOKOL_IMPL
|
||||
#define SOKOL_NO_DEPRECATED
|
||||
#include "sokol_gfx.h"
|
||||
|
||||
@[use_once]
|
||||
#define SOKOL_GL_IMPL
|
||||
#include "util/sokol_gl.h"
|
||||
#include "sokol_v.post.h"
|
||||
|
|
|
@ -7,5 +7,6 @@ import sokol.c as _
|
|||
|
||||
//#include "ft2build.h"
|
||||
|
||||
@[use_once]
|
||||
#define SOKOL_FONTSTASH_IMPL
|
||||
#include "util/sokol_fontstash.h"
|
||||
|
|
|
@ -1365,6 +1365,7 @@ pub:
|
|||
mod string
|
||||
pos token.Pos
|
||||
source_file string
|
||||
is_use_once bool // true for @[use_once]
|
||||
pub mut:
|
||||
val string // example: 'include <openssl/rand.h> # please install openssl // comment'
|
||||
kind string // : 'include'
|
||||
|
@ -1372,6 +1373,7 @@ pub mut:
|
|||
msg string // : 'please install openssl'
|
||||
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
|
||||
attrs []Attr
|
||||
}
|
||||
|
||||
// variable assign statement
|
||||
|
|
|
@ -1361,6 +1361,7 @@ pub fn (mut f Fmt) goto_stmt(node ast.GotoStmt) {
|
|||
}
|
||||
|
||||
pub fn (mut f Fmt) hash_stmt(node ast.HashStmt) {
|
||||
f.attrs(node.attrs)
|
||||
f.writeln('#${node.val}')
|
||||
}
|
||||
|
||||
|
|
|
@ -10,3 +10,9 @@
|
|||
// comment between without newlines
|
||||
#include "sqlite3.h"
|
||||
// comment directly after the HsahStmt
|
||||
|
||||
@[another; use_once]
|
||||
#define SOME_SINGLE_HEADER_IMPL 1
|
||||
|
||||
@[custom_tag; use_once]
|
||||
#flag -I @VMODROOT/c/something/else
|
||||
|
|
|
@ -78,6 +78,7 @@ fn (mut p Parser) hash() ast.HashStmt {
|
|||
pos := p.tok.pos()
|
||||
val := p.tok.lit
|
||||
kind := val.all_before(' ')
|
||||
attrs := p.attrs
|
||||
p.next()
|
||||
mut main_str := ''
|
||||
mut msg := ''
|
||||
|
@ -89,6 +90,15 @@ fn (mut p Parser) hash() ast.HashStmt {
|
|||
main_str = content.trim_space()
|
||||
msg = ''
|
||||
}
|
||||
|
||||
mut is_use_once := false
|
||||
for fna in attrs {
|
||||
match fna.name {
|
||||
'use_once' { is_use_once = true }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
||||
return ast.HashStmt{
|
||||
mod: p.mod
|
||||
source_file: p.file_path
|
||||
|
@ -97,6 +107,8 @@ fn (mut p Parser) hash() ast.HashStmt {
|
|||
main: main_str
|
||||
msg: msg
|
||||
pos: pos
|
||||
attrs: attrs
|
||||
is_use_once: is_use_once
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -203,7 +203,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
mut is_markused := false
|
||||
mut is_expand_simple_interpolation := false
|
||||
mut comments := []ast.Comment{}
|
||||
for fna in p.attrs {
|
||||
fn_attrs := p.attrs
|
||||
p.attrs = []
|
||||
for fna in fn_attrs {
|
||||
match fna.name {
|
||||
'noreturn' {
|
||||
is_noreturn = true
|
||||
|
@ -271,7 +273,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
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
|
||||
if is_pub {
|
||||
p.next()
|
||||
|
@ -286,7 +288,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
mut language := p.parse_language()
|
||||
p.fn_language = language
|
||||
if language != .v {
|
||||
for fna in p.attrs {
|
||||
for fna in fn_attrs {
|
||||
if fna.name == 'export' {
|
||||
p.error_with_pos('interop function cannot be exported', fna.pos)
|
||||
break
|
||||
|
@ -555,7 +557,7 @@ run them via `v file.v` instead',
|
|||
is_method: true
|
||||
receiver_type: rec.typ
|
||||
//
|
||||
attrs: p.attrs
|
||||
attrs: fn_attrs
|
||||
is_conditional: conditional_ctdefine_idx != ast.invalid_type_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
|
||||
is_file_translated: p.is_translated
|
||||
//
|
||||
attrs: p.attrs
|
||||
attrs: fn_attrs
|
||||
is_conditional: conditional_ctdefine_idx != ast.invalid_type_idx
|
||||
ctdefine_idx: conditional_ctdefine_idx
|
||||
//
|
||||
|
@ -686,7 +688,7 @@ run them via `v file.v` instead',
|
|||
is_markused: is_markused
|
||||
is_file_translated: p.is_translated
|
||||
//
|
||||
attrs: p.attrs
|
||||
attrs: fn_attrs
|
||||
is_conditional: conditional_ctdefine_idx != ast.invalid_type_idx
|
||||
ctdefine_idx: conditional_ctdefine_idx
|
||||
//
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue