stagePlanner.go
func planValue(stream *tokenStream) (*evaluationStage, error) {

	var token ExpressionToken
	var symbol OperatorSymbol
	var ret *evaluationStage
	var operator evaluationOperator
	var err error

	if !stream.hasNext() {
		return nil, nil
	}

	token = stream.next()

	switch token.Kind {

	case CLAUSE:

		ret, err = planTokens(stream)
		if err != nil {
			return nil, err
		}

		// advance past the CLAUSE_CLOSE token. We know that it's a CLAUSE_CLOSE, because at parse-time we check for unbalanced parens.
		stream.next()

		// the stage we got represents all of the logic contained within the parens
		// but for technical reasons, we need to wrap this stage in a "noop" stage which breaks long chains of precedence.
		// see github #33.
		ret = &evaluationStage{
			rightStage: ret,
			operator:   noopStageRight,
			symbol:     NOOP,
		}

		return ret, nil

	case CLAUSE_CLOSE:

		// when functions have empty params, this will be hit. In this case, we don't have any evaluation stage to do,
		// so we just return nil so that the stage planner continues on its way.
		stream.rewind()
		return nil, nil

	case VARIABLE:
		operator = makeParameterStage(token.Value.(string))

	case NUMERIC:
		fallthrough
	case STRING:
		fallthrough
	case PATTERN:
		fallthrough
	case BOOLEAN:
		symbol = LITERAL
		operator = makeLiteralStage(token.Value)
	case TIME:
		symbol = LITERAL
		operator = makeLiteralStage(float64(token.Value.(time.Time).Unix()))

	case PREFIX:
		stream.rewind()
		return planPrefix(stream)
	}

	if operator == nil {
		errorMsg := fmt.Sprintf("Unable to plan token kind: '%s', value: '%v'", token.Kind.String(), token.Value)
		return nil, errors.New(errorMsg)
	}

	return &evaluationStage{
		symbol:   symbol,
		operator: operator,
	}, nil
}
func planValue(stream *tokenStream) (*evaluationStage, error) {

	var token ExpressionToken
	var symbol OperatorSymbol
	var ret *evaluationStage
	var operator evaluationOperator
	var err error

	if !stream.hasNext() {
		return nil, nil
	}

	token = stream.next()

	switch token.Kind {

	case CLAUSE:

		ret, err = planTokens(stream)
		if err != nil {
			return nil, err
		}

		// advance past the CLAUSE_CLOSE token. We know that it's a CLAUSE_CLOSE, because at parse-time we check for unbalanced parens.
		stream.next()

		// the stage we got represents all of the logic contained within the parens
		// but for technical reasons, we need to wrap this stage in a "noop" stage which breaks long chains of precedence.
		// see github #33.
		ret = &evaluationStage{
			rightStage: ret,
			operator:   noopStageRight,
			symbol:     NOOP,
		}

		return ret, nil

	case CLAUSE_CLOSE:

		// when functions have empty params, this will be hit. In this case, we don't have any evaluation stage to do,
		// so we just return nil so that the stage planner continues on its way.
		stream.rewind()
		return nil, nil

	case VARIABLE:
		operator = makeParameterStage(token.Value.(string))

	case NUMERIC:
		fallthrough
	case STRING:
		fallthrough
	case PATTERN:
		fallthrough
	case BOOLEAN:
		symbol = LITERAL
		operator = makeLiteralStage(token.Value)
	case TIME:
		symbol = LITERAL
		operator = makeLiteralStage(float64(token.Value.(time.Time).Unix()))

	case PREFIX:
		stream.rewind()
		return planPrefix(stream)
	}

	if operator == nil {
		errorMsg := fmt.Sprintf("Unable to plan token kind: '%s', value: '%v'", token.Kind.String(), token.Value)
		return nil, errors.New(errorMsg)
	}

	return &evaluationStage{
		symbol:   symbol,
		operator: operator,
	}, nil
}
func planValue ( stream * tokenStream ) ( * evaluationStage , error ) { var token ExpressionToken var symbol OperatorSymbol var ret * evaluationStage var operator evaluationOperator var err error if ! stream . hasNext ( ) { return nil , nil } token = stream . next ( ) switch token . Kind { case CLAUSE : ret , err = planTokens ( stream ) if err != nil { return nil , err } // advance past the CLAUSE_CLOSE token. We know that it's a CLAUSE_CLOSE, because at parse-time we check for unbalanced parens. stream . next ( ) // the stage we got represents all of the logic contained within the parens // but for technical reasons, we need to wrap this stage in a "noop" stage which breaks long chains of precedence. // see github #33. ret = & evaluationStage { rightStage : ret , operator : noopStageRight , symbol : NOOP , } return ret , nil case CLAUSE_CLOSE : // when functions have empty params, this will be hit. In this case, we don't have any evaluation stage to do, // so we just return nil so that the stage planner continues on its way. stream . rewind ( ) return nil , nil case VARIABLE : operator = makeParameterStage ( token . Value . ( string ) ) case NUMERIC : fallthrough case STRING : fallthrough case PATTERN : fallthrough case BOOLEAN : symbol = LITERAL operator = makeLiteralStage ( token . Value ) case TIME : symbol = LITERAL operator = makeLiteralStage ( float64 ( token . Value . ( time . Time ) . Unix ( ) ) ) case PREFIX : stream . rewind ( ) return planPrefix ( stream ) } if operator == nil { errorMsg := fmt . Sprintf ( " " , token . Kind . String ( ) , token . Value ) return nil , errors . New ( errorMsg ) } return & evaluationStage { symbol : symbol , operator : operator , } , nil }
/*
	A truly special precedence function, this handles all the "lowest-case" errata of the process, including literals, parmeters,
	clauses, and prefixes.
*/
/ * A truly special precedence function this handles all the lowest - case errata of the process including literals parmeters clauses and prefixes .