mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
scanner: add support for @STRUCT
compile time substitution
This commit is contained in:
parent
285e04393e
commit
31ba64b409
@ -31,6 +31,7 @@ pub mut:
|
|||||||
is_started bool
|
is_started bool
|
||||||
fn_name string // needed for @FN
|
fn_name string // needed for @FN
|
||||||
mod_name string // needed for @MOD
|
mod_name string // needed for @MOD
|
||||||
|
struct_name string // needed for @STRUCT
|
||||||
is_print_line_on_error bool
|
is_print_line_on_error bool
|
||||||
is_print_colored_error bool
|
is_print_colored_error bool
|
||||||
is_print_rel_paths_on_error bool
|
is_print_rel_paths_on_error bool
|
||||||
@ -174,6 +175,67 @@ fn (mut s Scanner) ident_mod_name() string {
|
|||||||
return mod_name
|
return mod_name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ident_struct_name look ahead and return name of last encountered struct if possible, otherwise empty string
|
||||||
|
fn (mut s Scanner) ident_struct_name() string {
|
||||||
|
start := s.pos
|
||||||
|
mut pos := s.pos
|
||||||
|
|
||||||
|
// Return last known stuct_name encountered to avoid using high order/anonymous function definitions
|
||||||
|
if s.current_column() - 2 != 0 {
|
||||||
|
return s.struct_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pos++
|
||||||
|
|
||||||
|
// Eat whitespaces
|
||||||
|
for pos < s.text.len && s.text[pos].is_space() {
|
||||||
|
pos++
|
||||||
|
}
|
||||||
|
if pos >= s.text.len {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return if `(` is not the first character after "fn ..."
|
||||||
|
if s.text[pos] != `(` {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for closing paranthesis
|
||||||
|
for pos < s.text.len && s.text[pos] != `)` {
|
||||||
|
pos++
|
||||||
|
}
|
||||||
|
if pos >= s.text.len {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
pos--
|
||||||
|
// Search backwards for end position of struct name
|
||||||
|
// Eat whitespaces
|
||||||
|
for pos > start && s.text[pos].is_space() {
|
||||||
|
pos--
|
||||||
|
}
|
||||||
|
if pos < start {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
end_pos := pos + 1
|
||||||
|
|
||||||
|
// Go back while we have a name character or digit
|
||||||
|
for pos > start && (util.is_name_char(s.text[pos]) || s.text[pos].is_digit()) {
|
||||||
|
pos--
|
||||||
|
}
|
||||||
|
if pos < start {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
start_pos := pos + 1
|
||||||
|
|
||||||
|
if s.text[start_pos].is_digit() || end_pos > s.text.len || end_pos <= start_pos || end_pos <= start || start_pos <= start {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
struct_name := s.text[start_pos..end_pos]
|
||||||
|
return struct_name
|
||||||
|
}
|
||||||
|
|
||||||
fn filter_num_sep(txt byteptr, start int, end int) string {
|
fn filter_num_sep(txt byteptr, start int, end int) string {
|
||||||
unsafe{
|
unsafe{
|
||||||
mut b := malloc(end - start + 1) // add a byte for the endstring 0
|
mut b := malloc(end - start + 1) // add a byte for the endstring 0
|
||||||
@ -491,6 +553,7 @@ pub fn (mut s Scanner) scan() token.Token {
|
|||||||
kind := token.key_to_token(name)
|
kind := token.key_to_token(name)
|
||||||
if kind == .key_fn {
|
if kind == .key_fn {
|
||||||
s.fn_name = s.ident_fn_name()
|
s.fn_name = s.ident_fn_name()
|
||||||
|
s.struct_name = s.ident_struct_name()
|
||||||
} else if kind == .key_module {
|
} else if kind == .key_module {
|
||||||
s.mod_name = s.ident_mod_name()
|
s.mod_name = s.ident_mod_name()
|
||||||
}
|
}
|
||||||
@ -676,6 +739,7 @@ pub fn (mut s Scanner) scan() token.Token {
|
|||||||
name := s.ident_name()
|
name := s.ident_name()
|
||||||
// @FN => will be substituted with the name of the current V function
|
// @FN => will be substituted with the name of the current V function
|
||||||
// @MOD => will be substituted with the name of the current V module
|
// @MOD => will be substituted with the name of the current V module
|
||||||
|
// @STRUCT => will be substituted with the name of the current V struct
|
||||||
// @VEXE => will be substituted with the path to the V compiler
|
// @VEXE => will be substituted with the path to the V compiler
|
||||||
// @FILE => will be substituted with the path of the V source file
|
// @FILE => will be substituted with the path of the V source file
|
||||||
// @LINE => will be substituted with the V line number where it appears (as a string).
|
// @LINE => will be substituted with the V line number where it appears (as a string).
|
||||||
@ -690,6 +754,9 @@ pub fn (mut s Scanner) scan() token.Token {
|
|||||||
if name == 'MOD' {
|
if name == 'MOD' {
|
||||||
return s.new_token(.string, s.mod_name, 4)
|
return s.new_token(.string, s.mod_name, 4)
|
||||||
}
|
}
|
||||||
|
if name == 'STRUCT' {
|
||||||
|
return s.new_token(.string, s.struct_name, 7)
|
||||||
|
}
|
||||||
if name == 'VEXE' {
|
if name == 'VEXE' {
|
||||||
vexe := pref.vexe_path()
|
vexe := pref.vexe_path()
|
||||||
return s.new_token(.string, util.cescaped_path(vexe), 5)
|
return s.new_token(.string, util.cescaped_path(vexe), 5)
|
||||||
|
@ -5,6 +5,26 @@ module scanner
|
|||||||
|
|
||||||
import v.token
|
import v.token
|
||||||
|
|
||||||
|
|
||||||
|
struct TestStruct {
|
||||||
|
test string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut t TestStruct) test_struct() {
|
||||||
|
assert @STRUCT == 'TestStruct'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut t TestStruct) test_struct_w_return() string {
|
||||||
|
assert @STRUCT == 'TestStruct'
|
||||||
|
return t.test
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut t TestStruct) test_struct_w_high_order(cb fn(int)string) string {
|
||||||
|
assert @STRUCT == 'TestStruct'
|
||||||
|
return 'test'+cb(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn test_scan() {
|
fn test_scan() {
|
||||||
text := 'println(2 + 3)'
|
text := 'println(2 + 3)'
|
||||||
mut scanner := new_scanner(text, .skip_comments)
|
mut scanner := new_scanner(text, .skip_comments)
|
||||||
@ -41,9 +61,24 @@ fn test_scan() {
|
|||||||
assert 1.23e+10 == 1.23e0010
|
assert 1.23e+10 == 1.23e0010
|
||||||
assert (-1.23e+10) == (1.23e0010 * -1.0)
|
assert (-1.23e+10) == (1.23e0010 * -1.0)
|
||||||
|
|
||||||
// test @MOD
|
// Test @FN
|
||||||
|
assert @FN == 'test_scan'
|
||||||
|
|
||||||
|
// Test @MOD
|
||||||
assert @MOD == 'scanner'
|
assert @MOD == 'scanner'
|
||||||
|
|
||||||
// test @FN
|
// Test @STRUCT
|
||||||
assert @FN == 'test_scan'
|
assert @STRUCT == ''
|
||||||
|
|
||||||
|
ts := TestStruct { test: "test" }
|
||||||
|
ts.test_struct()
|
||||||
|
r1 := ts.test_struct_w_return()
|
||||||
|
r2 := ts.test_struct_w_high_order(fn(i int)string{
|
||||||
|
assert @STRUCT == ''
|
||||||
|
return i.str()
|
||||||
|
})
|
||||||
|
assert r1 == 'test'
|
||||||
|
assert r2 == 'test2'
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user