aggregates.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package flowclass
  2. import (
  3. "bytes"
  4. "fmt"
  5. "idio.link/go/parser"
  6. )
  7. type fcVector[A parser.ASTNode, _ any] struct {
  8. dim int
  9. newToken func() A
  10. }
  11. func (t fcVector[_, _]) Shift(sm *parser.SM, e rune) error {
  12. length := len(sm.Top().Nodes)
  13. if length == 0 {
  14. return sm.Push(t.newToken()).Shift(sm, e)
  15. }
  16. switch e {
  17. case ' ', ')':
  18. case ',':
  19. if length == t.dim {
  20. return fmt.Errorf("vector: too many components")
  21. }
  22. sm.Push(t.newToken())
  23. default:
  24. return parser.NewUnrecognized("vector", e)
  25. }
  26. return nil
  27. }
  28. func (t fcVector[_, B]) Coalesce(nodes []*parser.CSTNode) any {
  29. col := make([]B, 0, 8)
  30. for _, e := range nodes {
  31. col = append(col, e.Coalesce().(B))
  32. }
  33. return col
  34. }
  35. func (t fcVector[_, _]) Value() *bytes.Buffer {
  36. return nil
  37. }
  38. type fcSet[A parser.ASTNode, _ fmt.Stringer] struct {
  39. newToken func() A
  40. }
  41. func (t fcSet[_, _]) Shift(sm *parser.SM, e rune) error {
  42. switch {
  43. case e == ' ':
  44. case e == ',':
  45. case e == '}':
  46. case isAlpha(e) || isDigit(e):
  47. return sm.Push(t.newToken()).Shift(sm, e)
  48. default:
  49. if len(sm.Top().Nodes) == 0 {
  50. return fmt.Errorf("set: cannot be the empty set")
  51. }
  52. return parser.NewUnrecognized("set", e)
  53. }
  54. return nil
  55. }
  56. func (t fcSet[_, B]) Coalesce(nodes []*parser.CSTNode) any {
  57. col := make(map[string]B)
  58. for _, e := range nodes {
  59. tmp := e.Coalesce().(B)
  60. col[tmp.String()] = tmp
  61. }
  62. return col
  63. }
  64. func (t fcSet[_, _]) Value() *bytes.Buffer {
  65. return nil
  66. }