|
- package ast
-
- import (
- "bytes"
- "fmt"
- )
-
- type Node struct {
- Parent *Node
- Children []*Node
- Value interface{}
- Kind Kind
- }
-
- func NewNode(k Kind, v interface{}, ch ...*Node) *Node {
- n := &Node{
- Kind: k,
- Value: v,
- }
- for _, c := range ch {
- Insert(n, c)
- }
- return n
- }
-
- func (a *Node) Equal(b *Node) bool {
- if a.Kind != b.Kind {
- return false
- }
- if a.Value != b.Value {
- return false
- }
- if len(a.Children) != len(b.Children) {
- return false
- }
- for i, c := range a.Children {
- if !c.Equal(b.Children[i]) {
- return false
- }
- }
- return true
- }
-
- func (a *Node) String() string {
- var buf bytes.Buffer
- buf.WriteString(a.Kind.String())
- if a.Value != nil {
- buf.WriteString(" =")
- buf.WriteString(fmt.Sprintf("%v", a.Value))
- }
- if len(a.Children) > 0 {
- buf.WriteString(" [")
- for i, c := range a.Children {
- if i > 0 {
- buf.WriteString(", ")
- }
- buf.WriteString(c.String())
- }
- buf.WriteString("]")
- }
- return buf.String()
- }
-
- func Insert(parent *Node, children ...*Node) {
- parent.Children = append(parent.Children, children...)
- for _, ch := range children {
- ch.Parent = parent
- }
- }
-
- type List struct {
- Not bool
- Chars string
- }
-
- type Range struct {
- Not bool
- Lo, Hi rune
- }
-
- type Text struct {
- Text string
- }
-
- type Kind int
-
- const (
- KindNothing Kind = iota
- KindPattern
- KindList
- KindRange
- KindText
- KindAny
- KindSuper
- KindSingle
- KindAnyOf
- )
-
- func (k Kind) String() string {
- switch k {
- case KindNothing:
- return "Nothing"
- case KindPattern:
- return "Pattern"
- case KindList:
- return "List"
- case KindRange:
- return "Range"
- case KindText:
- return "Text"
- case KindAny:
- return "Any"
- case KindSuper:
- return "Super"
- case KindSingle:
- return "Single"
- case KindAnyOf:
- return "AnyOf"
- default:
- return ""
- }
- }
|