1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
9 // This file contains tables and code related to context rules.
14 // These bits, once set depending on the current value, are never unset.
15 bJapanese catBitmap = 1 << iota
17 bExtendedArabicIndicDigit
19 // These bits are set on each iteration depending on the current value.
28 // These bits indicated which of the permanent bits need to be set at the
32 permanent = bJapanese | bArabicIndicDigit | bExtendedArabicIndicDigit | bMustHaveJapn
37 var errContext = errors.New("precis: contextual rule violated")
40 // Programmatically set these required bits as, manually setting them seems
42 for i, ct := range categoryTransitions {
43 categoryTransitions[i].keep |= permanent
44 categoryTransitions[i].accept |= ct.term
48 var categoryTransitions = []struct {
49 keep catBitmap // mask selecting which bits to keep from the previous state
50 set catBitmap // mask for which bits to set for this transition
52 // These bitmaps are used for rules that require lookahead.
53 // term&accept == term must be true, which is enforced programmatically.
54 term catBitmap // bits accepted as termination condition
55 accept catBitmap // bits that pass, but not sufficient as termination
57 // The rule function cannot take a *context as an argument, as it would
58 // cause the context to escape, adding significant overhead.
59 rule func(beforeBits catBitmap) (doLookahead bool, err error)
61 joiningL: {set: bJoinStart},
62 joiningD: {set: bJoinStart | bJoinEnd},
63 joiningT: {keep: bJoinStart, set: bJoinMid},
64 joiningR: {set: bJoinEnd},
65 viramaModifier: {set: bVirama},
66 viramaJoinT: {set: bVirama | bJoinMid},
67 latinSmallL: {set: bLatinSmallL},
69 greekJoinT: {set: bGreek | bJoinMid},
70 hebrew: {set: bHebrew},
71 hebrewJoinT: {set: bHebrew | bJoinMid},
72 japanese: {set: bJapanese},
73 katakanaMiddleDot: {set: bMustHaveJapn},
78 rule: func(before catBitmap) (doLookAhead bool, err error) {
79 if before&bVirama != 0 {
82 if before&bJoinStart == 0 {
83 return false, errContext
89 rule: func(before catBitmap) (doLookAhead bool, err error) {
90 if before&bVirama == 0 {
98 rule: func(before catBitmap) (doLookAhead bool, err error) {
99 if before&bLatinSmallL == 0 {
100 return false, errContext
105 greekLowerNumeralSign: {
108 rule: func(before catBitmap) (doLookAhead bool, err error) {
114 rule: func(before catBitmap) (doLookAhead bool, err error) {
115 if before&bHebrew == 0 {
122 set: bArabicIndicDigit,
123 rule: func(before catBitmap) (doLookAhead bool, err error) {
124 if before&bExtendedArabicIndicDigit != 0 {
130 extendedArabicIndicDigit: {
131 set: bExtendedArabicIndicDigit,
132 rule: func(before catBitmap) (doLookAhead bool, err error) {
133 if before&bArabicIndicDigit != 0 {