// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package strconv

const fnParseComplex = "ParseComplex"

// convErr splits an error returned by parseFloatPrefix
// into a syntax or range error for ParseComplex.
func convErr( error,  string) (,  error) {
	if ,  := .(*NumError);  {
		.Func = fnParseComplex
		.Num = cloneString()
		if .Err == ErrRange {
			return nil, 
		}
	}
	return , nil
}

// ParseComplex converts the string s to a complex number
// with the precision specified by bitSize: 64 for complex64, or 128 for complex128.
// When bitSize=64, the result still has type complex128, but it will be
// convertible to complex64 without changing its value.
//
// The number represented by s must be of the form N, Ni, or N±Ni, where N stands
// for a floating-point number as recognized by ParseFloat, and i is the imaginary
// component. If the second N is unsigned, a + sign is required between the two components
// as indicated by the ±. If the second N is NaN, only a + sign is accepted.
// The form may be parenthesized and cannot contain any spaces.
// The resulting complex number consists of the two components converted by ParseFloat.
//
// The errors that ParseComplex returns have concrete type *NumError
// and include err.Num = s.
//
// If s is not syntactically well-formed, ParseComplex returns err.Err = ErrSyntax.
//
// If s is syntactically well-formed but either component is more than 1/2 ULP
// away from the largest floating point number of the given component's size,
// ParseComplex returns err.Err = ErrRange and c = ±Inf for the respective component.
func ( string,  int) (complex128, error) {
	 := 64
	if  == 64 {
		 = 32 // complex64 uses float32 parts
	}

	 := 

	// Remove parentheses, if any.
	if len() >= 2 && [0] == '(' && [len()-1] == ')' {
		 = [1 : len()-1]
	}

	var  error // pending range error, or nil

	// Read real part (possibly imaginary part if followed by 'i').
	, ,  := parseFloatPrefix(, )
	if  != nil {
		,  = convErr(, )
		if  != nil {
			return 0, 
		}
	}
	 = [:]

	// If we have nothing left, we're done.
	if len() == 0 {
		return complex(, 0), 
	}

	// Otherwise, look at the next character.
	switch [0] {
	case '+':
		// Consume the '+' to avoid an error if we have "+NaNi", but
		// do this only if we don't have a "++" (don't hide that error).
		if len() > 1 && [1] != '+' {
			 = [1:]
		}
	case '-':
		// ok
	case 'i':
		// If 'i' is the last character, we only have an imaginary part.
		if len() == 1 {
			return complex(0, ), 
		}
		fallthrough
	default:
		return 0, syntaxError(fnParseComplex, )
	}

	// Read imaginary part.
	, ,  := parseFloatPrefix(, )
	if  != nil {
		,  = convErr(, )
		if  != nil {
			return 0, 
		}
	}
	 = [:]
	if  != "i" {
		return 0, syntaxError(fnParseComplex, )
	}
	return complex(, ), 
}