v2 / vlib / v / parser / lock.v
58 lines · 56 sloc · 1.16 KB · 717aad4072b1c68d2c0fb8786270c0b86f6f5514
Raw
1module parser
2
3import v.ast
4
5fn (mut p Parser) lock_expr() ast.LockExpr {
6 // TODO: Handle aliasing sync
7 p.register_auto_import('sync')
8 p.open_scope()
9 defer {
10 p.close_scope()
11 }
12 mut pos := p.tok.pos()
13 mut lockeds := []ast.Expr{}
14 mut is_rlocked := []bool{}
15 for {
16 is_rlock := p.tok.kind == .key_rlock
17 if !is_rlock && p.tok.kind != .key_lock {
18 p.unexpected(expecting: 'one or more shared variable names')
19 return ast.LockExpr{
20 pos: pos
21 scope: p.scope
22 }
23 }
24 p.next()
25 if p.tok.kind == .lcbr {
26 break
27 }
28 if p.tok.kind == .name {
29 p.inside_lock_exprs = true
30 exprs := p.expr_list(true)
31 p.inside_lock_exprs = false
32 for e in exprs {
33 if !e.is_lockable() {
34 p.error_with_pos('`${e}` cannot be locked - only `x`, `x.y`, `x.$(y)` or `x[i]` are supported',
35 e.pos())
36 }
37 lockeds << e
38 is_rlocked << is_rlock
39 }
40 }
41 if p.tok.kind == .lcbr {
42 break
43 }
44 if p.tok.kind == .semicolon {
45 p.next()
46 }
47 }
48 stmts := p.parse_block_no_scope(false)
49 scope := p.scope
50 pos.update_last_line(p.prev_tok.line_nr)
51 return ast.LockExpr{
52 lockeds: lockeds
53 stmts: stmts
54 is_rlock: is_rlocked
55 pos: pos
56 scope: scope
57 }
58}
59