src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/parse/cmpd/cmpd.go (about) 1 // Package cmpd contains utilities for working with compound nodes. 2 package cmpd 3 4 import ( 5 "fmt" 6 7 "src.elv.sh/pkg/parse" 8 ) 9 10 // Primary returns a primary node and true if that's the only child of the 11 // compound node. Otherwise it returns nil and false. 12 func Primary(n *parse.Compound) (*parse.Primary, bool) { 13 if n != nil && len(n.Indexings) == 1 && len(n.Indexings[0].Indices) == 0 { 14 return n.Indexings[0].Head, true 15 } 16 return nil, false 17 } 18 19 // StringLiteral returns the value of a string literal and true if that's the 20 // only child of the compound node. Otherwise it returns "" and false. 21 func StringLiteral(n *parse.Compound) (string, bool) { 22 if pn, ok := Primary(n); ok { 23 switch pn.Type { 24 case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted: 25 return pn.Value, true 26 } 27 } 28 return "", false 29 } 30 31 // Lambda returns a lambda primary node and true if that's the only child of the 32 // compound node. Otherwise it returns nil and false. 33 func Lambda(n *parse.Compound) (*parse.Primary, bool) { 34 if pn, ok := Primary(n); ok { 35 if pn.Type == parse.Lambda { 36 return pn, true 37 } 38 } 39 return nil, false 40 } 41 42 // StringLiteralOrError is like StringLiteral, but returns an error suitable as 43 // a compiler error when StringLiteral would return false. 44 func StringLiteralOrError(n *parse.Compound, what string) (string, error) { 45 s, ok := StringLiteral(n) 46 if !ok { 47 return "", fmt.Errorf("%s must be string literal, found %s", what, Shape(n)) 48 } 49 return s, nil 50 } 51 52 // Shape describes the shape of the compound node. 53 func Shape(n *parse.Compound) string { 54 if len(n.Indexings) == 0 { 55 return "empty expression" 56 } 57 if len(n.Indexings) > 1 { 58 return "compound expression" 59 } 60 in := n.Indexings[0] 61 if len(in.Indices) > 0 { 62 return "indexing expression" 63 } 64 pn := in.Head 65 return "primary expression of type " + pn.Type.String() 66 }