| 1 | module build_constraint |
| 2 | |
| 3 | // parsing: |
| 4 | struct BParser { |
| 5 | tokens []Token |
| 6 | mut: |
| 7 | pos int |
| 8 | } |
| 9 | |
| 10 | fn (mut p BParser) peek(n int) Token { |
| 11 | if p.pos + n >= p.tokens.len { |
| 12 | return Token{ |
| 13 | kind: .teof |
| 14 | } |
| 15 | } |
| 16 | t := p.tokens[p.pos + n] |
| 17 | return t |
| 18 | } |
| 19 | |
| 20 | fn (mut p BParser) next() { |
| 21 | p.pos++ |
| 22 | } |
| 23 | |
| 24 | fn (mut p BParser) parse() !BExpr { |
| 25 | return p.expr() |
| 26 | } |
| 27 | |
| 28 | fn (mut p BParser) expr() !BExpr { |
| 29 | return BExpr{ |
| 30 | expr: p.or_expr()! |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | fn (mut p BParser) or_expr() !BOr { |
| 35 | mut exprs := []BAnd{} |
| 36 | exprs << p.and_expr()! |
| 37 | for t := p.peek(0); t.kind == .tor; t = p.peek(0) { |
| 38 | p.next() |
| 39 | exprs << p.and_expr()! |
| 40 | } |
| 41 | return BOr{ |
| 42 | exprs: exprs |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | fn (mut p BParser) and_expr() !BAnd { |
| 47 | mut exprs := []BUnary{} |
| 48 | exprs << p.unary_expr()! |
| 49 | for t := p.peek(0); t.kind == .tand; t = p.peek(0) { |
| 50 | p.next() |
| 51 | exprs << p.unary_expr()! |
| 52 | } |
| 53 | return BAnd{ |
| 54 | exprs: exprs |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | fn (mut p BParser) unary_expr() !BUnary { |
| 59 | t := p.peek(0) |
| 60 | match t.kind { |
| 61 | .tfact { |
| 62 | p.next() |
| 63 | return BUnary(BFact(t.value)) |
| 64 | } |
| 65 | .tdefine { |
| 66 | p.next() |
| 67 | return BUnary(BDefine(t.value)) |
| 68 | } |
| 69 | .tnot { |
| 70 | p.next() |
| 71 | nt := p.peek(0) |
| 72 | if nt.kind in [.tfact, .tdefine] { |
| 73 | ident := p.unary_expr()! |
| 74 | return BNot{ |
| 75 | expr: ident |
| 76 | } |
| 77 | } |
| 78 | expr := p.expr()! |
| 79 | return BNot{ |
| 80 | expr: expr |
| 81 | } |
| 82 | } |
| 83 | .tparen_open { |
| 84 | p.next() |
| 85 | expr := p.expr()! |
| 86 | if p.peek(0).kind != .tparen_close { |
| 87 | return error('expected closing )') |
| 88 | } |
| 89 | p.next() |
| 90 | return BUnary(expr) |
| 91 | } |
| 92 | else {} |
| 93 | } |
| 94 | |
| 95 | return error('unary failed, unexpected ${t}') |
| 96 | } |
| 97 | |