package csexp import ( "bytes" "fmt" "io" "slices" "git.codemonkeysoftware.net/b/peachy-go/shortcircuit" ) type Sexp interface { isSexp() WriteTo(w io.Writer) (n int64, err error) String() string Equal(Sexp) bool Clone() Sexp } type Atom []byte func (a Atom) isSexp() {} func (a Atom) WriteTo(w io.Writer) (int64, error) { if scw, ok := w.(*shortcircuit.Writer); ok && scw.Failed() { return 0, nil } n, err := fmt.Fprintf(w, "%d:%s", len(a), []byte(a)) return int64(n), err } func (a Atom) String() string { var buf bytes.Buffer a.WriteTo(&buf) return buf.String() } func (a Atom) Equal(s Sexp) bool { a2, ok := s.(Atom) return ok && bytes.Equal([]byte(a), []byte(a2)) } func (a Atom) Clone() Sexp { return Atom(bytes.Clone([]byte(a))) } type List []Sexp func (l List) isSexp() {} func (l List) WriteTo(w io.Writer) (int64, error) { scw := shortcircuit.EnsureWriter(w) if scw.Failed() { return 0, nil } io.WriteString(scw, "(") for _, child := range l { child.WriteTo(scw) } io.WriteString(scw, ")") return scw.Status() } func (l List) String() string { var buf bytes.Buffer l.WriteTo(&buf) return buf.String() } func (l List) Equal(s Sexp) bool { l2, ok := s.(List) return ok && slices.EqualFunc(l, l2, Sexp.Equal) } func (l List) Clone() Sexp { l2 := make(List, len(l)) for i, child := range l { l2[i] = child.Clone() } return l2 } func Parse(data []byte) (Sexp, error) { return nil, nil }