package goja

import (
	
	
	
	
	
	
	

	
)

type asciiString string

type asciiRuneReader struct {
	s   asciiString
	pos int
}

func ( *asciiRuneReader) () ( rune,  int,  error) {
	if .pos < len(.s) {
		 = rune(.s[.pos])
		 = 1
		.pos++
	} else {
		 = io.EOF
	}
	return
}

type asciiUtf16Reader struct {
	s   asciiString
	pos int
}

func ( *asciiUtf16Reader) () ( uint16,  error) {
	if .pos < len(.s) {
		 = uint16(.s[.pos])
		.pos++
	} else {
		 = io.EOF
	}
	return
}

func ( *asciiUtf16Reader) () ( rune,  int,  error) {
	if .pos < len(.s) {
		 = rune(.s[.pos])
		.pos++
		 = 1
	} else {
		 = io.EOF
	}
	return
}

func ( asciiString) () io.RuneReader {
	return &asciiRuneReader{
		s: ,
	}
}

func ( asciiString) () utf16Reader {
	return &asciiUtf16Reader{
		s: ,
	}
}

func ( asciiString) () io.RuneReader {
	return &asciiUtf16Reader{
		s: ,
	}
}

func ( asciiString) () []rune {
	 := make([]rune, len())
	for  := 0;  < len(); ++ {
		[] = rune([])
	}
	return 
}

// ss must be trimmed
func stringToInt( string) (int64, error) {
	if  == "" {
		return 0, nil
	}
	if  == "-0" {
		return 0, strconv.ErrSyntax
	}
	if len() > 2 {
		switch [:2] {
		case "0x", "0X":
			return strconv.ParseInt([2:], 16, 64)
		case "0b", "0B":
			return strconv.ParseInt([2:], 2, 64)
		case "0o", "0O":
			return strconv.ParseInt([2:], 8, 64)
		}
	}
	return strconv.ParseInt(, 10, 64)
}

func ( asciiString) ( string) (int64, error) {
	return stringToInt()
}

func isRangeErr( error) bool {
	if ,  := .(*strconv.NumError);  {
		return .Err == strconv.ErrRange
	}
	return false
}

func ( asciiString) ( string) (float64, error) {
	if  == "" {
		return 0, nil
	}
	if  == "-0" {
		var  float64
		return -, nil
	}

	// Go allows underscores in numbers, when parsed as floats, but ECMAScript expect them to be interpreted as NaN.
	if strings.ContainsRune(, '_') {
		return 0, strconv.ErrSyntax
	}

	// Hexadecimal floats are not supported by ECMAScript.
	if len() >= 2 {
		var  string
		if [0] == '-' || [0] == '+' {
			 = [1:]
		} else {
			 = 
		}
		if len() >= 2 && [0] == '0' && ([1] == 'x' || [1] == 'X') {
			return 0, strconv.ErrSyntax
		}
	}

	,  := strconv.ParseFloat(, 64)
	if  == nil && math.IsInf(, 0) {
		 := strings.ToLower()
		if strings.HasPrefix(, "inf") || strings.HasPrefix(, "-inf") || strings.HasPrefix(, "+inf") {
			// We handle "Infinity" separately, prevent from being parsed as Infinity due to strconv.ParseFloat() permissive syntax
			return 0, strconv.ErrSyntax
		}
	}
	if isRangeErr() {
		 = nil
	}
	return , 
}

func ( asciiString) () int64 {
	 := strings.TrimSpace(string())
	if  == "" {
		return 0
	}
	if  == "Infinity" ||  == "+Infinity" {
		return math.MaxInt64
	}
	if  == "-Infinity" {
		return math.MinInt64
	}
	,  := ._toInt()
	if  != nil {
		,  := ._toFloat()
		if  == nil {
			return int64()
		}
	}
	return 
}

func ( asciiString) () String {
	return 
}

func ( asciiString) () Value {
	return 
}

func ( asciiString) () string {
	return string()
}

func ( asciiString) () float64 {
	 := strings.TrimSpace(string())
	if  == "" {
		return 0
	}
	if  == "Infinity" ||  == "+Infinity" {
		return math.Inf(1)
	}
	if  == "-Infinity" {
		return math.Inf(-1)
	}
	,  := ._toFloat()
	if  != nil {
		,  := ._toInt()
		if  == nil {
			return float64()
		}
		 = math.NaN()
	}
	return 
}

func ( asciiString) () bool {
	return  != ""
}

func ( asciiString) () Value {
	 := strings.TrimSpace(string())
	if  == "" {
		return intToValue(0)
	}
	if  == "Infinity" ||  == "+Infinity" {
		return _positiveInf
	}
	if  == "-Infinity" {
		return _negativeInf
	}

	if ,  := ._toInt();  == nil {
		return intToValue()
	}

	if ,  := ._toFloat();  == nil {
		return floatToValue()
	}

	return _NaN
}

func ( asciiString) ( *Runtime) *Object {
	return ._newString(, .getStringPrototype())
}

func ( asciiString) ( Value) bool {
	return .StrictEquals()
}

func ( asciiString) ( Value) bool {
	if .StrictEquals() {
		return true
	}

	if ,  := .(valueInt);  {
		if ,  := ._toInt(strings.TrimSpace(string()));  == nil {
			return  == int64()
		}
		return false
	}

	if ,  := .(valueFloat);  {
		return .ToFloat() == float64()
	}

	if ,  := .(valueBool);  {
		if ,  := ._toFloat(strings.TrimSpace(string()));  == nil {
			return  == .ToFloat()
		}
		return false
	}

	if ,  := .(*valueBigInt);  {
		,  := stringToBigInt(.toTrimmedUTF8())
		if  != nil {
			return false
		}
		return .Cmp((*big.Int)()) == 0
	}

	if ,  := .(*Object);  {
		return .(.toPrimitive())
	}
	return false
}

func ( asciiString) ( Value) bool {
	if ,  := .(asciiString);  {
		return  == 
	}
	if ,  := .(*importedString);  {
		if .u == nil {
			return string() == .s
		}
	}
	return false
}

func ( asciiString) ( *Runtime) *Object {
	 := .getStringSingleton()
	.value = 
	.setLength()
	return .val
}

func ( asciiString) ( *maphash.Hash) uint64 {
	_, _ = .WriteString(string())
	 := .Sum64()
	.Reset()
	return 
}

func ( asciiString) ( int) uint16 {
	return uint16([])
}

func ( asciiString) () int {
	return len()
}

func ( asciiString) ( String) String {
	,  := devirtualizeString()
	if  != nil {
		 := make([]uint16, len()+len())
		[0] = unistring.BOM
		for  := 0;  < len(); ++ {
			[+1] = uint16([])
		}
		copy([len()+1:], [1:])
		return unicodeString()
	}
	return  + 
}

func ( asciiString) (,  int) String {
	return [:]
}

func ( asciiString) ( String) int {
	switch other := .(type) {
	case asciiString:
		return strings.Compare(string(), string())
	case unicodeString:
		return strings.Compare(string(), .String())
	case *importedString:
		return strings.Compare(string(), .s)
	default:
		panic(newTypeError("Internal bug: unknown string type: %T", ))
	}
}

func ( asciiString) ( String,  int) int {
	,  := devirtualizeString()
	if  == nil {
		if  > len() {
			return -1
		}
		 := strings.Index(string([:]), string())
		if  >= 0 {
			return  + 
		}
	}
	return -1
}

func ( asciiString) ( String,  int) int {
	,  := devirtualizeString()
	if  == nil {
		 :=  + len()
		var  string
		if  > len() {
			 = string()
		} else {
			 = string([:])
		}
		return strings.LastIndex(, string())
	}
	return -1
}

func ( asciiString) () String {
	return asciiString(strings.ToLower(string()))
}

func ( asciiString) () String {
	return asciiString(strings.ToUpper(string()))
}

func ( asciiString) () string {
	return strings.TrimSpace(string())
}

func ( asciiString) () unistring.String {
	return unistring.String()
}

func ( asciiString) () interface{} {
	return string()
}

func ( asciiString) () reflect.Type {
	return reflectTypeString
}