Skip to content

Commit 8f17139

Browse files
authored
v.parser: split parser methods to files based on topic (#24786)
1 parent aed5807 commit 8f17139

File tree

8 files changed

+1923
-1885
lines changed

8 files changed

+1923
-1885
lines changed

vlib/v/parser/asm.v

Lines changed: 665 additions & 0 deletions
Large diffs are not rendered by default.

vlib/v/parser/attribute.v

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
module parser
2+
3+
import v.ast
4+
import v.token
5+
6+
fn (mut p Parser) parse_attr(is_at bool) ast.Attr {
7+
mut kind := ast.AttrKind.plain
8+
p.inside_attr_decl = true
9+
defer {
10+
p.inside_attr_decl = false
11+
}
12+
apos := if is_at { p.peek_token(-2).pos() } else { p.prev_tok.pos() }
13+
if p.tok.kind == .key_unsafe {
14+
p.next()
15+
return ast.Attr{
16+
name: 'unsafe'
17+
kind: kind
18+
pos: apos.extend(p.tok.pos())
19+
has_at: is_at
20+
}
21+
}
22+
mut name := ''
23+
mut has_arg := false
24+
mut arg := ''
25+
mut comptime_cond := ast.empty_expr
26+
mut comptime_cond_opt := false
27+
if p.tok.kind == .key_if {
28+
kind = .comptime_define
29+
p.next()
30+
p.comptime_if_cond = true
31+
p.inside_if_expr = true
32+
p.inside_ct_if_expr = true
33+
comptime_cond = p.expr(0)
34+
p.comptime_if_cond = false
35+
p.inside_if_expr = false
36+
p.inside_ct_if_expr = false
37+
if comptime_cond is ast.PostfixExpr {
38+
comptime_cond_opt = true
39+
}
40+
name = comptime_cond.str()
41+
} else if p.tok.kind == .string {
42+
name = p.tok.lit
43+
kind = .string
44+
p.next()
45+
} else {
46+
name = p.check_name()
47+
// support dot prefix `module.name: arg`
48+
if p.tok.kind == .dot {
49+
p.next()
50+
name += '.'
51+
name += p.check_name()
52+
}
53+
if p.tok.kind == .colon {
54+
has_arg = true
55+
p.next()
56+
if p.tok.kind == .name { // `name: arg`
57+
kind = .plain
58+
arg = p.check_name()
59+
} else if p.tok.kind == .number { // `name: 123`
60+
kind = .number
61+
arg = p.tok.lit
62+
p.next()
63+
} else if p.tok.kind == .string { // `name: 'arg'`
64+
kind = .string
65+
arg = p.tok.lit
66+
p.next()
67+
} else if p.tok.kind == .key_true || p.tok.kind == .key_false { // `name: true`
68+
kind = .bool
69+
arg = p.tok.kind.str()
70+
p.next()
71+
} else if token.is_key(p.tok.lit) { // // `name: keyword`
72+
kind = .plain
73+
arg = p.check_name()
74+
} else {
75+
p.unexpected(additional_msg: 'an argument is expected after `:`')
76+
}
77+
}
78+
}
79+
return ast.Attr{
80+
name: name
81+
has_arg: has_arg
82+
arg: arg
83+
kind: kind
84+
ct_expr: comptime_cond
85+
ct_opt: comptime_cond_opt
86+
pos: apos.extend(p.tok.pos())
87+
has_at: is_at
88+
}
89+
}
90+
91+
fn (mut p Parser) is_attributes() bool {
92+
if p.tok.kind != .lsbr {
93+
return false
94+
}
95+
mut i := 0
96+
for {
97+
tok := p.peek_token(i)
98+
if tok.kind == .eof || tok.line_nr != p.tok.line_nr {
99+
return false
100+
}
101+
if tok.kind == .rsbr {
102+
break
103+
}
104+
i++
105+
}
106+
peek_rsbr_tok := p.peek_token(i + 1)
107+
if peek_rsbr_tok.line_nr == p.tok.line_nr && peek_rsbr_tok.kind != .rcbr {
108+
return false
109+
}
110+
return true
111+
}
112+
113+
// when is_top_stmt is true, attrs are added to p.attrs
114+
fn (mut p Parser) attributes() {
115+
start_pos := p.tok.pos()
116+
mut is_at := false
117+
if p.tok.kind == .lsbr {
118+
if p.pref.is_fmt {
119+
} else {
120+
p.error('`[attr]` has been deprecated, use `@[attr]` instead')
121+
}
122+
// [attr]
123+
p.check(.lsbr)
124+
} else if p.tok.kind == .at {
125+
// @[attr]
126+
p.check(.at)
127+
p.check(.lsbr)
128+
is_at = true
129+
}
130+
mut has_ctdefine := false
131+
for p.tok.kind != .rsbr {
132+
attr_start_pos := p.tok.pos()
133+
attr := p.parse_attr(is_at)
134+
if p.attrs.contains(attr.name) && attr.name != 'wasm_export' {
135+
p.error_with_pos('duplicate attribute `${attr.name}`', attr_start_pos.extend(p.prev_tok.pos()))
136+
return
137+
}
138+
if attr.kind == .comptime_define {
139+
if has_ctdefine {
140+
p.error_with_pos('only one `[if flag]` may be applied at a time `${attr.name}`',
141+
attr_start_pos.extend(p.prev_tok.pos()))
142+
return
143+
} else {
144+
has_ctdefine = true
145+
}
146+
}
147+
p.attrs << attr
148+
if p.tok.kind != .semicolon {
149+
if p.tok.kind == .rsbr {
150+
p.next()
151+
break
152+
}
153+
p.unexpected(expecting: '`;`')
154+
return
155+
}
156+
p.next()
157+
}
158+
if p.attrs.len == 0 {
159+
p.error_with_pos('attributes cannot be empty', start_pos.extend(p.tok.pos()))
160+
return
161+
}
162+
// TODO: remove when old attr syntax is removed
163+
if p.inside_struct_attr_decl && p.tok.kind == .lsbr {
164+
p.error_with_pos('multiple attributes should be in the same [], with ; separators',
165+
p.prev_tok.pos().extend(p.tok.pos()))
166+
return
167+
} else if p.inside_struct_attr_decl && p.tok.kind == .at {
168+
p.error_with_pos('multiple attributes should be in the same @[], with ; separators',
169+
p.prev_tok.pos().extend(p.tok.pos()))
170+
return
171+
}
172+
}

0 commit comments

Comments
 (0)