Something went wrong. Try again.
small gleam coding and persistent agent daemon with a detachable cli and a canvas ui forked from okami.mom/albedo
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202package chroma
import ( "encoding/xml" "fmt" "strings")
// A Mutator modifies the behaviour of the lexer.type Mutator interface { // Mutate the lexer state machine as it is processing. Mutate(state *LexerState) error}
// SerialisableMutator is a Mutator that can be serialised and deserialised.type SerialisableMutator interface { Mutator MutatorKind() string}
// A LexerMutator is an additional interface that a Mutator can implement// to modify the lexer when it is compiled.type LexerMutator interface { // MutateLexer can be implemented to mutate the lexer itself. // // Rules are the lexer rules, state is the state key for the rule the mutator is associated with. MutateLexer(rules CompiledRules, state string, rule int) error}
// A MutatorFunc is a Mutator that mutates the lexer state machine as it is processing.type MutatorFunc func(state *LexerState) error
func (m MutatorFunc) Mutate(state *LexerState) error { return m(state) } // nolint
type multiMutator struct { Mutators []Mutator `xml:"mutator"`}
func (m *multiMutator) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for { token, err := d.Token() if err != nil { return err } switch token := token.(type) { case xml.StartElement: mutator, err := unmarshalMutator(d, token) if err != nil { return err } m.Mutators = append(m.Mutators, mutator)
case xml.EndElement: return nil } }}
func (m *multiMutator) MarshalXML(e *xml.Encoder, start xml.StartElement) error { name := xml.Name{Local: "mutators"} if err := e.EncodeToken(xml.StartElement{Name: name}); err != nil { return err } for _, m := range m.Mutators { if err := marshalMutator(e, m); err != nil { return err } } return e.EncodeToken(xml.EndElement{Name: name})}
func (m *multiMutator) MutatorKind() string { return "mutators" }
func (m *multiMutator) Mutate(state *LexerState) error { for _, modifier := range m.Mutators { if err := modifier.Mutate(state); err != nil { return err } } return nil}
// Mutators applies a set of Mutators in order.func Mutators(modifiers ...Mutator) Mutator { return &multiMutator{modifiers}}
type includeMutator struct { State string `xml:"state,attr"`}
// Include the given state.func Include(state string) Rule { return Rule{Mutator: &includeMutator{state}}}
func (i *includeMutator) MutatorKind() string { return "include" }
func (i *includeMutator) Mutate(s *LexerState) error { return fmt.Errorf("should never reach here Include(%q)", i.State)}
func (i *includeMutator) MutateLexer(rules CompiledRules, state string, rule int) error { includedRules, ok := rules[i.State] if !ok { return fmt.Errorf("invalid include state %q", i.State) } rules[state] = append(rules[state][:rule], append(includedRules, rules[state][rule+1:]...)...) return nil}
type combinedMutator struct { States []string `xml:"state,attr"`}
func (c *combinedMutator) MutatorKind() string { return "combined" }
// Combined creates a new anonymous state from the given states, and pushes that state.func Combined(states ...string) Mutator { return &combinedMutator{states}}
func (c *combinedMutator) Mutate(s *LexerState) error { return fmt.Errorf("should never reach here Combined(%v)", c.States)}
func (c *combinedMutator) MutateLexer(rules CompiledRules, state string, rule int) error { name := "__combined_" + strings.Join(c.States, "__") if _, ok := rules[name]; !ok { combined := []*CompiledRule{} for _, state := range c.States { rules, ok := rules[state] if !ok { return fmt.Errorf("invalid combine state %q", state) } combined = append(combined, rules...) } rules[name] = combined } rules[state][rule].Mutator = Push(name) return nil}
type pushMutator struct { States []string `xml:"state,attr"`}
func (p *pushMutator) MutatorKind() string { return "push" }
func (p *pushMutator) Mutate(s *LexerState) error { if len(p.States) == 0 { s.Stack = append(s.Stack, s.State) } else { for _, state := range p.States { if state == "#pop" { s.Stack = s.Stack[:len(s.Stack)-1] } else { s.Stack = append(s.Stack, state) } } } return nil}
// Push states onto the stack.func Push(states ...string) Mutator { return &pushMutator{states}}
type popMutator struct { Depth int `xml:"depth,attr"`}
func (p *popMutator) MutatorKind() string { return "pop" }
func (p *popMutator) Mutate(state *LexerState) error { if len(state.Stack) == 0 { return fmt.Errorf("nothing to pop") } state.Stack = state.Stack[:len(state.Stack)-p.Depth] return nil}
// Pop state from the stack when rule matches.func Pop(n int) Mutator { return &popMutator{n}}
// Default returns a Rule that applies a set of Mutators.func Default(mutators ...Mutator) Rule { return Rule{Mutator: Mutators(mutators...)}}
// Stringify returns the raw string for a set of tokens.func Stringify(tokens ...Token) string { out := []string{} for _, t := range tokens { out = append(out, t.Value) } return strings.Join(out, "")}