mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 04:02:26 -05:00 
			
		
		
		
	
		
			
	
	
		
			1338 lines
		
	
	
	
		
			42 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			1338 lines
		
	
	
	
		
			42 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | // Copyright 2019 The CC 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 cc // import "modernc.org/cc/v3" | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"fmt" | ||
|  | 	"math" | ||
|  | 	"math/big" | ||
|  | ) | ||
|  | 
 | ||
|  | var ( | ||
|  | 	_ Value = (*Float128Value)(nil) | ||
|  | 	_ Value = (*InitializerValue)(nil) | ||
|  | 	_ Value = Complex128Value(0) | ||
|  | 	_ Value = Complex256Value{} | ||
|  | 	_ Value = Complex64Value(0) | ||
|  | 	_ Value = Float32Value(0) | ||
|  | 	_ Value = Float64Value(0) | ||
|  | 	_ Value = Int64Value(0) | ||
|  | 	_ Value = StringValue(0) | ||
|  | 	_ Value = Uint64Value(0) | ||
|  | 	_ Value = WideStringValue(0) | ||
|  | 
 | ||
|  | 	_ Operand = (*funcDesignator)(nil) | ||
|  | 	_ Operand = (*lvalue)(nil) | ||
|  | 	_ Operand = (*operand)(nil) | ||
|  | 	_ Operand = noOperand | ||
|  | 
 | ||
|  | 	noOperand = &operand{typ: noType} | ||
|  | ) | ||
|  | 
 | ||
|  | type Operand interface { | ||
|  | 	// IsAssingmentCompatible reports whether the operand can be | ||
|  | 	// assigned to lhs. [0], 6.5.16.1. | ||
|  | 	IsAssingmentCompatible(lhs Type) bool | ||
|  | 	ConvertTo(Type) Operand | ||
|  | 	Declarator() *Declarator | ||
|  | 	IsConst() bool | ||
|  | 	IsLValue() bool | ||
|  | 	IsNonZero() bool | ||
|  | 	IsZero() bool | ||
|  | 	Offset() uintptr // Valid only for non nil Declarator() value | ||
|  | 	Type() Type | ||
|  | 	Value() Value | ||
|  | 	convertFromInt(*context, Node, Type) Operand | ||
|  | 	convertTo(*context, Node, Type) Operand | ||
|  | 	convertToInt(*context, Node, Type) Operand | ||
|  | 	getABI() *ABI | ||
|  | 	integerPromotion(*context, Node) Operand | ||
|  | 	normalize(*context, Node) Operand | ||
|  | } | ||
|  | 
 | ||
|  | type Value interface { | ||
|  | 	IsConst() bool | ||
|  | 	IsNonZero() bool | ||
|  | 	IsZero() bool | ||
|  | 	add(b Value) Value | ||
|  | 	and(b Value) Value | ||
|  | 	cpl() Value | ||
|  | 	div(b Value) Value | ||
|  | 	eq(b Value) Value | ||
|  | 	ge(b Value) Value | ||
|  | 	gt(b Value) Value | ||
|  | 	le(b Value) Value | ||
|  | 	lsh(b Value) Value | ||
|  | 	lt(b Value) Value | ||
|  | 	mod(b Value) Value | ||
|  | 	mul(b Value) Value | ||
|  | 	neg() Value | ||
|  | 	neq(b Value) Value | ||
|  | 	or(b Value) Value | ||
|  | 	rsh(b Value) Value | ||
|  | 	sub(b Value) Value | ||
|  | 	xor(b Value) Value | ||
|  | } | ||
|  | 
 | ||
|  | type WideStringValue StringID | ||
|  | 
 | ||
|  | func (v WideStringValue) add(b Value) Value { panic(todo("")) } | ||
|  | func (v WideStringValue) and(b Value) Value { panic(todo("")) } | ||
|  | func (v WideStringValue) cpl() Value        { panic(todo("")) } | ||
|  | func (v WideStringValue) div(b Value) Value { panic(todo("")) } | ||
|  | func (v WideStringValue) eq(b Value) Value  { return boolValue(v == b.(WideStringValue)) } | ||
|  | func (v WideStringValue) IsConst() bool     { return true } | ||
|  | func (v WideStringValue) IsNonZero() bool   { return true } | ||
|  | func (v WideStringValue) IsZero() bool      { return false } | ||
|  | func (v WideStringValue) lsh(b Value) Value { panic(todo("")) } | ||
|  | func (v WideStringValue) mod(b Value) Value { panic(todo("")) } | ||
|  | func (v WideStringValue) mul(b Value) Value { panic(todo("")) } | ||
|  | func (v WideStringValue) neg() Value        { panic(todo("")) } | ||
|  | func (v WideStringValue) neq(b Value) Value { return boolValue(v != b.(WideStringValue)) } | ||
|  | func (v WideStringValue) or(b Value) Value  { panic(todo("")) } | ||
|  | func (v WideStringValue) rsh(b Value) Value { panic(todo("")) } | ||
|  | func (v WideStringValue) sub(b Value) Value { panic(todo("")) } | ||
|  | func (v WideStringValue) xor(b Value) Value { panic(todo("")) } | ||
|  | 
 | ||
|  | func (v WideStringValue) le(b Value) Value { | ||
|  | 	return boolValue(StringID(v).String() <= StringID(b.(WideStringValue)).String()) | ||
|  | } | ||
|  | 
 | ||
|  | func (v WideStringValue) ge(b Value) Value { | ||
|  | 	return boolValue(StringID(v).String() >= StringID(b.(WideStringValue)).String()) | ||
|  | } | ||
|  | 
 | ||
|  | func (v WideStringValue) gt(b Value) Value { | ||
|  | 	return boolValue(StringID(v).String() > StringID(b.(WideStringValue)).String()) | ||
|  | } | ||
|  | 
 | ||
|  | func (v WideStringValue) lt(b Value) Value { | ||
|  | 	return boolValue(StringID(v).String() < StringID(b.(WideStringValue)).String()) | ||
|  | } | ||
|  | 
 | ||
|  | type StringValue StringID | ||
|  | 
 | ||
|  | func (v StringValue) add(b Value) Value { panic(todo("")) } | ||
|  | func (v StringValue) and(b Value) Value { panic(todo("")) } | ||
|  | func (v StringValue) cpl() Value        { panic(todo("")) } | ||
|  | func (v StringValue) div(b Value) Value { panic(todo("")) } | ||
|  | func (v StringValue) eq(b Value) Value  { return boolValue(v == b.(StringValue)) } | ||
|  | func (v StringValue) IsConst() bool     { return true } | ||
|  | func (v StringValue) IsNonZero() bool   { return true } | ||
|  | func (v StringValue) IsZero() bool      { return false } | ||
|  | func (v StringValue) lsh(b Value) Value { panic(todo("")) } | ||
|  | func (v StringValue) mod(b Value) Value { panic(todo("")) } | ||
|  | func (v StringValue) mul(b Value) Value { panic(todo("")) } | ||
|  | func (v StringValue) neg() Value        { panic(todo("")) } | ||
|  | func (v StringValue) neq(b Value) Value { return boolValue(v != b.(StringValue)) } | ||
|  | func (v StringValue) or(b Value) Value  { panic(todo("")) } | ||
|  | func (v StringValue) rsh(b Value) Value { panic(todo("")) } | ||
|  | func (v StringValue) sub(b Value) Value { panic(todo("")) } | ||
|  | func (v StringValue) xor(b Value) Value { panic(todo("")) } | ||
|  | 
 | ||
|  | func (v StringValue) le(b Value) Value { | ||
|  | 	return boolValue(StringID(v).String() <= StringID(b.(StringValue)).String()) | ||
|  | } | ||
|  | 
 | ||
|  | func (v StringValue) ge(b Value) Value { | ||
|  | 	return boolValue(StringID(v).String() >= StringID(b.(StringValue)).String()) | ||
|  | } | ||
|  | 
 | ||
|  | func (v StringValue) gt(b Value) Value { | ||
|  | 	return boolValue(StringID(v).String() > StringID(b.(StringValue)).String()) | ||
|  | } | ||
|  | 
 | ||
|  | func (v StringValue) lt(b Value) Value { | ||
|  | 	return boolValue(StringID(v).String() < StringID(b.(StringValue)).String()) | ||
|  | } | ||
|  | 
 | ||
|  | type Int64Value int64 | ||
|  | 
 | ||
|  | func (v Int64Value) add(b Value) Value { return v + b.(Int64Value) } | ||
|  | func (v Int64Value) and(b Value) Value { return v & b.(Int64Value) } | ||
|  | func (v Int64Value) cpl() Value        { return ^v } | ||
|  | func (v Int64Value) eq(b Value) Value  { return boolValue(v == b.(Int64Value)) } | ||
|  | func (v Int64Value) ge(b Value) Value  { return boolValue(v >= b.(Int64Value)) } | ||
|  | func (v Int64Value) gt(b Value) Value  { return boolValue(v > b.(Int64Value)) } | ||
|  | func (v Int64Value) IsConst() bool     { return true } | ||
|  | func (v Int64Value) IsNonZero() bool   { return v != 0 } | ||
|  | func (v Int64Value) IsZero() bool      { return v == 0 } | ||
|  | func (v Int64Value) le(b Value) Value  { return boolValue(v <= b.(Int64Value)) } | ||
|  | func (v Int64Value) lt(b Value) Value  { return boolValue(v < b.(Int64Value)) } | ||
|  | func (v Int64Value) mul(b Value) Value { return v * b.(Int64Value) } | ||
|  | func (v Int64Value) neg() Value        { return -v } | ||
|  | func (v Int64Value) neq(b Value) Value { return boolValue(v != b.(Int64Value)) } | ||
|  | func (v Int64Value) or(b Value) Value  { return v | b.(Int64Value) } | ||
|  | func (v Int64Value) sub(b Value) Value { return v - b.(Int64Value) } | ||
|  | func (v Int64Value) xor(b Value) Value { return v ^ b.(Int64Value) } | ||
|  | 
 | ||
|  | func (v Int64Value) div(b Value) Value { | ||
|  | 	if b.IsZero() { | ||
|  | 		return nil | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return v / b.(Int64Value) | ||
|  | } | ||
|  | 
 | ||
|  | func (v Int64Value) lsh(b Value) Value { | ||
|  | 	switch y := b.(type) { | ||
|  | 	case Int64Value: | ||
|  | 		return v << uint64(y) | ||
|  | 	case Uint64Value: | ||
|  | 		return v << y | ||
|  | 	default: | ||
|  | 		panic(todo("")) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (v Int64Value) rsh(b Value) Value { | ||
|  | 	switch y := b.(type) { | ||
|  | 	case Int64Value: | ||
|  | 		return v >> uint64(y) | ||
|  | 	case Uint64Value: | ||
|  | 		return v >> y | ||
|  | 	default: | ||
|  | 		panic(todo("")) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (v Int64Value) mod(b Value) Value { | ||
|  | 	if b.IsZero() { | ||
|  | 		return nil | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return v % b.(Int64Value) | ||
|  | } | ||
|  | 
 | ||
|  | type Uint64Value uint64 | ||
|  | 
 | ||
|  | func (v Uint64Value) add(b Value) Value { return v + b.(Uint64Value) } | ||
|  | func (v Uint64Value) and(b Value) Value { return v & b.(Uint64Value) } | ||
|  | func (v Uint64Value) cpl() Value        { return ^v } | ||
|  | func (v Uint64Value) eq(b Value) Value  { return boolValue(v == b.(Uint64Value)) } | ||
|  | func (v Uint64Value) ge(b Value) Value  { return boolValue(v >= b.(Uint64Value)) } | ||
|  | func (v Uint64Value) gt(b Value) Value  { return boolValue(v > b.(Uint64Value)) } | ||
|  | func (v Uint64Value) IsConst() bool     { return true } | ||
|  | func (v Uint64Value) IsNonZero() bool   { return v != 0 } | ||
|  | func (v Uint64Value) IsZero() bool      { return v == 0 } | ||
|  | func (v Uint64Value) le(b Value) Value  { return boolValue(v <= b.(Uint64Value)) } | ||
|  | func (v Uint64Value) lt(b Value) Value  { return boolValue(v < b.(Uint64Value)) } | ||
|  | func (v Uint64Value) mul(b Value) Value { return v * b.(Uint64Value) } | ||
|  | func (v Uint64Value) neg() Value        { return -v } | ||
|  | func (v Uint64Value) neq(b Value) Value { return boolValue(v != b.(Uint64Value)) } | ||
|  | func (v Uint64Value) or(b Value) Value  { return v | b.(Uint64Value) } | ||
|  | func (v Uint64Value) sub(b Value) Value { return v - b.(Uint64Value) } | ||
|  | func (v Uint64Value) xor(b Value) Value { return v ^ b.(Uint64Value) } | ||
|  | 
 | ||
|  | func (v Uint64Value) div(b Value) Value { | ||
|  | 	if b.IsZero() { | ||
|  | 		return nil | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return v / b.(Uint64Value) | ||
|  | } | ||
|  | 
 | ||
|  | func (v Uint64Value) lsh(b Value) Value { | ||
|  | 	switch y := b.(type) { | ||
|  | 	case Int64Value: | ||
|  | 		return v << uint64(y) | ||
|  | 	case Uint64Value: | ||
|  | 		return v << y | ||
|  | 	default: | ||
|  | 		panic(todo("")) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (v Uint64Value) rsh(b Value) Value { | ||
|  | 	switch y := b.(type) { | ||
|  | 	case Int64Value: | ||
|  | 		return v >> uint64(y) | ||
|  | 	case Uint64Value: | ||
|  | 		return v >> y | ||
|  | 	default: | ||
|  | 		panic(todo("")) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (v Uint64Value) mod(b Value) Value { | ||
|  | 	if b.IsZero() { | ||
|  | 		return nil | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return v % b.(Uint64Value) | ||
|  | } | ||
|  | 
 | ||
|  | type Float32Value float32 | ||
|  | 
 | ||
|  | func (v Float32Value) add(b Value) Value { return v + b.(Float32Value) } | ||
|  | func (v Float32Value) and(b Value) Value { panic(todo("")) } | ||
|  | func (v Float32Value) cpl() Value        { panic(todo("")) } | ||
|  | func (v Float32Value) div(b Value) Value { return v / b.(Float32Value) } | ||
|  | func (v Float32Value) eq(b Value) Value  { return boolValue(v == b.(Float32Value)) } | ||
|  | func (v Float32Value) ge(b Value) Value  { return boolValue(v >= b.(Float32Value)) } | ||
|  | func (v Float32Value) gt(b Value) Value  { return boolValue(v > b.(Float32Value)) } | ||
|  | func (v Float32Value) IsConst() bool     { return true } | ||
|  | func (v Float32Value) IsNonZero() bool   { return v != 0 } | ||
|  | func (v Float32Value) IsZero() bool      { return !math.Signbit(float64(v)) && v == 0 } | ||
|  | func (v Float32Value) le(b Value) Value  { return boolValue(v <= b.(Float32Value)) } | ||
|  | func (v Float32Value) lsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Float32Value) lt(b Value) Value  { return boolValue(v < b.(Float32Value)) } | ||
|  | func (v Float32Value) mod(b Value) Value { panic(todo("")) } | ||
|  | func (v Float32Value) mul(b Value) Value { return v * b.(Float32Value) } | ||
|  | func (v Float32Value) neg() Value        { return -v } | ||
|  | func (v Float32Value) neq(b Value) Value { return boolValue(v != b.(Float32Value)) } | ||
|  | func (v Float32Value) or(b Value) Value  { panic(todo("")) } | ||
|  | func (v Float32Value) rsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Float32Value) sub(b Value) Value { return v - b.(Float32Value) } | ||
|  | func (v Float32Value) xor(b Value) Value { panic(todo("")) } | ||
|  | 
 | ||
|  | type Float64Value float64 | ||
|  | 
 | ||
|  | func (v Float64Value) add(b Value) Value { return v + b.(Float64Value) } | ||
|  | func (v Float64Value) and(b Value) Value { panic(todo("")) } | ||
|  | func (v Float64Value) cpl() Value        { panic(todo("")) } | ||
|  | func (v Float64Value) div(b Value) Value { return v / b.(Float64Value) } | ||
|  | func (v Float64Value) eq(b Value) Value  { return boolValue(v == b.(Float64Value)) } | ||
|  | func (v Float64Value) ge(b Value) Value  { return boolValue(v >= b.(Float64Value)) } | ||
|  | func (v Float64Value) gt(b Value) Value  { return boolValue(v > b.(Float64Value)) } | ||
|  | func (v Float64Value) IsConst() bool     { return true } | ||
|  | func (v Float64Value) IsNonZero() bool   { return v != 0 } | ||
|  | func (v Float64Value) IsZero() bool      { return !math.Signbit(float64(v)) && v == 0 } | ||
|  | func (v Float64Value) le(b Value) Value  { return boolValue(v <= b.(Float64Value)) } | ||
|  | func (v Float64Value) lsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Float64Value) lt(b Value) Value  { return boolValue(v < b.(Float64Value)) } | ||
|  | func (v Float64Value) mod(b Value) Value { panic(todo("")) } | ||
|  | func (v Float64Value) mul(b Value) Value { return v * b.(Float64Value) } | ||
|  | func (v Float64Value) neg() Value        { return -v } | ||
|  | func (v Float64Value) neq(b Value) Value { return boolValue(v != b.(Float64Value)) } | ||
|  | func (v Float64Value) or(b Value) Value  { panic(todo("")) } | ||
|  | func (v Float64Value) rsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Float64Value) sub(b Value) Value { return v - b.(Float64Value) } | ||
|  | func (v Float64Value) xor(b Value) Value { panic(todo("")) } | ||
|  | 
 | ||
|  | var float128Zero = &Float128Value{N: big.NewFloat(0)} | ||
|  | 
 | ||
|  | type Float128Value struct { | ||
|  | 	N   *big.Float | ||
|  | 	NaN bool | ||
|  | } | ||
|  | 
 | ||
|  | func (v *Float128Value) add(b Value) Value { return v.safe(b, func(x, y *big.Float) { x.Add(x, y) }) } | ||
|  | func (v *Float128Value) and(b Value) Value { panic(todo("")) } | ||
|  | func (v *Float128Value) cpl() Value        { panic(todo("")) } | ||
|  | func (v *Float128Value) div(b Value) Value { return v.safe(b, func(x, y *big.Float) { x.Quo(x, y) }) } | ||
|  | func (v *Float128Value) eq(b Value) Value  { panic(todo("")) } | ||
|  | func (v *Float128Value) ge(b Value) Value  { panic(todo("")) } | ||
|  | func (v *Float128Value) gt(b Value) Value  { return boolValue(v.cmp(b, -1, 0)) } | ||
|  | func (v *Float128Value) IsNonZero() bool   { panic(todo("")) } | ||
|  | func (v *Float128Value) IsConst() bool     { return true } | ||
|  | func (v *Float128Value) IsZero() bool      { return !v.NaN && !v.N.Signbit() && v.cmp(float128Zero, 0) } | ||
|  | func (v *Float128Value) le(b Value) Value  { panic(todo("")) } | ||
|  | func (v *Float128Value) lsh(b Value) Value { panic(todo("")) } | ||
|  | func (v *Float128Value) lt(b Value) Value  { panic(todo("")) } | ||
|  | func (v *Float128Value) mod(b Value) Value { panic(todo("")) } | ||
|  | func (v *Float128Value) mul(b Value) Value { return v.safe(b, func(x, y *big.Float) { x.Mul(x, y) }) } | ||
|  | func (v *Float128Value) neg() Value        { return v.safe(nil, func(x, y *big.Float) { x.Neg(x) }) } | ||
|  | func (v *Float128Value) neq(b Value) Value { panic(todo("")) } | ||
|  | func (v *Float128Value) or(b Value) Value  { panic(todo("")) } | ||
|  | func (v *Float128Value) rsh(b Value) Value { panic(todo("")) } | ||
|  | func (v *Float128Value) sub(b Value) Value { return v.safe(b, func(x, y *big.Float) { x.Sub(x, y) }) } | ||
|  | func (v *Float128Value) xor(b Value) Value { panic(todo("")) } | ||
|  | 
 | ||
|  | func (v *Float128Value) cmp(b Value, accept ...int) bool { | ||
|  | 	w := b.(*Float128Value) | ||
|  | 	if v.NaN || w.NaN { | ||
|  | 		return false | ||
|  | 	} | ||
|  | 
 | ||
|  | 	x := v.N.Cmp(w.N) | ||
|  | 	for _, v := range accept { | ||
|  | 		if v == x { | ||
|  | 			return true | ||
|  | 		} | ||
|  | 	} | ||
|  | 	return false | ||
|  | } | ||
|  | 
 | ||
|  | func (v *Float128Value) String() string { | ||
|  | 	switch { | ||
|  | 	case v == nil: | ||
|  | 		return "<nil>" | ||
|  | 	case v.NaN: | ||
|  | 		return "NaN" | ||
|  | 	default: | ||
|  | 		return fmt.Sprint(v.N) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (v *Float128Value) safe(b Value, f func(*big.Float, *big.Float)) (ret Value) { | ||
|  | 	var w *Float128Value | ||
|  | 	if b != nil { | ||
|  | 		w = b.(*Float128Value) | ||
|  | 	} | ||
|  | 	if v.NaN || w != nil && w.NaN { | ||
|  | 		return &Float128Value{NaN: true} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	r := &Float128Value{} | ||
|  | 
 | ||
|  | 	defer func() { | ||
|  | 		switch x := recover().(type) { | ||
|  | 		case big.ErrNaN: | ||
|  | 			r.N = nil | ||
|  | 			r.NaN = true | ||
|  | 			ret = r | ||
|  | 		case nil: | ||
|  | 			// ok | ||
|  | 		default: | ||
|  | 			panic(x) | ||
|  | 		} | ||
|  | 	}() | ||
|  | 
 | ||
|  | 	r.N = big.NewFloat(0).SetPrec(0).Set(v.N) | ||
|  | 	var wn *big.Float | ||
|  | 	if w != nil { | ||
|  | 		wn = w.N | ||
|  | 	} | ||
|  | 	f(r.N, wn) | ||
|  | 	return r | ||
|  | } | ||
|  | 
 | ||
|  | type Complex64Value complex64 | ||
|  | 
 | ||
|  | func (v Complex64Value) add(b Value) Value { return v + b.(Complex64Value) } | ||
|  | func (v Complex64Value) and(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex64Value) cpl() Value        { panic(todo("")) } | ||
|  | func (v Complex64Value) div(b Value) Value { return v / b.(Complex64Value) } | ||
|  | func (v Complex64Value) eq(b Value) Value  { return boolValue(v == b.(Complex64Value)) } | ||
|  | func (v Complex64Value) ge(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex64Value) gt(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex64Value) IsConst() bool     { return true } | ||
|  | func (v Complex64Value) IsNonZero() bool   { return v != 0 } | ||
|  | func (v Complex64Value) IsZero() bool      { return v == 0 } | ||
|  | func (v Complex64Value) le(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex64Value) lsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex64Value) lt(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex64Value) mod(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex64Value) mul(b Value) Value { return v * b.(Complex64Value) } | ||
|  | func (v Complex64Value) neg() Value        { return -v } | ||
|  | func (v Complex64Value) neq(b Value) Value { return boolValue(v != b.(Complex64Value)) } | ||
|  | func (v Complex64Value) or(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex64Value) rsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex64Value) sub(b Value) Value { return v - b.(Complex64Value) } | ||
|  | func (v Complex64Value) xor(b Value) Value { panic(todo("")) } | ||
|  | 
 | ||
|  | type Complex128Value complex128 | ||
|  | 
 | ||
|  | func (v Complex128Value) add(b Value) Value { return v + b.(Complex128Value) } | ||
|  | func (v Complex128Value) and(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex128Value) cpl() Value        { panic(todo("")) } | ||
|  | func (v Complex128Value) div(b Value) Value { return v / b.(Complex128Value) } | ||
|  | func (v Complex128Value) eq(b Value) Value  { return boolValue(v == b.(Complex128Value)) } | ||
|  | func (v Complex128Value) ge(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex128Value) gt(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex128Value) IsConst() bool     { return true } | ||
|  | func (v Complex128Value) IsNonZero() bool   { return v != 0 } | ||
|  | func (v Complex128Value) IsZero() bool      { return v == 0 } | ||
|  | func (v Complex128Value) le(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex128Value) lsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex128Value) lt(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex128Value) mod(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex128Value) mul(b Value) Value { return v * b.(Complex128Value) } | ||
|  | func (v Complex128Value) neg() Value        { return -v } | ||
|  | func (v Complex128Value) neq(b Value) Value { return boolValue(v != b.(Complex128Value)) } | ||
|  | func (v Complex128Value) or(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex128Value) rsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex128Value) sub(b Value) Value { return v - b.(Complex128Value) } | ||
|  | func (v Complex128Value) xor(b Value) Value { panic(todo("")) } | ||
|  | 
 | ||
|  | type Complex256Value struct { | ||
|  | 	Re, Im *Float128Value | ||
|  | } | ||
|  | 
 | ||
|  | func (v Complex256Value) add(b Value) Value { | ||
|  | 	w := b.(Complex256Value) | ||
|  | 	return Complex256Value{v.Re.add(w.Re).(*Float128Value), v.Im.add(w.Im).(*Float128Value)} | ||
|  | } | ||
|  | 
 | ||
|  | func (v Complex256Value) and(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex256Value) cpl() Value        { panic(todo("")) } | ||
|  | func (v Complex256Value) div(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex256Value) eq(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex256Value) ge(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex256Value) gt(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex256Value) IsConst() bool     { return true } | ||
|  | func (v Complex256Value) IsNonZero() bool   { panic(todo("")) } | ||
|  | func (v Complex256Value) IsZero() bool      { return v.Re.IsZero() && v.Im.IsZero() } | ||
|  | func (v Complex256Value) le(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex256Value) lsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex256Value) lt(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex256Value) mod(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex256Value) mul(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex256Value) neg() Value        { panic(todo("")) } | ||
|  | func (v Complex256Value) neq(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex256Value) or(b Value) Value  { panic(todo("")) } | ||
|  | func (v Complex256Value) rsh(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex256Value) sub(b Value) Value { panic(todo("")) } | ||
|  | func (v Complex256Value) xor(b Value) Value { panic(todo("")) } | ||
|  | 
 | ||
|  | type lvalue struct { | ||
|  | 	Operand | ||
|  | 	declarator *Declarator | ||
|  | } | ||
|  | 
 | ||
|  | func (o *lvalue) ConvertTo(to Type) (r Operand) { return o.convertTo(nil, nil, to) } | ||
|  | func (o *lvalue) Declarator() *Declarator       { return o.declarator } | ||
|  | func (o *lvalue) IsLValue() bool                { return true } | ||
|  | 
 | ||
|  | func (o *lvalue) IsConst() bool { | ||
|  | 	if v := o.Value(); v != nil { | ||
|  | 		return v.IsConst() | ||
|  | 	} | ||
|  | 
 | ||
|  | 	d := o.Declarator() | ||
|  | 	return d != nil && (d.Linkage != None || d.IsStatic()) | ||
|  | } | ||
|  | 
 | ||
|  | func (o *lvalue) convertTo(ctx *context, n Node, to Type) (r Operand) { | ||
|  | 	return &lvalue{Operand: o.Operand.convertTo(ctx, n, to), declarator: o.declarator} | ||
|  | } | ||
|  | 
 | ||
|  | type funcDesignator struct { | ||
|  | 	Operand | ||
|  | 	declarator *Declarator | ||
|  | } | ||
|  | 
 | ||
|  | func (o *funcDesignator) ConvertTo(to Type) (r Operand) { return o.convertTo(nil, nil, to) } | ||
|  | func (o *funcDesignator) Declarator() *Declarator       { return o.declarator } | ||
|  | func (o *funcDesignator) IsLValue() bool                { return false } | ||
|  | func (o *funcDesignator) IsConst() bool                 { return true } | ||
|  | 
 | ||
|  | func (o *funcDesignator) convertTo(ctx *context, n Node, to Type) (r Operand) { | ||
|  | 	return &lvalue{Operand: o.Operand.convertTo(ctx, n, to), declarator: o.declarator} | ||
|  | } | ||
|  | 
 | ||
|  | type operand struct { | ||
|  | 	abi    *ABI | ||
|  | 	typ    Type | ||
|  | 	value  Value | ||
|  | 	offset uintptr | ||
|  | } | ||
|  | 
 | ||
|  | func (o *operand) ConvertTo(to Type) (r Operand) { return o.convertTo(nil, nil, to) } | ||
|  | func (o *operand) Declarator() *Declarator       { return nil } | ||
|  | func (o *operand) Offset() uintptr               { return o.offset } | ||
|  | func (o *operand) IsLValue() bool                { return false } | ||
|  | func (o *operand) IsNonZero() bool               { return o.value != nil && o.value.IsNonZero() } | ||
|  | func (o *operand) IsZero() bool                  { return o.value != nil && o.value.IsZero() } | ||
|  | func (o *operand) Type() Type                    { return o.typ } | ||
|  | func (o *operand) Value() Value                  { return o.value } | ||
|  | func (o *operand) getABI() *ABI                  { return o.abi } | ||
|  | 
 | ||
|  | // IsAssingmentCompatible implements Operand. | ||
|  | func (o *operand) IsAssingmentCompatible(lhs Type) bool { return lhs.isAssingmentCompatibleOperand(o) } | ||
|  | 
 | ||
|  | func (o *operand) IsConst() bool { | ||
|  | 	if v := o.Value(); v != nil { | ||
|  | 		return v.IsConst() | ||
|  | 	} | ||
|  | 
 | ||
|  | 	d := o.Declarator() | ||
|  | 	return d != nil && (d.Linkage != None || d.IsStatic()) | ||
|  | } | ||
|  | 
 | ||
|  | // [0]6.3.1.8 | ||
|  | // | ||
|  | // Many operators that expect operands of arithmetic type cause conversions and | ||
|  | // yield result types in a similar way. The purpose is to determine a common | ||
|  | // real type for the operands and result. For the specified operands, each | ||
|  | // operand is converted, without change of type domain, to a type whose | ||
|  | // corresponding real type is the common real type. Unless explicitly stated | ||
|  | // otherwise, the common real type is also the corresponding real type of the | ||
|  | // result, whose type domain is the type domain of the operands if they are the | ||
|  | // same, and complex otherwise. This pattern is called the usual arithmetic | ||
|  | // conversions: | ||
|  | func usualArithmeticConversions(ctx *context, n Node, a, b Operand, normalize bool) (Operand, Operand) { | ||
|  | 	if a.Type().Kind() == Invalid || b.Type().Kind() == Invalid { | ||
|  | 		return noOperand, noOperand | ||
|  | 	} | ||
|  | 
 | ||
|  | 	abi := a.getABI() | ||
|  | 	if !a.Type().IsArithmeticType() { | ||
|  | 		if ctx != nil { | ||
|  | 			ctx.errNode(n, "not an arithmetic type: %s", a.Type()) | ||
|  | 		} | ||
|  | 		return noOperand, noOperand | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if !b.Type().IsArithmeticType() { | ||
|  | 		if ctx != nil { | ||
|  | 			ctx.errNode(n, "not an arithmetic type: %s", b.Type()) | ||
|  | 		} | ||
|  | 		return noOperand, noOperand | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if a.Type() == nil || b.Type() == nil { | ||
|  | 		return a, b | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if normalize { | ||
|  | 		a = a.normalize(ctx, n) | ||
|  | 		b = b.normalize(ctx, n) | ||
|  | 	} | ||
|  | 	if a == noOperand || b == noOperand { | ||
|  | 		return noOperand, noOperand | ||
|  | 	} | ||
|  | 
 | ||
|  | 	at := a.Type() | ||
|  | 	bt := b.Type() | ||
|  | 	cplx := at.IsComplexType() || bt.IsComplexType() | ||
|  | 
 | ||
|  | 	// First, if the corresponding real type of either operand is long | ||
|  | 	// double, the other operand is converted, without change of type | ||
|  | 	// domain, to a type whose corresponding real type is long double. | ||
|  | 	if at.Kind() == ComplexLongDouble || bt.Kind() == ComplexLongDouble || at.Kind() == LongDouble || bt.Kind() == LongDouble { | ||
|  | 		switch { | ||
|  | 		case cplx: | ||
|  | 			return a.convertTo(ctx, n, abi.Type(ComplexLongDouble)), b.convertTo(ctx, n, abi.Type(ComplexLongDouble)) | ||
|  | 		default: | ||
|  | 			return a.convertTo(ctx, n, abi.Type(LongDouble)), b.convertTo(ctx, n, abi.Type(LongDouble)) | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Otherwise, if the corresponding real type of either operand is | ||
|  | 	// double, the other operand is converted, without change of type | ||
|  | 	// domain, to a type whose corresponding real type is double. | ||
|  | 	if at.Kind() == ComplexDouble || bt.Kind() == ComplexDouble || at.Kind() == Double || bt.Kind() == Double { | ||
|  | 		switch { | ||
|  | 		case cplx: | ||
|  | 			return a.convertTo(ctx, n, abi.Type(ComplexDouble)), b.convertTo(ctx, n, abi.Type(ComplexDouble)) | ||
|  | 		default: | ||
|  | 			return a.convertTo(ctx, n, abi.Type(Double)), b.convertTo(ctx, n, abi.Type(Double)) | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Otherwise, if the corresponding real type of either operand is | ||
|  | 	// float, the other operand is converted, without change of type | ||
|  | 	// domain, to a type whose corresponding real type is float. | ||
|  | 	if at.Kind() == ComplexFloat || bt.Kind() == ComplexFloat || at.Kind() == Float || bt.Kind() == Float { | ||
|  | 		switch { | ||
|  | 		case cplx: | ||
|  | 			return a.convertTo(ctx, n, abi.Type(ComplexFloat)), b.convertTo(ctx, n, abi.Type(ComplexFloat)) | ||
|  | 		default: | ||
|  | 			return a.convertTo(ctx, n, abi.Type(Float)), b.convertTo(ctx, n, abi.Type(Float)) | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if cplx { | ||
|  | 		panic(internalErrorf("TODO %v, %v", at, bt)) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if !a.Type().IsIntegerType() || !b.Type().IsIntegerType() { | ||
|  | 		panic(todo("")) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Otherwise, the integer promotions are performed on both operands. | ||
|  | 	a = a.integerPromotion(ctx, n) | ||
|  | 	b = b.integerPromotion(ctx, n) | ||
|  | 	at = a.Type() | ||
|  | 	bt = b.Type() | ||
|  | 
 | ||
|  | 	// Then the following rules are applied to the promoted operands: | ||
|  | 
 | ||
|  | 	// If both operands have the same type, then no further conversion is | ||
|  | 	// needed. | ||
|  | 	if at.Kind() == bt.Kind() { | ||
|  | 		return a, b | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Otherwise, if both operands have signed integer types or both have | ||
|  | 	// unsigned integer types, the operand with the type of lesser integer | ||
|  | 	// conversion rank is converted to the type of the operand with greater | ||
|  | 	// rank. | ||
|  | 	if abi.isSignedInteger(at.Kind()) == abi.isSignedInteger(bt.Kind()) { | ||
|  | 		t := a.Type() | ||
|  | 		if intConvRank[bt.Kind()] > intConvRank[at.Kind()] { | ||
|  | 			t = b.Type() | ||
|  | 		} | ||
|  | 		return a.convertTo(ctx, n, t), b.convertTo(ctx, n, t) | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Otherwise, if the operand that has unsigned integer type has rank | ||
|  | 	// greater or equal to the rank of the type of the other operand, then | ||
|  | 	// the operand with signed integer type is converted to the type of the | ||
|  | 	// operand with unsigned integer type. | ||
|  | 	switch { | ||
|  | 	case a.Type().IsSignedType(): // b is unsigned | ||
|  | 		if intConvRank[bt.Kind()] >= intConvRank[a.Type().Kind()] { | ||
|  | 			return a.convertTo(ctx, n, b.Type()), b | ||
|  | 		} | ||
|  | 	case b.Type().IsSignedType(): // a is unsigned | ||
|  | 		if intConvRank[at.Kind()] >= intConvRank[b.Type().Kind()] { | ||
|  | 			return a, b.convertTo(ctx, n, a.Type()) | ||
|  | 		} | ||
|  | 	default: | ||
|  | 		panic(fmt.Errorf("TODO %v %v", a.Type(), b.Type())) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Otherwise, if the type of the operand with signed integer type can | ||
|  | 	// represent all of the values of the type of the operand with unsigned | ||
|  | 	// integer type, then the operand with unsigned integer type is | ||
|  | 	// converted to the type of the operand with signed integer type. | ||
|  | 	var signed Type | ||
|  | 	switch { | ||
|  | 	case abi.isSignedInteger(at.Kind()): // b is unsigned | ||
|  | 		signed = a.Type() | ||
|  | 		if at.Size() > bt.Size() { | ||
|  | 			return a, b.convertTo(ctx, n, a.Type()) | ||
|  | 		} | ||
|  | 	case abi.isSignedInteger(bt.Kind()): // a is unsigned | ||
|  | 		signed = b.Type() | ||
|  | 		if bt.Size() > at.Size() { | ||
|  | 			return a.convertTo(ctx, n, b.Type()), b | ||
|  | 		} | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Otherwise, both operands are converted to the unsigned integer type | ||
|  | 	// corresponding to the type of the operand with signed integer type. | ||
|  | 	var typ Type | ||
|  | 	switch signed.Kind() { | ||
|  | 	case Int: | ||
|  | 		//TODO if a.IsEnumConst || b.IsEnumConst { | ||
|  | 		//TODO 	return a, b | ||
|  | 		//TODO } | ||
|  | 
 | ||
|  | 		typ = abi.Type(UInt) | ||
|  | 	case Long: | ||
|  | 		typ = abi.Type(ULong) | ||
|  | 	case LongLong: | ||
|  | 		typ = abi.Type(ULongLong) | ||
|  | 	default: | ||
|  | 		panic(todo("")) | ||
|  | 	} | ||
|  | 	return a.convertTo(ctx, n, typ), b.convertTo(ctx, n, typ) | ||
|  | } | ||
|  | 
 | ||
|  | // [0]6.3.1.1-2 | ||
|  | // | ||
|  | // If an int can represent all values of the original type, the value is | ||
|  | // converted to an int; otherwise, it is converted to an unsigned int. These | ||
|  | // are called the integer promotions. All other types are unchanged by the | ||
|  | // integer promotions. | ||
|  | func (o *operand) integerPromotion(ctx *context, n Node) Operand { | ||
|  | 	t := o.Type() | ||
|  | 	if t2 := integerPromotion(o.abi, t); t2.Kind() != t.Kind() { | ||
|  | 		return o.convertTo(ctx, n, t2) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return o | ||
|  | } | ||
|  | 
 | ||
|  | // [0]6.3.1.1-2 | ||
|  | // | ||
|  | // If an int can represent all values of the original type, the value is | ||
|  | // converted to an int; otherwise, it is converted to an unsigned int. These | ||
|  | // are called the integer promotions. All other types are unchanged by the | ||
|  | // integer promotions. | ||
|  | func integerPromotion(abi *ABI, t Type) Type { | ||
|  | 	// github.com/gcc-mirror/gcc/gcc/testsuite/gcc.c-torture/execute/bf-sign-2.c | ||
|  | 	// | ||
|  | 	// This test checks promotion of bitfields.  Bitfields | ||
|  | 	// should be promoted very much like chars and shorts: | ||
|  | 	// | ||
|  | 	// Bitfields (signed or unsigned) should be promoted to | ||
|  | 	// signed int if their value will fit in a signed int, | ||
|  | 	// otherwise to an unsigned int if their value will fit | ||
|  | 	// in an unsigned int, otherwise we don't promote them | ||
|  | 	// (ANSI/ISO does not specify the behavior of bitfields | ||
|  | 	// larger than an unsigned int). | ||
|  | 	if t.IsBitFieldType() { | ||
|  | 		f := t.BitField() | ||
|  | 		intBits := int(abi.Types[Int].Size) * 8 | ||
|  | 		switch { | ||
|  | 		case t.IsSignedType(): | ||
|  | 			if f.BitFieldWidth() < intBits-1 { | ||
|  | 				return abi.Type(Int) | ||
|  | 			} | ||
|  | 		default: | ||
|  | 			if f.BitFieldWidth() < intBits { | ||
|  | 				return abi.Type(Int) | ||
|  | 			} | ||
|  | 		} | ||
|  | 		return t | ||
|  | 	} | ||
|  | 
 | ||
|  | 	switch t.Kind() { | ||
|  | 	case Invalid: | ||
|  | 		return t | ||
|  | 	case Char, SChar, UChar, Short, UShort: | ||
|  | 		return abi.Type(Int) | ||
|  | 	default: | ||
|  | 		return t | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (o *operand) convertTo(ctx *context, n Node, to Type) Operand { | ||
|  | 	if o.Type().Kind() == Invalid { | ||
|  | 		return o | ||
|  | 	} | ||
|  | 
 | ||
|  | 	v := o.Value() | ||
|  | 	r := &operand{abi: o.abi, typ: to, offset: o.offset, value: v} | ||
|  | 	switch v.(type) { | ||
|  | 	case nil, *InitializerValue: | ||
|  | 		return r | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if o.Type().Kind() == to.Kind() { | ||
|  | 		return r.normalize(ctx, n) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if o.Type().IsIntegerType() { | ||
|  | 		return o.convertFromInt(ctx, n, to) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if to.IsIntegerType() { | ||
|  | 		return o.convertToInt(ctx, n, to) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	switch o.Type().Kind() { | ||
|  | 	case Array: | ||
|  | 		switch to.Kind() { | ||
|  | 		case Ptr: | ||
|  | 			return r | ||
|  | 		default: | ||
|  | 			panic(todo("", n.Position())) | ||
|  | 		} | ||
|  | 	case ComplexFloat: | ||
|  | 		v := v.(Complex64Value) | ||
|  | 		switch to.Kind() { | ||
|  | 		case ComplexDouble: | ||
|  | 			r.value = Complex128Value(v) | ||
|  | 		case Float: | ||
|  | 			r.value = Float32Value(real(v)) | ||
|  | 		case Double: | ||
|  | 			r.value = Float64Value(real(v)) | ||
|  | 		case ComplexLongDouble: | ||
|  | 			panic(todo("", n.Position())) | ||
|  | 		default: | ||
|  | 			panic(todo("", n.Position())) | ||
|  | 		} | ||
|  | 	case ComplexDouble: | ||
|  | 		v := v.(Complex128Value) | ||
|  | 		switch to.Kind() { | ||
|  | 		case ComplexFloat: | ||
|  | 			r.value = Complex64Value(v) | ||
|  | 		case ComplexLongDouble: | ||
|  | 			//TODO panic(todo("", n.Position())) | ||
|  | 			r.value = nil | ||
|  | 		case Float: | ||
|  | 			r.value = Float32Value(real(v)) | ||
|  | 		case Double: | ||
|  | 			r.value = Float64Value(real(v)) | ||
|  | 		default: | ||
|  | 			//TODO panic(todo("", n.Position(), o.Type(), to)) | ||
|  | 			r.value = nil | ||
|  | 		} | ||
|  | 	case Float: | ||
|  | 		v := v.(Float32Value) | ||
|  | 		switch to.Kind() { | ||
|  | 		case ComplexFloat: | ||
|  | 			r.value = Complex64Value(complex(v, 0)) | ||
|  | 		case ComplexDouble: | ||
|  | 			r.value = Complex128Value(complex(v, 0)) | ||
|  | 		case Double: | ||
|  | 			r.value = Float64Value(v) | ||
|  | 		case ComplexLongDouble: | ||
|  | 			panic(todo("", n.Position())) | ||
|  | 		case LongDouble: | ||
|  | 			r.value = &Float128Value{N: big.NewFloat(float64(v))} | ||
|  | 		case Decimal32, Decimal64, Decimal128: | ||
|  | 			// ok | ||
|  | 		default: | ||
|  | 			panic(todo("695 %s", to.Kind())) | ||
|  | 		} | ||
|  | 	case Double: | ||
|  | 		v := v.(Float64Value) | ||
|  | 		switch to.Kind() { | ||
|  | 		case ComplexFloat: | ||
|  | 			r.value = Complex64Value(complex(v, 0)) | ||
|  | 		case ComplexDouble: | ||
|  | 			r.value = Complex128Value(complex(v, 0)) | ||
|  | 		case LongDouble: | ||
|  | 			f := float64(v) | ||
|  | 			switch { | ||
|  | 			case math.IsNaN(f): | ||
|  | 				r.value = &Float128Value{NaN: true} | ||
|  | 			default: | ||
|  | 				r.value = &Float128Value{N: big.NewFloat(f)} | ||
|  | 			} | ||
|  | 		case Float: | ||
|  | 			r.value = Float32Value(v) | ||
|  | 		case ComplexLongDouble: | ||
|  | 			panic(todo("", n.Position())) | ||
|  | 		case Vector: | ||
|  | 			r.value = nil | ||
|  | 		case Decimal32, Decimal64, Decimal128: | ||
|  | 			// ok | ||
|  | 		default: | ||
|  | 			panic(todo("", to.Kind())) | ||
|  | 		} | ||
|  | 	case LongDouble: | ||
|  | 		v := v.(*Float128Value) | ||
|  | 		switch to.Kind() { | ||
|  | 		case Double: | ||
|  | 			if v.NaN { | ||
|  | 				r.value = Float64Value(math.NaN()) | ||
|  | 				break | ||
|  | 			} | ||
|  | 
 | ||
|  | 			d, _ := v.N.Float64() | ||
|  | 			r.value = Float64Value(d) | ||
|  | 		case Float: | ||
|  | 			if v.NaN { | ||
|  | 				r.value = Float32Value(math.NaN()) | ||
|  | 				break | ||
|  | 			} | ||
|  | 
 | ||
|  | 			d, _ := v.N.Float64() | ||
|  | 			r.value = Float32Value(d) | ||
|  | 		case ComplexLongDouble: | ||
|  | 			if v.NaN { | ||
|  | 				r.value = Complex256Value{v, &Float128Value{NaN: true}} | ||
|  | 				break | ||
|  | 			} | ||
|  | 
 | ||
|  | 			r.value = Complex256Value{v, &Float128Value{N: big.NewFloat(0)}} | ||
|  | 		case Decimal32, Decimal64, Decimal128: | ||
|  | 			// ok | ||
|  | 		default: | ||
|  | 			panic(todo("813 %v", to.Kind())) | ||
|  | 		} | ||
|  | 	case Ptr: | ||
|  | 		switch to.Kind() { | ||
|  | 		case Void: | ||
|  | 			return noOperand | ||
|  | 		default: | ||
|  | 			panic(internalErrorf("%v: %v y-> %v %v", n.Position(), o.Type(), to, to.Kind())) | ||
|  | 		} | ||
|  | 	default: | ||
|  | 		panic(internalErrorf("%v: %v -> %v %v", n.Position(), o.Type(), to, to.Kind())) | ||
|  | 	} | ||
|  | 	return r.normalize(ctx, n) | ||
|  | } | ||
|  | 
 | ||
|  | type signedSaturationLimit struct { | ||
|  | 	fmin, fmax float64 | ||
|  | 	min, max   int64 | ||
|  | } | ||
|  | 
 | ||
|  | type unsignedSaturationLimit struct { | ||
|  | 	fmax float64 | ||
|  | 	max  uint64 | ||
|  | } | ||
|  | 
 | ||
|  | var ( | ||
|  | 	signedSaturationLimits = [...]signedSaturationLimit{ | ||
|  | 		1: {math.Nextafter(math.MinInt32, 0), math.Nextafter(math.MaxInt32, 0), math.MinInt32, math.MaxInt32}, | ||
|  | 		2: {math.Nextafter(math.MinInt32, 0), math.Nextafter(math.MaxInt32, 0), math.MinInt32, math.MaxInt32}, | ||
|  | 		4: {math.Nextafter(math.MinInt32, 0), math.Nextafter(math.MaxInt32, 0), math.MinInt32, math.MaxInt32}, | ||
|  | 		8: {math.Nextafter(math.MinInt64, 0), math.Nextafter(math.MaxInt64, 0), math.MinInt64, math.MaxInt64}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	unsignedSaturationLimits = [...]unsignedSaturationLimit{ | ||
|  | 		1: {math.Nextafter(math.MaxUint32, 0), math.MaxUint32}, | ||
|  | 		2: {math.Nextafter(math.MaxUint32, 0), math.MaxUint32}, | ||
|  | 		4: {math.Nextafter(math.MaxUint32, 0), math.MaxUint32}, | ||
|  | 		8: {math.Nextafter(math.MaxUint64, 0), math.MaxUint64}, | ||
|  | 	} | ||
|  | ) | ||
|  | 
 | ||
|  | func (o *operand) convertToInt(ctx *context, n Node, to Type) (r Operand) { | ||
|  | 	v := o.Value() | ||
|  | 	switch o.Type().Kind() { | ||
|  | 	case Float: | ||
|  | 		v := float64(v.(Float32Value)) | ||
|  | 		switch { | ||
|  | 		case to.IsSignedType(): | ||
|  | 			limits := &signedSaturationLimits[to.Size()] | ||
|  | 			if v > limits.fmax { | ||
|  | 				return (&operand{abi: o.abi, typ: to, value: Int64Value(limits.max)}).normalize(ctx, n) | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if v < limits.fmin { | ||
|  | 				return (&operand{abi: o.abi, typ: to, value: Int64Value(limits.min)}).normalize(ctx, n) | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Int64Value(v)}).normalize(ctx, n) | ||
|  | 		default: | ||
|  | 			limits := &unsignedSaturationLimits[to.Size()] | ||
|  | 			if v > limits.fmax { | ||
|  | 				return (&operand{abi: o.abi, typ: to, value: Uint64Value(limits.max)}).normalize(ctx, n) | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Uint64Value(v)}).normalize(ctx, n) | ||
|  | 		} | ||
|  | 	case Double: | ||
|  | 		v := float64(v.(Float64Value)) | ||
|  | 		switch { | ||
|  | 		case to.IsSignedType(): | ||
|  | 			limits := &signedSaturationLimits[to.Size()] | ||
|  | 			if v > limits.fmax { | ||
|  | 				return (&operand{abi: o.abi, typ: to, value: Int64Value(limits.max)}).normalize(ctx, n) | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if v < limits.fmin { | ||
|  | 				return (&operand{abi: o.abi, typ: to, value: Int64Value(limits.min)}).normalize(ctx, n) | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Int64Value(v)}).normalize(ctx, n) | ||
|  | 		default: | ||
|  | 			limits := &unsignedSaturationLimits[to.Size()] | ||
|  | 			if v > limits.fmax { | ||
|  | 				return (&operand{abi: o.abi, typ: to, value: Uint64Value(limits.max)}).normalize(ctx, n) | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Uint64Value(v)}).normalize(ctx, n) | ||
|  | 		} | ||
|  | 	case LongDouble: | ||
|  | 		panic(todo("", n.Position())) | ||
|  | 	case Ptr: | ||
|  | 		var v uint64 | ||
|  | 		switch x := o.Value().(type) { | ||
|  | 		case Int64Value: | ||
|  | 			v = uint64(x) | ||
|  | 		case Uint64Value: | ||
|  | 			v = uint64(x) | ||
|  | 		case *InitializerValue: | ||
|  | 			return (&operand{abi: o.abi, typ: to}) | ||
|  | 		default: | ||
|  | 			panic(internalErrorf("%v: %T", n.Position(), x)) | ||
|  | 		} | ||
|  | 		switch { | ||
|  | 		case to.IsSignedType(): | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Int64Value(v)}).normalize(ctx, n) | ||
|  | 		default: | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Uint64Value(v)}).normalize(ctx, n) | ||
|  | 		} | ||
|  | 	case Array: | ||
|  | 		return &operand{abi: o.abi, typ: to} | ||
|  | 	case Vector: | ||
|  | 		if o.Type().Size() == to.Size() { | ||
|  | 			return &operand{abi: o.abi, typ: to} | ||
|  | 		} | ||
|  | 	} | ||
|  | 	if ctx != nil { | ||
|  | 		ctx.errNode(n, "cannot convert %s to %s", o.Type(), to) | ||
|  | 	} | ||
|  | 	return &operand{abi: o.abi, typ: to} | ||
|  | } | ||
|  | 
 | ||
|  | func (o *operand) convertFromInt(ctx *context, n Node, to Type) (r Operand) { | ||
|  | 	var v uint64 | ||
|  | 	switch x := o.Value().(type) { | ||
|  | 	case Int64Value: | ||
|  | 		v = uint64(x) | ||
|  | 	case Uint64Value: | ||
|  | 		v = uint64(x) | ||
|  | 	default: | ||
|  | 		if ctx != nil { | ||
|  | 			ctx.errNode(n, "conversion to integer: invalid value") | ||
|  | 		} | ||
|  | 		return &operand{abi: o.abi, typ: to} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if to.IsIntegerType() { | ||
|  | 		switch { | ||
|  | 		case to.IsSignedType(): | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Int64Value(v)}).normalize(ctx, n) | ||
|  | 		default: | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Uint64Value(v)}).normalize(ctx, n) | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	switch to.Kind() { | ||
|  | 	case ComplexFloat: | ||
|  | 		switch { | ||
|  | 		case o.Type().IsSignedType(): | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Complex64Value(complex(float64(int64(v)), 0))}).normalize(ctx, n) | ||
|  | 		default: | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Complex64Value(complex(float64(v), 0))}).normalize(ctx, n) | ||
|  | 		} | ||
|  | 	case ComplexDouble: | ||
|  | 		switch { | ||
|  | 		case o.Type().IsSignedType(): | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Complex128Value(complex(float64(int64(v)), 0))}).normalize(ctx, n) | ||
|  | 		default: | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Complex128Value(complex(float64(v), 0))}).normalize(ctx, n) | ||
|  | 		} | ||
|  | 	case Float: | ||
|  | 		switch { | ||
|  | 		case o.Type().IsSignedType(): | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Float32Value(float64(int64(v)))}).normalize(ctx, n) | ||
|  | 		default: | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Float32Value(float64(v))}).normalize(ctx, n) | ||
|  | 		} | ||
|  | 	case ComplexLongDouble: | ||
|  | 		panic(todo("", n.Position())) | ||
|  | 	case Double: | ||
|  | 		switch { | ||
|  | 		case o.Type().IsSignedType(): | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Float64Value(int64(v))}).normalize(ctx, n) | ||
|  | 		default: | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: Float64Value(v)}).normalize(ctx, n) | ||
|  | 		} | ||
|  | 	case LongDouble: | ||
|  | 		switch { | ||
|  | 		case o.Type().IsSignedType(): | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: &Float128Value{N: big.NewFloat(0).SetInt64(int64(v))}}).normalize(ctx, n) | ||
|  | 		default: | ||
|  | 			return (&operand{abi: o.abi, typ: to, value: &Float128Value{N: big.NewFloat(0).SetUint64(v)}}).normalize(ctx, n) | ||
|  | 		} | ||
|  | 	case Ptr: | ||
|  | 		return (&operand{abi: o.abi, typ: to, value: Uint64Value(v)}).normalize(ctx, n) | ||
|  | 	case Struct, Union, Array, Void, Int128, UInt128: | ||
|  | 		return &operand{abi: o.abi, typ: to} | ||
|  | 	case Vector: | ||
|  | 		if o.Type().Size() == to.Size() { | ||
|  | 			return &operand{abi: o.abi, typ: to} | ||
|  | 		} | ||
|  | 	} | ||
|  | 	if ctx != nil { | ||
|  | 		ctx.errNode(n, "cannot convert %s to %s", o.Type(), to) | ||
|  | 	} | ||
|  | 	return &operand{abi: o.abi, typ: to} | ||
|  | } | ||
|  | 
 | ||
|  | func (o *operand) normalize(ctx *context, n Node) (r Operand) { | ||
|  | 	if o.Type() == nil { | ||
|  | 		ctx.errNode(n, "operand has unsupported, invalid or incomplete type") | ||
|  | 		return noOperand | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if o.Type().IsIntegerType() { | ||
|  | 		switch { | ||
|  | 		case o.Type().IsSignedType(): | ||
|  | 			if x, ok := o.value.(Uint64Value); ok { | ||
|  | 				o.value = Int64Value(x) | ||
|  | 			} | ||
|  | 		default: | ||
|  | 			if x, ok := o.value.(Int64Value); ok { | ||
|  | 				o.value = Uint64Value(x) | ||
|  | 			} | ||
|  | 		} | ||
|  | 		switch x := o.Value().(type) { | ||
|  | 		case Int64Value: | ||
|  | 			if v := convertInt64(int64(x), o.Type(), o.abi); v != int64(x) { | ||
|  | 				o.value = Int64Value(v) | ||
|  | 			} | ||
|  | 		case Uint64Value: | ||
|  | 			v := uint64(x) | ||
|  | 			switch o.Type().Size() { | ||
|  | 			case 1: | ||
|  | 				v &= 0xff | ||
|  | 			case 2: | ||
|  | 				v &= 0xffff | ||
|  | 			case 4: | ||
|  | 				v &= 0xffffffff | ||
|  | 			} | ||
|  | 			if v != uint64(x) { | ||
|  | 				o.value = Uint64Value(v) | ||
|  | 			} | ||
|  | 		case *InitializerValue, nil: | ||
|  | 			// ok | ||
|  | 		default: | ||
|  | 			panic(internalErrorf("%T %v", x, x)) | ||
|  | 		} | ||
|  | 		return o | ||
|  | 	} | ||
|  | 
 | ||
|  | 	switch o.Type().Kind() { | ||
|  | 	case ComplexFloat: | ||
|  | 		switch o.Value().(type) { | ||
|  | 		case Complex64Value, nil: | ||
|  | 			return o | ||
|  | 		default: | ||
|  | 			panic(todo("")) | ||
|  | 		} | ||
|  | 	case ComplexDouble: | ||
|  | 		switch o.Value().(type) { | ||
|  | 		case Complex128Value, nil: | ||
|  | 			return o | ||
|  | 		default: | ||
|  | 			panic(todo("")) | ||
|  | 		} | ||
|  | 	case ComplexLongDouble: | ||
|  | 		switch o.Value().(type) { | ||
|  | 		case Complex256Value, nil: | ||
|  | 			return o | ||
|  | 		default: | ||
|  | 			panic(todo("934 %v", o.Type().Kind())) | ||
|  | 		} | ||
|  | 	case Float: | ||
|  | 		switch o.Value().(type) { | ||
|  | 		case Float32Value, *InitializerValue, nil: | ||
|  | 			return o | ||
|  | 		default: | ||
|  | 			panic(todo("")) | ||
|  | 		} | ||
|  | 	case Double: | ||
|  | 		switch x := o.Value().(type) { | ||
|  | 		case Float64Value, *InitializerValue, nil: | ||
|  | 			return o | ||
|  | 		default: | ||
|  | 			panic(internalErrorf("%T %v", x, x)) | ||
|  | 		} | ||
|  | 	case LongDouble: | ||
|  | 		switch x := o.Value().(type) { | ||
|  | 		case *Float128Value, nil: | ||
|  | 			return o | ||
|  | 		default: | ||
|  | 			panic(internalErrorf("%T %v TODO980 %v", x, x, n.Position())) | ||
|  | 		} | ||
|  | 	case Ptr: | ||
|  | 		switch o.Value().(type) { | ||
|  | 		case Int64Value, Uint64Value, *InitializerValue, StringValue, WideStringValue, nil: | ||
|  | 			return o | ||
|  | 		default: | ||
|  | 			panic(todo("")) | ||
|  | 		} | ||
|  | 	case Array, Void, Function, Struct, Union, Vector, Decimal32, Decimal64, Decimal128: | ||
|  | 		return o | ||
|  | 	case ComplexChar, ComplexInt, ComplexLong, ComplexLongLong, ComplexShort, ComplexUInt, ComplexUShort: | ||
|  | 		//TOD | ||
|  | 		if ctx != nil { | ||
|  | 			ctx.errNode(n, "unsupported type: %s", o.Type()) | ||
|  | 		} | ||
|  | 		return noOperand | ||
|  | 	} | ||
|  | 	panic(internalErrorf("%v, %v", o.Type(), o.Type().Kind())) | ||
|  | } | ||
|  | 
 | ||
|  | func convertInt64(n int64, t Type, abi *ABI) int64 { | ||
|  | 	k := t.Kind() | ||
|  | 	if k == Enum { | ||
|  | 		//TODO | ||
|  | 	} | ||
|  | 	signed := abi.isSignedInteger(k) | ||
|  | 	switch sz := abi.size(k); sz { | ||
|  | 	case 1: | ||
|  | 		switch { | ||
|  | 		case signed: | ||
|  | 			switch { | ||
|  | 			case int8(n) < 0: | ||
|  | 				return n | ^math.MaxUint8 | ||
|  | 			default: | ||
|  | 				return n & math.MaxUint8 | ||
|  | 			} | ||
|  | 		default: | ||
|  | 			return n & math.MaxUint8 | ||
|  | 		} | ||
|  | 	case 2: | ||
|  | 		switch { | ||
|  | 		case signed: | ||
|  | 			switch { | ||
|  | 			case int16(n) < 0: | ||
|  | 				return n | ^math.MaxUint16 | ||
|  | 			default: | ||
|  | 				return n & math.MaxUint16 | ||
|  | 			} | ||
|  | 		default: | ||
|  | 			return n & math.MaxUint16 | ||
|  | 		} | ||
|  | 	case 4: | ||
|  | 		switch { | ||
|  | 		case signed: | ||
|  | 			switch { | ||
|  | 			case int32(n) < 0: | ||
|  | 				return n | ^math.MaxUint32 | ||
|  | 			default: | ||
|  | 				return n & math.MaxUint32 | ||
|  | 			} | ||
|  | 		default: | ||
|  | 			return n & math.MaxUint32 | ||
|  | 		} | ||
|  | 	default: | ||
|  | 		return n | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func boolValue(b bool) Value { | ||
|  | 	if b { | ||
|  | 		return Int64Value(1) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return Int64Value(0) | ||
|  | } | ||
|  | 
 | ||
|  | type initializer interface { | ||
|  | 	List() []*Initializer | ||
|  | 	IsConst() bool | ||
|  | } | ||
|  | 
 | ||
|  | type InitializerValue struct { | ||
|  | 	typ         Type | ||
|  | 	initializer initializer | ||
|  | } | ||
|  | 
 | ||
|  | func (v *InitializerValue) List() []*Initializer { | ||
|  | 	if v == nil || v.initializer == nil { | ||
|  | 		return nil | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return v.initializer.List() | ||
|  | } | ||
|  | 
 | ||
|  | func (v *InitializerValue) IsConst() bool { | ||
|  | 	return v != nil && v.initializer != nil && v.initializer.IsConst() | ||
|  | } | ||
|  | func (v *InitializerValue) Type() Type        { return v.typ } | ||
|  | func (v *InitializerValue) add(b Value) Value { return nil } | ||
|  | func (v *InitializerValue) and(b Value) Value { return nil } | ||
|  | func (v *InitializerValue) cpl() Value        { return nil } | ||
|  | func (v *InitializerValue) div(b Value) Value { return nil } | ||
|  | func (v *InitializerValue) eq(b Value) Value  { return nil } | ||
|  | func (v *InitializerValue) ge(b Value) Value  { return nil } | ||
|  | func (v *InitializerValue) gt(b Value) Value  { return nil } | ||
|  | func (v *InitializerValue) le(b Value) Value  { return nil } | ||
|  | func (v *InitializerValue) lsh(b Value) Value { return nil } | ||
|  | func (v *InitializerValue) lt(b Value) Value  { return nil } | ||
|  | func (v *InitializerValue) mod(b Value) Value { return nil } | ||
|  | func (v *InitializerValue) mul(b Value) Value { return nil } | ||
|  | func (v *InitializerValue) neg() Value        { return nil } | ||
|  | func (v *InitializerValue) neq(b Value) Value { return nil } | ||
|  | func (v *InitializerValue) or(b Value) Value  { return nil } | ||
|  | func (v *InitializerValue) rsh(b Value) Value { return nil } | ||
|  | func (v *InitializerValue) sub(b Value) Value { return nil } | ||
|  | func (v *InitializerValue) xor(b Value) Value { return nil } | ||
|  | 
 | ||
|  | func (v *InitializerValue) IsNonZero() bool { | ||
|  | 	if v == nil { | ||
|  | 		return false | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, v := range v.List() { | ||
|  | 		if !v.AssignmentExpression.Operand.IsZero() { | ||
|  | 			return true | ||
|  | 		} | ||
|  | 	} | ||
|  | 	return false | ||
|  | } | ||
|  | 
 | ||
|  | func (v *InitializerValue) IsZero() bool { | ||
|  | 	if v == nil { | ||
|  | 		return false | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, v := range v.List() { | ||
|  | 		if !v.AssignmentExpression.Operand.IsZero() { | ||
|  | 			return false | ||
|  | 		} | ||
|  | 	} | ||
|  | 	return true | ||
|  | } |