Skip to content

Commit 4a37d6c

Browse files
authored
Add helper for converting token IDs to indexes (#436)
Adds a helper method index to convert an ID into it's index representation for improved readability. This is a follow up to #429.
1 parent 0fe48ab commit 4a37d6c

File tree

3 files changed

+32
-9
lines changed

3 files changed

+32
-9
lines changed

experimental/token/cursor.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func NewCursorAt(tok Token) *Cursor {
5959

6060
return &Cursor{
6161
withContext: tok.withContext,
62-
idx: int(tok.ID() - 1), // Convert to 0-based index.
62+
idx: tok.ID().naturalIndex(), // Convert to 0-based index.
6363
}
6464
}
6565

@@ -178,7 +178,7 @@ func (c *Cursor) PrevSkippable() Token {
178178
if c.IsSynthetic() {
179179
c.idx--
180180
} else {
181-
c.idx = int(tok.ID() - 1)
181+
c.idx = tok.ID().naturalIndex()
182182
}
183183
return tok
184184
}

experimental/token/raw.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,35 @@ func (t ID) String() string {
5555
return "Token(<nil>)"
5656
}
5757
if t < 0 {
58-
return fmt.Sprintf("Token(^%d)", ^int(t))
58+
return fmt.Sprintf("Token(%d)", t.syntheticIndex())
5959
}
60+
return fmt.Sprintf("Token(%d)", t.naturalIndex())
61+
}
62+
63+
// naturalIndex returns the index of this token in the natural stream.
64+
func (t ID) naturalIndex() int {
65+
if t.IsZero() {
66+
panic("protocompile/token: called naturalIndex on zero token")
67+
}
68+
if t < 0 {
69+
panic("protocompile/token: called naturalIndex on synthetic token")
70+
}
71+
// Need to subtract off one, because the zeroth
72+
// ID is used as a "missing" sentinel.
73+
return int(t) - 1
74+
}
6075

61-
return fmt.Sprintf("Token(%d)", int(t)-1)
76+
// syntheticIndex returns the index of this token in the synthetic stream.
77+
func (t ID) syntheticIndex() int {
78+
if t.IsZero() {
79+
panic("protocompile/token: called syntheticIndex on zero token")
80+
}
81+
if t > 0 {
82+
panic("protocompile/token: called syntheticIndex on natural token")
83+
}
84+
// Need to invert the bits, because synthetic tokens are
85+
// stored as negative numbers.
86+
return ^int(t)
6287
}
6388

6489
// Constants for extracting the parts of tokenImpl.kindAndOffset.

experimental/token/token.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ func (t Token) Children() *Cursor {
325325
start, _ := t.StartEnd()
326326
return &Cursor{
327327
withContext: t.withContext,
328-
idx: int(start.id), // Skip the start!
328+
idx: start.id.naturalIndex() + 1, // Skip the start!
329329
}
330330
}
331331

@@ -497,14 +497,12 @@ func (t Token) nat() *nat {
497497
if t.IsSynthetic() {
498498
return nil
499499
}
500-
// Need to subtract off one, because the zeroth
501-
// ID is used as a "missing" sentinel.
502-
return &t.Context().Stream().nats[t.id-1]
500+
return &t.Context().Stream().nats[t.id.naturalIndex()]
503501
}
504502

505503
func (t Token) synth() *synth {
506504
if !t.IsSynthetic() {
507505
return nil
508506
}
509-
return &t.Context().Stream().synths[^t.id]
507+
return &t.Context().Stream().synths[t.id.syntheticIndex()]
510508
}

0 commit comments

Comments
 (0)