package flowclass import ( "bytes" "fmt" "idio.link/go/parser" ) type fcVector[A parser.ASTNode, _ any] struct { dim int newToken func() A } func (t fcVector[_, _]) Shift(sm *parser.SM, e rune) error { length := len(sm.Top().Nodes) if length == 0 { return sm.Push(t.newToken()).Shift(sm, e) } switch e { case ' ', ')': case ',': if length == t.dim { return fmt.Errorf("vector: too many components") } sm.Push(t.newToken()) default: return parser.NewUnrecognized("vector", e) } return nil } func (t fcVector[_, B]) Coalesce(nodes []*parser.CSTNode) any { col := make([]B, 0, 8) for _, e := range nodes { col = append(col, e.Coalesce().(B)) } return col } func (t fcVector[_, _]) Value() *bytes.Buffer { return nil } type fcSet[A parser.ASTNode, _ fmt.Stringer] struct { newToken func() A } func (t fcSet[_, _]) Shift(sm *parser.SM, e rune) error { switch { case e == ' ': case e == ',': case e == '}': case isAlpha(e) || isDigit(e): return sm.Push(t.newToken()).Shift(sm, e) default: if len(sm.Top().Nodes) == 0 { return fmt.Errorf("set: cannot be the empty set") } return parser.NewUnrecognized("set", e) } return nil } func (t fcSet[_, B]) Coalesce(nodes []*parser.CSTNode) any { col := make(map[string]B) for _, e := range nodes { tmp := e.Coalesce().(B) col[tmp.String()] = tmp } return col } func (t fcSet[_, _]) Value() *bytes.Buffer { return nil }