stagePlanner.go
func planPrecedenceLevel(
	stream *tokenStream,
	typeErrorFormat string,
	validSymbols map[string]OperatorSymbol,
	validKinds []TokenKind,
	rightPrecedent precedent,
	leftPrecedent precedent) (*evaluationStage, error) {

	var token ExpressionToken
	var symbol OperatorSymbol
	var leftStage, rightStage *evaluationStage
	var checks typeChecks
	var err error
	var keyFound bool

	if leftPrecedent != nil {

		leftStage, err = leftPrecedent(stream)
		if err != nil {
			return nil, err
		}
	}

	for stream.hasNext() {

		token = stream.next()

		if len(validKinds) > 0 {

			keyFound = false
			for _, kind := range validKinds {
				if kind == token.Kind {
					keyFound = true
					break
				}
			}

			if !keyFound {
				break
			}
		}

		if validSymbols != nil {

			if !isString(token.Value) {
				break
			}

			symbol, keyFound = validSymbols[token.Value.(string)]
			if !keyFound {
				break
			}
		}

		if rightPrecedent != nil {
			rightStage, err = rightPrecedent(stream)
			if err != nil {
				return nil, err
			}
		}

		checks = findTypeChecks(symbol)

		return &evaluationStage{

			symbol:     symbol,
			leftStage:  leftStage,
			rightStage: rightStage,
			operator:   stageSymbolMap[symbol],

			leftTypeCheck:   checks.left,
			rightTypeCheck:  checks.right,
			typeCheck:       checks.combined,
			typeErrorFormat: typeErrorFormat,
		}, nil
	}

	stream.rewind()
	return leftStage, nil
}
func planPrecedenceLevel(
	stream *tokenStream,
	typeErrorFormat string,
	validSymbols map[string]OperatorSymbol,
	validKinds []TokenKind,
	rightPrecedent precedent,
	leftPrecedent precedent) (*evaluationStage, error) {

	var token ExpressionToken
	var symbol OperatorSymbol
	var leftStage, rightStage *evaluationStage
	var checks typeChecks
	var err error
	var keyFound bool

	if leftPrecedent != nil {

		leftStage, err = leftPrecedent(stream)
		if err != nil {
			return nil, err
		}
	}

	for stream.hasNext() {

		token = stream.next()

		if len(validKinds) > 0 {

			keyFound = false
			for _, kind := range validKinds {
				if kind == token.Kind {
					keyFound = true
					break
				}
			}

			if !keyFound {
				break
			}
		}

		if validSymbols != nil {

			if !isString(token.Value) {
				break
			}

			symbol, keyFound = validSymbols[token.Value.(string)]
			if !keyFound {
				break
			}
		}

		if rightPrecedent != nil {
			rightStage, err = rightPrecedent(stream)
			if err != nil {
				return nil, err
			}
		}

		checks = findTypeChecks(symbol)

		return &evaluationStage{

			symbol:     symbol,
			leftStage:  leftStage,
			rightStage: rightStage,
			operator:   stageSymbolMap[symbol],

			leftTypeCheck:   checks.left,
			rightTypeCheck:  checks.right,
			typeCheck:       checks.combined,
			typeErrorFormat: typeErrorFormat,
		}, nil
	}

	stream.rewind()
	return leftStage, nil
}
func planPrecedenceLevel ( stream * tokenStream , typeErrorFormat string , validSymbols map [ string ] OperatorSymbol , validKinds [ ] TokenKind , rightPrecedent precedent , leftPrecedent precedent ) ( * evaluationStage , error ) { var token ExpressionToken var symbol OperatorSymbol var leftStage , rightStage * evaluationStage var checks typeChecks var err error var keyFound bool if leftPrecedent != nil { leftStage , err = leftPrecedent ( stream ) if err != nil { return nil , err } } for stream . hasNext ( ) { token = stream . next ( ) if len ( validKinds ) > 0 { keyFound = false for _ , kind := range validKinds { if kind == token . Kind { keyFound = true break } } if ! keyFound { break } } if validSymbols != nil { if ! isString ( token . Value ) { break } symbol , keyFound = validSymbols [ token . Value . ( string ) ] if ! keyFound { break } } if rightPrecedent != nil { rightStage , err = rightPrecedent ( stream ) if err != nil { return nil , err } } checks = findTypeChecks ( symbol ) return & evaluationStage { symbol : symbol , leftStage : leftStage , rightStage : rightStage , operator : stageSymbolMap [ symbol ] , leftTypeCheck : checks . left , rightTypeCheck : checks . right , typeCheck : checks . combined , typeErrorFormat : typeErrorFormat , } , nil } stream . rewind ( ) return leftStage , nil }
/*
	The most usual method of parsing an evaluation stage for a given precedence.
	Most stages use the same logic
*/
/ * The most usual method of parsing an evaluation stage for a given precedence . Most stages use the same logic