scanner: fix parsing multiple .amp
parent
af27963938
commit
b3fc462a78
|
@ -505,7 +505,8 @@ pub fn (mut f Fmt) struct_field_expr(fexpr ast.Expr) {
|
|||
|
||||
fn (f &Fmt) type_to_str(t table.Type) string {
|
||||
mut res := f.table.type_to_str(t)
|
||||
if res.ends_with('_ptr') {
|
||||
|
||||
for res.ends_with('_ptr') {
|
||||
// type_ptr => &type
|
||||
res = res[0..res.len - 4]
|
||||
start_pos := 2 * res.count('[]')
|
||||
|
|
|
@ -2,12 +2,18 @@ const (
|
|||
x = &Test{}
|
||||
y = []&Test{}
|
||||
z = &[]&Test{}
|
||||
xx = &&Test{}
|
||||
yy = []&&Test{}
|
||||
zz = &&[]&&Test{}
|
||||
)
|
||||
|
||||
fn test_type_ptr() {
|
||||
_ := &Test{}
|
||||
_ := []&Test{}
|
||||
_ := &[]&Test{}
|
||||
_ := &&Test{}
|
||||
_ := []&&Test{}
|
||||
_ := &&[]&&Test{}
|
||||
}
|
||||
|
||||
struct Test {
|
||||
|
|
|
@ -361,7 +361,7 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool) {
|
|||
mut args := []table.Arg{}
|
||||
mut is_variadic := false
|
||||
// `int, int, string` (no names, just types)
|
||||
types_only := p.tok.kind in [.amp, .and, .ellipsis] || (p.peek_tok.kind == .comma && p.table.known_type(p.tok.lit)) ||
|
||||
types_only := p.tok.kind in [.amp, .ellipsis] || (p.peek_tok.kind == .comma && p.table.known_type(p.tok.lit)) ||
|
||||
p.peek_tok.kind == .rpar
|
||||
// TODO copy pasta, merge 2 branches
|
||||
if types_only {
|
||||
|
|
|
@ -111,12 +111,8 @@ pub fn (mut p Parser) parse_type() table.Type {
|
|||
p.next()
|
||||
}
|
||||
// &Type
|
||||
for p.tok.kind in [.and, .amp] {
|
||||
if p.tok.kind == .and {
|
||||
nr_muls += 2
|
||||
} else {
|
||||
for p.tok.kind == .amp {
|
||||
nr_muls++
|
||||
}
|
||||
p.next()
|
||||
}
|
||||
|
||||
|
|
|
@ -641,6 +641,15 @@ pub fn (mut s Scanner) buffer_scan() token.Token {
|
|||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
fn (s Scanner) look_ahead(n int) byte {
|
||||
if s.pos + n < s.text.len {
|
||||
return s.text[s.pos + n]
|
||||
} else {
|
||||
return `\0`
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut s Scanner) text_scan() token.Token {
|
||||
// if s.comments_mode == .parse_comments {
|
||||
// println('\nscan()')
|
||||
|
@ -676,14 +685,14 @@ fn (mut s Scanner) text_scan() token.Token {
|
|||
}
|
||||
// handle each char
|
||||
c := s.text[s.pos]
|
||||
nextc := if s.pos + 1 < s.text.len { s.text[s.pos + 1] } else { `\0` }
|
||||
nextc := s.look_ahead(1)
|
||||
|
||||
// name or keyword
|
||||
if util.is_name_char(c) {
|
||||
name := s.ident_name()
|
||||
// tmp hack to detect . in ${}
|
||||
// Check if not .eof to prevent panic
|
||||
next_char := if s.pos + 1 < s.text.len { s.text[s.pos + 1] } else { `\0` }
|
||||
next_char := s.look_ahead(1)
|
||||
kind := token.keywords[name]
|
||||
if kind != .unknown {
|
||||
if kind == .key_fn {
|
||||
|
@ -738,7 +747,7 @@ fn (mut s Scanner) text_scan() token.Token {
|
|||
if c == `)` && s.is_inter_start {
|
||||
s.is_inter_end = true
|
||||
s.is_inter_start = false
|
||||
next_char := if s.pos + 1 < s.text.len { s.text[s.pos + 1] } else { `\0` }
|
||||
next_char := s.look_ahead(1)
|
||||
if next_char == s.quote {
|
||||
s.is_inside_string = false
|
||||
}
|
||||
|
@ -849,7 +858,9 @@ fn (mut s Scanner) text_scan() token.Token {
|
|||
s.pos++
|
||||
return s.new_token(.and_assign, '', 2)
|
||||
}
|
||||
if nextc == `&` {
|
||||
|
||||
afternextc := s.look_ahead(2)
|
||||
if nextc == `&` && afternextc.is_space() {
|
||||
s.pos++
|
||||
return s.new_token(.and, '', 2)
|
||||
}
|
||||
|
|
|
@ -44,8 +44,7 @@ fn fn_name_mod_level_high_order(cb fn(int)) {
|
|||
cb(1)
|
||||
}
|
||||
|
||||
fn test_scan() {
|
||||
text := 'println(2 + 3)'
|
||||
fn scan_kinds(text string) []token.Kind {
|
||||
mut scanner := new_scanner(text, .skip_comments)
|
||||
mut token_kinds := []token.Kind{}
|
||||
for {
|
||||
|
@ -55,6 +54,11 @@ fn test_scan() {
|
|||
}
|
||||
token_kinds << tok.kind
|
||||
}
|
||||
return token_kinds
|
||||
}
|
||||
|
||||
fn test_scan() {
|
||||
token_kinds := scan_kinds('println(2 + 3)')
|
||||
assert token_kinds.len == 6
|
||||
assert token_kinds[0] == .name
|
||||
assert token_kinds[1] == .lpar
|
||||
|
@ -122,3 +126,55 @@ fn test_vmod_file() {
|
|||
assert content.contains('version:')
|
||||
assert content.contains('description:')
|
||||
}
|
||||
|
||||
fn test_reference() {
|
||||
mut result := scan_kinds('true && false')
|
||||
assert result.len == 3
|
||||
assert result[0] == .key_true
|
||||
assert result[1] == .and
|
||||
assert result[2] == .key_false
|
||||
|
||||
result = scan_kinds('&foo')
|
||||
assert result.len == 2
|
||||
assert result[0] == .amp
|
||||
assert result[1] == .name
|
||||
|
||||
result = scan_kinds('[]&foo')
|
||||
assert result.len == 4
|
||||
assert result[0] == .lsbr
|
||||
assert result[1] == .rsbr
|
||||
assert result[2] == .amp
|
||||
assert result[3] == .name
|
||||
|
||||
result = scan_kinds('&[]&foo')
|
||||
assert result.len == 5
|
||||
assert result[0] == .amp
|
||||
assert result[1] == .lsbr
|
||||
assert result[2] == .rsbr
|
||||
assert result[3] == .amp
|
||||
assert result[4] == .name
|
||||
|
||||
result = scan_kinds('&&foo')
|
||||
assert result.len == 3
|
||||
assert result[0] == .amp
|
||||
assert result[1] == .amp
|
||||
assert result[2] == .name
|
||||
|
||||
result = scan_kinds('[]&&foo')
|
||||
assert result.len == 5
|
||||
assert result[0] == .lsbr
|
||||
assert result[1] == .rsbr
|
||||
assert result[2] == .amp
|
||||
assert result[3] == .amp
|
||||
assert result[4] == .name
|
||||
|
||||
result = scan_kinds('&&[]&&foo')
|
||||
assert result.len == 7
|
||||
assert result[0] == .amp
|
||||
assert result[1] == .amp
|
||||
assert result[2] == .lsbr
|
||||
assert result[3] == .rsbr
|
||||
assert result[4] == .amp
|
||||
assert result[5] == .amp
|
||||
assert result[6] == .name
|
||||
}
|
||||
|
|
|
@ -274,7 +274,7 @@ pub fn (t &Table) known_type(name string) bool {
|
|||
pub fn (t &Table) array_name(elem_type Type, nr_dims int) string {
|
||||
elem_type_sym := t.get_type_symbol(elem_type)
|
||||
return 'array_${elem_type_sym.name}' + if elem_type.is_ptr() {
|
||||
'_ptr'
|
||||
'_ptr'.repeat(elem_type.nr_muls())
|
||||
} else {
|
||||
''
|
||||
} + if nr_dims > 1 {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
fn process(foo &&int) int {
|
||||
return **foo
|
||||
}
|
||||
|
||||
fn test_ref_deref() {
|
||||
foo := 12
|
||||
bar := &foo
|
||||
fiz := process(&bar)
|
||||
assert fiz == 12
|
||||
}
|
Loading…
Reference in New Issue