func parseVarExp()

in variables.go [451:504]


func parseVarExp(lex <-chan token, pathSep string, maxIdx int64, enableNumKeys, allowEscapePath bool) (varEvaler, error) {
	stack := []parseState{{st: stLeft}}

	// parser loop
	for tok := range lex {
		switch tok.typ {
		case tokOpen:
			stack = append(stack, parseState{st: stLeft, isvar: true})
		case tokClose:
			// finalize and pop state
			piece, err := stack[len(stack)-1].finalize(pathSep, maxIdx, enableNumKeys, allowEscapePath)
			stack = stack[:len(stack)-1]
			if err != nil {
				return nil, err
			}

			// append result top stacked state
			st := &stack[len(stack)-1]
			st.pieces[st.st] = append(st.pieces[st.st], piece)

		case tokSep: // switch from left to right
			st := &stack[len(stack)-1]
			if !st.isvar {
				return nil, errors.New("default separator not within expansion")
			}
			if st.st == stRight {
				st.pieces[st.st] = addString(st.pieces[st.st], tok.val)
			} else {
				// switch to 'right'
				st.st = stRight
				st.op = tok.val
			}

		case tokString:
			// append raw string
			st := &stack[len(stack)-1]
			st.pieces[st.st] = addString(st.pieces[st.st], tok.val)
		}
	}

	// validate and return final state
	if len(stack) > 1 {
		return nil, errors.New("missing '}'")
	}
	if len(stack) == 0 {
		return nil, errors.New("fatal: expansion parse state empty")
	}

	result := stack[0].pieces[stLeft]
	if len(result) == 1 {
		return result[0], nil
	}
	return &splice{result}, nil
}