diff --git a/gg/v2/location.go b/gg/v2/location.go index 73a0047..a1de1aa 100644 --- a/gg/v2/location.go +++ b/gg/v2/location.go @@ -25,10 +25,6 @@ func (e LocatedError) Error() string { return fmt.Sprintf("%d:%d: %v", e.Row, e.Col, e.Err) } -type locatable interface { - locate() Location -} - type locatableRune struct { Location r rune @@ -38,12 +34,3 @@ type locatableString struct { Location str string } - -type locatableSlice[T locatable] []T - -func (s locatableSlice[T]) locate() Location { - if len(s) == 0 { - panic("can't locate empty locatableSlice") - } - return s[0].locate() -} diff --git a/gg/v2/term.go b/gg/v2/term.go index 5cb8c08..aef98fa 100644 --- a/gg/v2/term.go +++ b/gg/v2/term.go @@ -28,11 +28,7 @@ func (str stringerStr) String() string { return string(str) } -// TODO in the end I don't think locatable is actually needed here... I think -// seq is the only place where locating anything is required generally, and -// that's done using Decoder.nextLoc. Otherwise the Location is used when -// constructing Value's, which only really requires runes to be locatable. -type term[T locatable] struct { +type term[T any] struct { name fmt.Stringer decodeFn func(d *Decoder) (T, error) } @@ -41,7 +37,7 @@ func (t term[T]) String() string { return t.name.String() } -func firstOf[T locatable](terms ...*term[T]) *term[T] { +func firstOf[T any](terms ...*term[T]) *term[T] { if len(terms) < 2 { panic("firstOfTerms requires at least 2 terms") } @@ -72,11 +68,11 @@ func firstOf[T locatable](terms ...*term[T]) *term[T] { } } -func seq[Ta, Tb, Tc locatable]( +func seq[Ta, Tb, Tc any]( name fmt.Stringer, termA *term[Ta], termB *term[Tb], - fn func(Ta, Tb) (Tc, error), // TODO probably don't need error return + fn func(Ta, Tb) Tc, ) *term[Tc] { return &term[Tc]{ name: name, @@ -95,30 +91,25 @@ func seq[Ta, Tb, Tc locatable]( return zero, err } - vc, err := fn(va, vb) - if err != nil { - return zero, err - } - - return vc, nil + return fn(va, vb), nil }, } } -func matchAndSkip[Ta, Tb locatable]( +func matchAndSkip[Ta, Tb any]( termA *term[Ta], termB *term[Tb], ) *term[Tb] { - return seq(termA, termA, termB, func(_ Ta, b Tb) (Tb, error) { - return b, nil + return seq(termA, termA, termB, func(_ Ta, b Tb) Tb { + return b }) } -func oneOrMore[T locatable](t *term[T]) *term[locatableSlice[T]] { - return &term[locatableSlice[T]]{ +func oneOrMore[T any](t *term[T]) *term[[]T] { + return &term[[]T]{ name: stringerFn(func() string { return fmt.Sprintf("one or more %v", t) }), - decodeFn: func(d *Decoder) (locatableSlice[T], error) { + decodeFn: func(d *Decoder) ([]T, error) { var vv []T for { v, err := t.decodeFn(d) @@ -140,12 +131,12 @@ func oneOrMore[T locatable](t *term[T]) *term[locatableSlice[T]] { } } -func zeroOrMore[T locatable](t *term[T]) *term[locatableSlice[T]] { - return &term[locatableSlice[T]]{ +func zeroOrMore[T any](t *term[T]) *term[[]T] { + return &term[[]T]{ name: stringerFn(func() string { return fmt.Sprintf("zero or more %v", t) }), - decodeFn: func(d *Decoder) (locatableSlice[T], error) { + decodeFn: func(d *Decoder) ([]T, error) { var vv []T for { v, err := t.decodeFn(d) @@ -163,7 +154,7 @@ func zeroOrMore[T locatable](t *term[T]) *term[locatableSlice[T]] { } } -func mapTerm[Ta locatable, Tb locatable]( +func mapTerm[Ta, Tb any]( name fmt.Stringer, t *term[Ta], fn func(Ta) Tb, ) *term[Tb] { return &term[Tb]{ @@ -209,7 +200,7 @@ func runeTerm(r rune) *term[locatableRune] { ) } -func locatableRunesToString(rr locatableSlice[locatableRune]) string { +func locatableRunesToString(rr []locatableRune) string { str := make([]rune, len(rr)) for i := range rr { str[i] = rr[i].r @@ -218,11 +209,11 @@ func locatableRunesToString(rr locatableSlice[locatableRune]) string { } func runesToStringTerm( - t *term[locatableSlice[locatableRune]], + t *term[[]locatableRune], ) *term[locatableString] { return mapTerm( - t, t, func(rr locatableSlice[locatableRune]) locatableString { - return locatableString{rr.locate(), locatableRunesToString(rr)} + t, t, func(rr []locatableRune) locatableString { + return locatableString{rr[0].locate(), locatableRunesToString(rr)} }, ) } @@ -239,10 +230,8 @@ var ( stringerStr("negative-number"), runeTerm('-'), positiveNumberTerm, - func(neg locatableRune, posNum locatableString) (locatableString, error) { - return locatableString{ - neg.locate(), string(neg.r) + posNum.str, - }, nil + func(neg locatableRune, posNum locatableString) locatableString { + return locatableString{neg.locate(), string(neg.r) + posNum.str} }, ) @@ -274,9 +263,9 @@ var ( stringerStr("name"), letterTerm, letterTailTerm, - func(head locatableRune, tail locatableSlice[locatableRune]) (Value, error) { + func(head locatableRune, tail []locatableRune) Value { name := string(head.r) + locatableRunesToString(tail) - return Value{Name: &name, Location: head.locate()}, nil + return Value{Name: &name, Location: head.locate()} }, ) ) @@ -293,21 +282,14 @@ func openEdgeIntoValue(val Value, oe *OpenEdge) *OpenEdge { } var graphTerm = func() *term[Value] { - type locatableOpenEdge struct { - Location - oe *OpenEdge - } - type tupleState struct { - Location // location of last place tupleState was updated - ins []*OpenEdge - oe *OpenEdge + ins []*OpenEdge + oe *OpenEdge } type graphState struct { - Location // location of last place graphState was updated - g *Graph - oe *OpenEdge + g *Graph + oe *OpenEdge } var ( @@ -318,7 +300,7 @@ var graphTerm = func() *term[Value] { func(lr locatableRune) tupleState { // if ')', then map that to an empty state. This acts as a // sentinel value to indicate "end of tuple". - return tupleState{Location: lr.locate()} + return tupleState{} }, ) @@ -329,7 +311,7 @@ var graphTerm = func() *term[Value] { func(lr locatableRune) graphState { // if '}', then map that to an empty state. This acts as a // sentinel value to indicate "end of graph". - return graphState{Location: lr.locate()} + return graphState{} }, ) ) @@ -339,7 +321,7 @@ var graphTerm = func() *term[Value] { // deal with recursive dependencies between them. valueTerm = new(term[Value]) - tupleTerm = new(term[locatableOpenEdge]) + tupleTerm = new(term[*OpenEdge]) tupleTailTerm = new(term[tupleState]) tupleOpenEdgeTerm = new(term[tupleState]) tupleOpenEdgeTailTerm = new(term[tupleState]) @@ -355,13 +337,9 @@ var graphTerm = func() *term[Value] { stringerStr("tuple"), runeTerm('('), tupleTailTerm, - func(lr locatableRune, ts tupleState) (locatableOpenEdge, error) { + func(lr locatableRune, ts tupleState) *OpenEdge { slices.Reverse(ts.ins) - oe := graph.TupleOut(None, ts.ins...) - return locatableOpenEdge{ - Location: lr.locate(), - oe: oe, - }, nil + return graph.TupleOut(None, ts.ins...) }, ) @@ -382,10 +360,9 @@ var graphTerm = func() *term[Value] { valueTerm, valueTerm, tupleOpenEdgeTailTerm, - func(val Value, ts tupleState) (tupleState, error) { + func(val Value, ts tupleState) tupleState { ts.oe = openEdgeIntoValue(val, ts.oe) - ts.Location = val.locate() - return ts, nil + return ts }, ) @@ -399,12 +376,12 @@ var graphTerm = func() *term[Value] { stringerStr("graph"), runeTerm('{'), graphTailTerm, - func(lr locatableRune, gs graphState) (Value, error) { + func(lr locatableRune, gs graphState) Value { if gs.g == nil { gs.g = new(Graph) } - return Value{Graph: gs.g, Location: lr.locate()}, nil + return Value{Graph: gs.g, Location: lr.locate()} }, ) @@ -414,15 +391,14 @@ var graphTerm = func() *term[Value] { nameTerm, nameTerm, matchAndSkip(runeTerm('='), graphOpenEdgeTerm), - func(name Value, gs graphState) (graphState, error) { + func(name Value, gs graphState) graphState { if gs.g == nil { gs.g = new(Graph) } gs.g = gs.g.AddValueIn(name, gs.oe) gs.oe = nil - gs.Location = name.locate() - return gs, nil + return gs }, ), ) @@ -432,20 +408,18 @@ var graphTerm = func() *term[Value] { valueTerm, valueTerm, graphOpenEdgeValueTailTerm, - func(val Value, gs graphState) (graphState, error) { + func(val Value, gs graphState) graphState { gs.oe = openEdgeIntoValue(val, gs.oe) - gs.Location = val.locate() - return gs, nil + return gs }, ), seq( tupleTerm, tupleTerm, graphOpenEdgeTailTerm, - func(loe locatableOpenEdge, gs graphState) (graphState, error) { - gs.oe = loe.oe - gs.Location = loe.locate() - return gs, nil + func(oe *OpenEdge, gs graphState) graphState { + gs.oe = oe + return gs }, ), )