func simpleCompound(pn *parse.Primary) (*parse.Compound, string) { thisIndexing, ok := pn.Parent().(*parse.Indexing) if !ok { return nil, "" } thisCompound, ok := thisIndexing.Parent().(*parse.Compound) if !ok { return nil, "" } head := "" for _, in := range thisCompound.Indexings { if len(in.Indicies) > 0 { return nil, "" } typ := in.Head.Type if typ != parse.Bareword && typ != parse.SingleQuoted && typ != parse.DoubleQuoted { return nil, "" } head += in.Head.Value if in == thisIndexing { break } } return thisCompound, head }
func (cp *compiler) literal(n *parse.Primary, msg string) string { switch n.Type { case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted: return n.Value default: cp.errorf(n.Begin(), msg) return "" // not reached } }
func primaryInSimpleCompound(pn *parse.Primary) (*parse.Compound, string) { thisIndexing, ok := pn.Parent().(*parse.Indexing) if !ok { return nil, "" } thisCompound, ok := thisIndexing.Parent().(*parse.Compound) if !ok { return nil, "" } ok, head, _ := simpleCompound(thisCompound, thisIndexing) if !ok { return nil, "" } return thisCompound, head }
func simpleCompound(pn *parse.Primary) (*parse.Compound, string) { thisIndexing, ok := pn.Parent().(*parse.Indexing) if !ok { return nil, "" } thisCompound, ok := thisIndexing.Parent().(*parse.Compound) if !ok { return nil, "" } tilde := false head := "" for _, in := range thisCompound.Indexings { if len(in.Indicies) > 0 { return nil, "" } switch in.Head.Type { case parse.Tilde: tilde = true case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted: head += in.Head.Value } if in == thisIndexing { break } } if tilde { i := strings.Index(head, "/") if i == -1 { return nil, "" } uname := head[:i] home, err := osutil.GetHome(uname) if err != nil { // TODO report error return nil, "" } head = home + head[i:] } return thisCompound, head }
func (cp *compiler) primary(n *parse.Primary) ValuesOpFunc { switch n.Type { case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted: return literalStr(n.Value) case parse.Variable: qname := n.Value if !cp.registerVariableGet(qname) { cp.errorf("variable $%s not found", n.Value) } return variable(qname) case parse.Wildcard: vs := []Value{GlobPattern{[]glob.Segment{ wildcardToSegment(n.SourceText())}, ""}} return func(ec *EvalCtx) []Value { return vs } case parse.Tilde: cp.errorf("compiler bug: Tilde not handled in .compound") return literalStr("~") case parse.PredCapture: return cp.predCapture(n.Chunk) case parse.OutputCapture: return cp.outputCapture(n) case parse.List: return cp.list(n.List) case parse.Lambda: return cp.lambda(n) case parse.Map: return cp.map_(n) case parse.Braced: return cp.braced(n) default: cp.errorf("bad PrimaryType; parser bug") return literalStr(n.SourceText()) } }
func (cp *compiler) primary(n *parse.Primary) valuesOp { switch n.Type { case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted: return literalStr(n.Value) case parse.Variable: qname := n.Value[1:] if !cp.registerVariableGet(qname) { cp.errorf(n.Begin(), "variable %s not found", n.Value) } return variable(qname, n.Begin()) // case parse.Wildcard: case parse.ErrorCapture: op := cp.chunk(n.Chunk) return func(ec *evalCtx) []Value { return []Value{Error{ec.peval(op)}} } case parse.OutputCapture: return cp.outputCapture(n) case parse.List: op := cp.array(n.List) return func(ec *evalCtx) []Value { return []Value{NewList(op(ec)...)} } case parse.Lambda: return cp.lambda(n) case parse.Map: return cp.map_(n) case parse.Braced: return cp.braced(n) default: // XXX: Primary types not yet implemented are just treated as // barewords. Should report parser bug of bad PrimaryType after they // have been implemented. return literalStr(n.SourceText()) // panic("bad PrimaryType; parser bug") } }
func (cp *compiler) bracedOp(n *parse.Primary) ValuesOp { return ValuesOp{cp.braced(n), n.Begin(), n.End()} }
func (cp *compiler) map_Op(n *parse.Primary) ValuesOp { return ValuesOp{cp.map_(n), n.Begin(), n.End()} }
func (cp *compiler) lambdaOp(n *parse.Primary) ValuesOp { return ValuesOp{cp.lambda(n), n.Begin(), n.End()} }
func (cp *compiler) outputCaptureOp(n *parse.Primary) ValuesOp { return ValuesOp{cp.outputCapture(n), n.Begin(), n.End()} }
func (cp *compiler) primaryOp(n *parse.Primary) ValuesOp { return ValuesOp{cp.primary(n), n.Begin(), n.End()} }
func (cp *compiler) primary(n *parse.Primary) ValuesOp { switch n.Type { case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted: return literalStr(n.Value) case parse.Variable: qname := n.Value if !cp.registerVariableGet(qname) { cp.errorf(n.Begin(), "variable %s not found", n.Value) } return variable(qname, n.Begin()) case parse.Wildcard: vs := []Value{GlobPattern{[]glob.Segment{ wildcardToSegment(n.SourceText())}}} return func(ec *EvalCtx) []Value { return vs } case parse.Tilde: cp.errorf(n.Begin(), "compiler bug: Tilde not handled in .compound") return literalStr("~") case parse.ErrorCapture: op := cp.chunk(n.Chunk) return func(ec *EvalCtx) []Value { return []Value{Error{ec.PEval(op)}} } case parse.OutputCapture: return cp.outputCapture(n) case parse.List: op := cp.array(n.List) return func(ec *EvalCtx) []Value { return []Value{NewList(op(ec)...)} } case parse.Lambda: return cp.lambda(n) case parse.Map: return cp.map_(n) case parse.Braced: return cp.braced(n) default: cp.errorf(n.Begin(), "bad PrimaryType; parser bug") return literalStr(n.SourceText()) } }