(prog *syntax.Prog)
| 19 | ) |
| 20 | |
| 21 | func toByteProg(prog *syntax.Prog) error { |
| 22 | var b runeBuilder |
| 23 | for pc := range prog.Inst { |
| 24 | i := &prog.Inst[pc] |
| 25 | switch i.Op { |
| 26 | case syntax.InstRune, syntax.InstRune1: |
| 27 | // General rune range. PIA. |
| 28 | // TODO: Pick off single-byte case. |
| 29 | if lo, hi, fold, ok := oneByteRange(i); ok { |
| 30 | i.Op = instByteRange |
| 31 | i.Arg = uint32(lo)<<8 | uint32(hi) |
| 32 | if fold { |
| 33 | i.Arg |= argFold |
| 34 | } |
| 35 | break |
| 36 | } |
| 37 | |
| 38 | r := i.Rune |
| 39 | if syntax.Flags(i.Arg)&syntax.FoldCase != 0 { |
| 40 | // Build folded list. |
| 41 | var rr []rune |
| 42 | if len(r) == 1 { |
| 43 | rr = appendFoldedRange(rr, r[0], r[0]) |
| 44 | } else { |
| 45 | for j := 0; j < len(r); j += 2 { |
| 46 | rr = appendFoldedRange(rr, r[j], r[j+1]) |
| 47 | } |
| 48 | } |
| 49 | r = rr |
| 50 | } |
| 51 | |
| 52 | b.init(prog, uint32(pc), i.Out) |
| 53 | if len(r) == 1 { |
| 54 | b.addRange(r[0], r[0], false) |
| 55 | } else { |
| 56 | for j := 0; j < len(r); j += 2 { |
| 57 | b.addRange(r[j], r[j+1], false) |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | case syntax.InstRuneAny, syntax.InstRuneAnyNotNL: |
| 62 | // All runes. |
| 63 | // AnyNotNL should exclude \n but the line-at-a-time |
| 64 | // execution takes care of that for us. |
| 65 | b.init(prog, uint32(pc), i.Out) |
| 66 | b.addRange(0, unicode.MaxRune, false) |
| 67 | } |
| 68 | } |
| 69 | return nil |
| 70 | } |
| 71 | |
| 72 | func oneByteRange(i *syntax.Inst) (lo, hi byte, fold, ok bool) { |
| 73 | if i.Op == syntax.InstRune1 { |
no test coverage detected
searching dependent graphs…