|
|
@ -7,16 +7,26 @@ import (
|
|
|
|
|
|
|
|
|
|
|
|
type fieldPath struct {
|
|
|
|
type fieldPath struct {
|
|
|
|
// slice of values, to be reused over and over
|
|
|
|
// slice of values, to be reused over and over
|
|
|
|
vals []int
|
|
|
|
vals [6]int
|
|
|
|
|
|
|
|
|
|
|
|
// index of the last valid value. e.g., the head of the stack.
|
|
|
|
// index of the last valid value. e.g., the head of the stack.
|
|
|
|
last int
|
|
|
|
last int
|
|
|
|
|
|
|
|
|
|
|
|
history [][]int
|
|
|
|
// history of fieldpath values. that is, all selections thus far.
|
|
|
|
|
|
|
|
// Everything is fixed width to avoid allocations as much as possible
|
|
|
|
|
|
|
|
// inside of the fieldpath stuff. history lengths are known to go over 500,
|
|
|
|
|
|
|
|
// but I honestly have no idea if there is or isn't a limit. this is a
|
|
|
|
|
|
|
|
// hazard.
|
|
|
|
|
|
|
|
history [1024][7]int
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// last valid index of a history entry
|
|
|
|
|
|
|
|
hlast int
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func newFieldPath() *fieldPath {
|
|
|
|
func newFieldPath() *fieldPath {
|
|
|
|
f := &fieldPath{vals: make([]int, 32)}
|
|
|
|
f := new(fieldPath)
|
|
|
|
f.vals[f.last] = -1
|
|
|
|
f.vals[f.last] = -1
|
|
|
|
|
|
|
|
f.hlast = -1
|
|
|
|
return f
|
|
|
|
return f
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -50,11 +60,29 @@ func (f *fieldPath) read(br bit.Reader, n node, class *Class) error {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn(f, br)
|
|
|
|
fn(f, br)
|
|
|
|
Debug.Printf("fieldpath: %v", f.path())
|
|
|
|
Debug.Printf("fieldpath: %v", f.path())
|
|
|
|
// Debug.Printf("fieldpath: %v", f.getField(class))
|
|
|
|
f.keep()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// adds our current vals to the history list.
|
|
|
|
|
|
|
|
// a history list entry is an array of ints, 7 ints wide. a fieldPath value is
|
|
|
|
|
|
|
|
// 6 ints wide. a history value encodes the number of valid entries in its
|
|
|
|
|
|
|
|
// first position. e.g., this:
|
|
|
|
|
|
|
|
// [0 0 0 0 0 0 0]
|
|
|
|
|
|
|
|
// would indicate the selection [0]
|
|
|
|
|
|
|
|
// [0 4 0 0 0 0 0]
|
|
|
|
|
|
|
|
// would indicate the selection [4]
|
|
|
|
|
|
|
|
// [1 4 2 0 0 0 0]
|
|
|
|
|
|
|
|
// would indicate the selection [4 2]
|
|
|
|
|
|
|
|
func (f *fieldPath) keep() {
|
|
|
|
|
|
|
|
f.hlast++
|
|
|
|
|
|
|
|
f.history[f.hlast][0] = f.last
|
|
|
|
|
|
|
|
for i := 0; i <= f.last; i++ {
|
|
|
|
|
|
|
|
f.history[f.hlast][i+1] = f.vals[i]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (f *fieldPath) getField(class *Class) *Field {
|
|
|
|
func (f *fieldPath) getField(class *Class) *Field {
|
|
|
|
if f.last > 0 {
|
|
|
|
if f.last > 0 {
|
|
|
|
for i := 0; i < f.last; i++ {
|
|
|
|
for i := 0; i < f.last; i++ {
|
|
|
|