| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | // Copyright 2009 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 gc | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-02 16:03:26 -05:00
										 |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-05-21 13:28:10 -04:00
										 |  |  | 	"cmd/compile/internal/big" | 
					
						
							| 
									
										
										
										
											2015-03-02 16:03:26 -05:00
										 |  |  | 	"cmd/internal/obj" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 18:56:47 +10:00
										 |  |  | // IntLiteral returns the Node's literal value as an interger. | 
					
						
							|  |  |  | func (n *Node) IntLiteral() (x int64, ok bool) { | 
					
						
							|  |  |  | 	switch { | 
					
						
							|  |  |  | 	case n == nil: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	case Isconst(n, CTINT): | 
					
						
							|  |  |  | 		return n.Int(), true | 
					
						
							|  |  |  | 	case Isconst(n, CTBOOL): | 
					
						
							|  |  |  | 		return int64(obj.Bool2int(n.Bool())), true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-22 20:08:03 -07:00
										 |  |  | // Int returns n as an int. | 
					
						
							|  |  |  | // n must be an integer constant. | 
					
						
							|  |  |  | func (n *Node) Int() int64 { | 
					
						
							|  |  |  | 	if !Isconst(n, CTINT) { | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 		Fatalf("Int(%v)", n) | 
					
						
							| 
									
										
										
										
											2015-04-22 20:08:03 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	return n.Val().U.(*Mpint).Int64() | 
					
						
							| 
									
										
										
										
											2015-04-22 20:08:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SetInt sets n's value to i. | 
					
						
							|  |  |  | // n must be an integer constant. | 
					
						
							|  |  |  | func (n *Node) SetInt(i int64) { | 
					
						
							|  |  |  | 	if !Isconst(n, CTINT) { | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 		Fatalf("SetInt(%v)", n) | 
					
						
							| 
									
										
										
										
											2015-04-22 20:08:03 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	n.Val().U.(*Mpint).SetInt64(i) | 
					
						
							| 
									
										
										
										
											2015-04-22 20:08:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SetBigInt sets n's value to x. | 
					
						
							|  |  |  | // n must be an integer constant. | 
					
						
							|  |  |  | func (n *Node) SetBigInt(x *big.Int) { | 
					
						
							|  |  |  | 	if !Isconst(n, CTINT) { | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 		Fatalf("SetBigInt(%v)", n) | 
					
						
							| 
									
										
										
										
											2015-04-22 20:08:03 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 	n.Val().U.(*Mpint).Val.Set(x) | 
					
						
							| 
									
										
										
										
											2015-04-22 20:08:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-07 18:43:03 -07:00
										 |  |  | // Bool returns n as an bool. | 
					
						
							|  |  |  | // n must be an boolean constant. | 
					
						
							|  |  |  | func (n *Node) Bool() bool { | 
					
						
							|  |  |  | 	if !Isconst(n, CTBOOL) { | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 		Fatalf("Int(%v)", n) | 
					
						
							| 
									
										
										
										
											2015-05-07 18:43:03 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 	return n.Val().U.(bool) | 
					
						
							| 
									
										
										
										
											2015-05-07 18:43:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-22 09:51:12 +09:00
										 |  |  | // truncate float literal fv to 32-bit or 64-bit precision | 
					
						
							|  |  |  | // according to type; return truncated value. | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | func truncfltlit(oldv *Mpflt, t *Type) *Mpflt { | 
					
						
							|  |  |  | 	if t == nil { | 
					
						
							|  |  |  | 		return oldv | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-02 14:22:05 -05:00
										 |  |  | 	var v Val | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 	v.U = oldv | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	overflow(v, t) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:59:08 -07:00
										 |  |  | 	fv := newMpflt() | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	fv.Set(oldv) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// convert large precision literal floating | 
					
						
							|  |  |  | 	// into limited precision (float64 or float32) | 
					
						
							|  |  |  | 	switch t.Etype { | 
					
						
							|  |  |  | 	case TFLOAT64: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		d := fv.Float64() | 
					
						
							|  |  |  | 		fv.SetFloat64(d) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case TFLOAT32: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		d := fv.Float32() | 
					
						
							|  |  |  | 		fv.SetFloat64(d) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return fv | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | // NegOne returns a Node of type t with value -1. | 
					
						
							|  |  |  | func NegOne(t *Type) *Node { | 
					
						
							|  |  |  | 	n := Nodintconst(-1) | 
					
						
							|  |  |  | 	convlit(&n, t) | 
					
						
							|  |  |  | 	return n | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-22 09:51:12 +09:00
										 |  |  | // convert n, if literal, to type t. | 
					
						
							|  |  |  | // implicit conversion. | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | func convlit(np **Node, t *Type) { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	convlit1(np, t, false) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-22 09:51:12 +09:00
										 |  |  | // convert n, if literal, to type t. | 
					
						
							|  |  |  | // return a new node if necessary | 
					
						
							|  |  |  | //(if n is a named constant, can't edit n->type directly). | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | func convlit1(np **Node, t *Type, explicit bool) { | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	n := *np | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if n == nil || t == nil || n.Type == nil || isideal(t) || n.Type == t { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if !explicit && !isideal(n.Type) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if n.Op == OLITERAL { | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		nn := Nod(OXXX, nil, nil) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		*nn = *n | 
					
						
							|  |  |  | 		n = nn | 
					
						
							|  |  |  | 		*np = n | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch n.Op { | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		if n.Type == idealbool { | 
					
						
							|  |  |  | 			if t.Etype == TBOOL { | 
					
						
							|  |  |  | 				n.Type = t | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				n.Type = Types[TBOOL] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if n.Type.Etype == TIDEAL { | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 			convlit(&n.Left, t) | 
					
						
							|  |  |  | 			convlit(&n.Right, t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			n.Type = t | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// target is invalid type for a constant?  leave alone. | 
					
						
							|  |  |  | 	case OLITERAL: | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if !okforconst[t.Etype] && n.Type.Etype != TNIL { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			defaultlit(&n, nil) | 
					
						
							|  |  |  | 			*np = n | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case OLSH, ORSH: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		convlit1(&n.Left, t, explicit && isideal(n.Left.Type)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		t = n.Left.Type | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT { | 
					
						
							|  |  |  | 			n.SetVal(toint(n.Val())) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if t != nil && !Isint[t.Etype] { | 
					
						
							| 
									
										
										
										
											2015-04-17 12:03:22 -04:00
										 |  |  | 			Yyerror("invalid operation: %v (shift of type %v)", n, t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			t = nil | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		n.Type = t | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OCOMPLEX: | 
					
						
							|  |  |  | 		if n.Type.Etype == TIDEAL { | 
					
						
							|  |  |  | 			switch t.Etype { | 
					
						
							|  |  |  | 			// If trying to convert to non-complex type, | 
					
						
							|  |  |  | 			// leave as complex128 and let typechecker complain. | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				t = Types[TCOMPLEX128] | 
					
						
							|  |  |  | 				fallthrough | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				//fallthrough | 
					
						
							|  |  |  | 			case TCOMPLEX128: | 
					
						
							|  |  |  | 				n.Type = t | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 				convlit(&n.Left, Types[TFLOAT64]) | 
					
						
							|  |  |  | 				convlit(&n.Right, Types[TFLOAT64]) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			case TCOMPLEX64: | 
					
						
							|  |  |  | 				n.Type = t | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 				convlit(&n.Left, Types[TFLOAT32]) | 
					
						
							|  |  |  | 				convlit(&n.Right, Types[TFLOAT32]) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// avoided repeated calculations, errors | 
					
						
							|  |  |  | 	if Eqtype(n.Type, t) { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	ct := consttype(n) | 
					
						
							| 
									
										
										
										
											2016-02-29 20:07:09 -08:00
										 |  |  | 	var et EType | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if ct < 0 { | 
					
						
							|  |  |  | 		goto bad | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:07:09 -08:00
										 |  |  | 	et = t.Etype | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if et == TINTER { | 
					
						
							|  |  |  | 		if ct == CTNIL && n.Type == Types[TNIL] { | 
					
						
							|  |  |  | 			n.Type = t | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		defaultlit(np, nil) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch ct { | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		goto bad | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case CTNIL: | 
					
						
							|  |  |  | 		switch et { | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			n.Type = nil | 
					
						
							|  |  |  | 			goto bad | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// let normal conversion code handle it | 
					
						
							|  |  |  | 		case TSTRING: | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case TARRAY: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			if !Isslice(t) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 				goto bad | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case TPTR32, | 
					
						
							|  |  |  | 			TPTR64, | 
					
						
							|  |  |  | 			TINTER, | 
					
						
							|  |  |  | 			TMAP, | 
					
						
							|  |  |  | 			TCHAN, | 
					
						
							|  |  |  | 			TFUNC, | 
					
						
							|  |  |  | 			TUNSAFEPTR: | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// A nil literal may be converted to uintptr | 
					
						
							|  |  |  | 		// if it is an unsafe.Pointer | 
					
						
							|  |  |  | 		case TUINTPTR: | 
					
						
							|  |  |  | 			if n.Type.Etype == TUNSAFEPTR { | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 				n.SetVal(Val{new(Mpint)}) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 				n.Val().U.(*Mpint).SetInt64(0) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				goto bad | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case CTSTR, CTBOOL: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:07:09 -08:00
										 |  |  | 		if et != n.Type.Etype { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto bad | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case CTINT, CTRUNE, CTFLT, CTCPLX: | 
					
						
							| 
									
										
										
										
											2015-05-01 19:50:27 -07:00
										 |  |  | 		if n.Type.Etype == TUNSAFEPTR && t.Etype != TUINTPTR { | 
					
						
							|  |  |  | 			goto bad | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-10-26 16:00:59 -07:00
										 |  |  | 		ct := n.Val().Ctype() | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if Isint[et] { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			switch ct { | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				goto bad | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 			case CTCPLX, CTFLT, CTRUNE: | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 				n.SetVal(toint(n.Val())) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 				fallthrough | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case CTINT: | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 				overflow(n.Val(), t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		} else if Isfloat[et] { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			switch ct { | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				goto bad | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 			case CTCPLX, CTINT, CTRUNE: | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 				n.SetVal(toflt(n.Val())) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 				fallthrough | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case CTFLT: | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 				n.SetVal(Val{truncfltlit(n.Val().U.(*Mpflt), t)}) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		} else if Iscomplex[et] { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			switch ct { | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				goto bad | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 			case CTFLT, CTINT, CTRUNE: | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 				n.SetVal(tocplx(n.Val())) | 
					
						
							| 
									
										
										
										
											2015-11-04 15:47:48 -05:00
										 |  |  | 				fallthrough | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			case CTCPLX: | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 				overflow(n.Val(), t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		} else if et == TSTRING && (ct == CTINT || ct == CTRUNE) && explicit { | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 			n.SetVal(tostr(n.Val())) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			goto bad | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	n.Type = t | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bad: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if n.Diag == 0 { | 
					
						
							| 
									
										
										
										
											2015-09-07 10:37:26 +10:00
										 |  |  | 		if !t.Broke { | 
					
						
							| 
									
										
										
										
											2015-04-17 12:03:22 -04:00
										 |  |  | 			Yyerror("cannot convert %v to type %v", n, t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		n.Diag = 1 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if isideal(n.Type) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		defaultlit(&n, nil) | 
					
						
							|  |  |  | 		*np = n | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func copyval(v Val) Val { | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	switch v.Ctype() { | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case CTINT, CTRUNE: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		i := new(Mpint) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		i.Set(v.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 		i.Rune = v.U.(*Mpint).Rune | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = i | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTFLT: | 
					
						
							| 
									
										
										
										
											2015-03-20 16:59:08 -07:00
										 |  |  | 		f := newMpflt() | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		f.Set(v.U.(*Mpflt)) | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = f | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTCPLX: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		c := new(Mpcplx) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		c.Real.Set(&v.U.(*Mpcplx).Real) | 
					
						
							|  |  |  | 		c.Imag.Set(&v.U.(*Mpcplx).Imag) | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = c | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return v | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func tocplx(v Val) Val { | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	switch v.Ctype() { | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case CTINT, CTRUNE: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		c := new(Mpcplx) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		c.Real.SetInt(v.U.(*Mpint)) | 
					
						
							|  |  |  | 		c.Imag.SetFloat64(0.0) | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = c | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTFLT: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		c := new(Mpcplx) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		c.Real.Set(v.U.(*Mpflt)) | 
					
						
							|  |  |  | 		c.Imag.SetFloat64(0.0) | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = c | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return v | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func toflt(v Val) Val { | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	switch v.Ctype() { | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case CTINT, CTRUNE: | 
					
						
							| 
									
										
										
										
											2015-03-20 16:59:08 -07:00
										 |  |  | 		f := newMpflt() | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		f.SetInt(v.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = f | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTCPLX: | 
					
						
							| 
									
										
										
										
											2015-03-20 16:59:08 -07:00
										 |  |  | 		f := newMpflt() | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		f.Set(&v.U.(*Mpcplx).Real) | 
					
						
							|  |  |  | 		if v.U.(*Mpcplx).Imag.CmpFloat64(0) != 0 { | 
					
						
							| 
									
										
										
										
											2016-03-15 13:06:58 -07:00
										 |  |  | 			Yyerror("constant %v%vi truncated to real", Fconv(&v.U.(*Mpcplx).Real, FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, FmtSharp|FmtSign)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = f | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return v | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func toint(v Val) Val { | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	switch v.Ctype() { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	case CTRUNE: | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 		i := new(Mpint) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		i.Set(v.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 		v.U = i | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTFLT: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		i := new(Mpint) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if f := v.U.(*Mpflt); i.SetFloat(f) < 0 { | 
					
						
							| 
									
										
										
										
											2015-12-03 15:51:03 -08:00
										 |  |  | 			msg := "constant %v truncated to integer" | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			// provide better error message if SetFloat failed because f was too large | 
					
						
							| 
									
										
										
										
											2015-12-03 15:51:03 -08:00
										 |  |  | 			if f.Val.IsInt() { | 
					
						
							|  |  |  | 				msg = "constant %v overflows integer" | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-03-15 13:06:58 -07:00
										 |  |  | 			Yyerror(msg, Fconv(f, FmtSharp)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = i | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTCPLX: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		i := new(Mpint) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if i.SetFloat(&v.U.(*Mpcplx).Real) < 0 { | 
					
						
							| 
									
										
										
										
											2016-03-15 13:06:58 -07:00
										 |  |  | 			Yyerror("constant %v%vi truncated to integer", Fconv(&v.U.(*Mpcplx).Real, FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, FmtSharp|FmtSign)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpcplx).Imag.CmpFloat64(0) != 0 { | 
					
						
							| 
									
										
										
										
											2016-03-15 13:06:58 -07:00
										 |  |  | 			Yyerror("constant %v%vi truncated to real", Fconv(&v.U.(*Mpcplx).Real, FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, FmtSharp|FmtSign)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = i | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return v | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | func doesoverflow(v Val, t *Type) bool { | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	switch v.Ctype() { | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case CTINT, CTRUNE: | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if !Isint[t.Etype] { | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 			Fatalf("overflow: %v integer constant", t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpint).Cmp(Minintval[t.Etype]) < 0 || v.U.(*Mpint).Cmp(Maxintval[t.Etype]) > 0 { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case CTFLT: | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if !Isfloat[t.Etype] { | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 			Fatalf("overflow: %v floating-point constant", t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpflt).Cmp(minfltval[t.Etype]) <= 0 || v.U.(*Mpflt).Cmp(maxfltval[t.Etype]) >= 0 { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case CTCPLX: | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if !Iscomplex[t.Etype] { | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 			Fatalf("overflow: %v complex constant", t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpcplx).Real.Cmp(minfltval[t.Etype]) <= 0 || v.U.(*Mpcplx).Real.Cmp(maxfltval[t.Etype]) >= 0 || v.U.(*Mpcplx).Imag.Cmp(minfltval[t.Etype]) <= 0 || v.U.(*Mpcplx).Imag.Cmp(maxfltval[t.Etype]) >= 0 { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	return false | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func overflow(v Val, t *Type) { | 
					
						
							|  |  |  | 	// v has already been converted | 
					
						
							|  |  |  | 	// to appropriate form for t. | 
					
						
							|  |  |  | 	if t == nil || t.Etype == TIDEAL { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-01 19:50:27 -07:00
										 |  |  | 	// Only uintptrs may be converted to unsafe.Pointer, which cannot overflow. | 
					
						
							|  |  |  | 	if t.Etype == TUNSAFEPTR { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-15 11:16:58 -07:00
										 |  |  | 	if doesoverflow(v, t) { | 
					
						
							|  |  |  | 		Yyerror("constant %s overflows %v", Vconv(v, 0), t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func tostr(v Val) Val { | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	switch v.Ctype() { | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case CTINT, CTRUNE: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpint).Cmp(Minintval[TINT]) < 0 || v.U.(*Mpint).Cmp(Maxintval[TINT]) > 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			Yyerror("overflow in int -> string") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		r := uint(v.U.(*Mpint).Int64()) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		v = Val{} | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = string(r) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTFLT: | 
					
						
							|  |  |  | 		Yyerror("no float -> string") | 
					
						
							|  |  |  | 		fallthrough | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case CTNIL: | 
					
						
							|  |  |  | 		v = Val{} | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		v.U = "" | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return v | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 16:00:59 -07:00
										 |  |  | func consttype(n *Node) Ctype { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if n == nil || n.Op != OLITERAL { | 
					
						
							|  |  |  | 		return -1 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-10-26 16:00:59 -07:00
										 |  |  | 	return n.Val().Ctype() | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 16:00:59 -07:00
										 |  |  | func Isconst(n *Node, ct Ctype) bool { | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	t := consttype(n) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// If the caller is asking for CTINT, allow CTRUNE too. | 
					
						
							|  |  |  | 	// Makes life easier for back ends. | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	return t == ct || (ct == CTINT && t == CTRUNE) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func saveorig(n *Node) *Node { | 
					
						
							|  |  |  | 	if n == n.Orig { | 
					
						
							|  |  |  | 		// duplicate node for n->orig. | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		n1 := Nod(OLITERAL, nil, nil) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		n.Orig = n1 | 
					
						
							|  |  |  | 		*n1 = *n | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n.Orig | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-22 09:51:12 +09:00
										 |  |  | // if n is constant, rewrite as OLITERAL node. | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | func evconst(n *Node) { | 
					
						
							|  |  |  | 	// pick off just the opcodes that can be | 
					
						
							|  |  |  | 	// constant evaluated. | 
					
						
							|  |  |  | 	switch n.Op { | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OADD, | 
					
						
							|  |  |  | 		OAND, | 
					
						
							|  |  |  | 		OANDAND, | 
					
						
							|  |  |  | 		OANDNOT, | 
					
						
							|  |  |  | 		OARRAYBYTESTR, | 
					
						
							|  |  |  | 		OCOM, | 
					
						
							|  |  |  | 		ODIV, | 
					
						
							|  |  |  | 		OEQ, | 
					
						
							|  |  |  | 		OGE, | 
					
						
							|  |  |  | 		OGT, | 
					
						
							|  |  |  | 		OLE, | 
					
						
							|  |  |  | 		OLSH, | 
					
						
							|  |  |  | 		OLT, | 
					
						
							|  |  |  | 		OMINUS, | 
					
						
							|  |  |  | 		OMOD, | 
					
						
							|  |  |  | 		OMUL, | 
					
						
							|  |  |  | 		ONE, | 
					
						
							|  |  |  | 		ONOT, | 
					
						
							|  |  |  | 		OOR, | 
					
						
							|  |  |  | 		OOROR, | 
					
						
							|  |  |  | 		OPLUS, | 
					
						
							|  |  |  | 		ORSH, | 
					
						
							|  |  |  | 		OSUB, | 
					
						
							|  |  |  | 		OXOR: | 
					
						
							|  |  |  | 		break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OCONV: | 
					
						
							|  |  |  | 		if n.Type == nil { | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if !okforconst[n.Type.Etype] && n.Type.Etype != TNIL { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// merge adjacent constants in the argument list. | 
					
						
							|  |  |  | 	case OADDSTR: | 
					
						
							| 
									
										
										
										
											2016-03-08 15:10:26 -08:00
										 |  |  | 		s := n.List.Slice() | 
					
						
							| 
									
										
										
										
											2016-03-07 09:36:24 -08:00
										 |  |  | 		for i1 := 0; i1 < len(s); i1++ { | 
					
						
							|  |  |  | 			if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) { | 
					
						
							|  |  |  | 				// merge from i1 up to but not including i2 | 
					
						
							|  |  |  | 				var strs []string | 
					
						
							|  |  |  | 				i2 := i1 | 
					
						
							|  |  |  | 				for i2 < len(s) && Isconst(s[i2], CTSTR) { | 
					
						
							|  |  |  | 					strs = append(strs, s[i2].Val().U.(string)) | 
					
						
							|  |  |  | 					i2++ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				nl := Nod(OXXX, nil, nil) | 
					
						
							|  |  |  | 				*nl = *s[i1] | 
					
						
							|  |  |  | 				nl.Orig = nl | 
					
						
							|  |  |  | 				nl.SetVal(Val{strings.Join(strs, "")}) | 
					
						
							|  |  |  | 				s[i1] = nl | 
					
						
							|  |  |  | 				s = append(s[:i1+1], s[i2:]...) | 
					
						
							| 
									
										
										
										
											2015-06-09 18:37:26 -07:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 09:36:24 -08:00
										 |  |  | 		if len(s) == 1 && Isconst(s[0], CTSTR) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			n.Op = OLITERAL | 
					
						
							| 
									
										
										
										
											2016-03-07 09:36:24 -08:00
										 |  |  | 			n.SetVal(s[0].Val()) | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2016-03-08 15:10:26 -08:00
										 |  |  | 			n.List.Set(s) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	nl := n.Left | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if nl == nil || nl.Type == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if consttype(nl) < 0 { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-02-29 20:07:09 -08:00
										 |  |  | 	wl := nl.Type.Etype | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 	if Isint[wl] || Isfloat[wl] || Iscomplex[wl] { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		wl = TIDEAL | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 16:00:59 -07:00
										 |  |  | 	// avoid constant conversions in switches below | 
					
						
							|  |  |  | 	const ( | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		CTINT_         = uint32(CTINT) | 
					
						
							|  |  |  | 		CTRUNE_        = uint32(CTRUNE) | 
					
						
							|  |  |  | 		CTFLT_         = uint32(CTFLT) | 
					
						
							|  |  |  | 		CTCPLX_        = uint32(CTCPLX) | 
					
						
							|  |  |  | 		CTSTR_         = uint32(CTSTR) | 
					
						
							|  |  |  | 		CTBOOL_        = uint32(CTBOOL) | 
					
						
							|  |  |  | 		CTNIL_         = uint32(CTNIL) | 
					
						
							|  |  |  | 		OCONV_         = uint32(OCONV) << 16 | 
					
						
							|  |  |  | 		OARRAYBYTESTR_ = uint32(OARRAYBYTESTR) << 16 | 
					
						
							|  |  |  | 		OPLUS_         = uint32(OPLUS) << 16 | 
					
						
							|  |  |  | 		OMINUS_        = uint32(OMINUS) << 16 | 
					
						
							|  |  |  | 		OCOM_          = uint32(OCOM) << 16 | 
					
						
							|  |  |  | 		ONOT_          = uint32(ONOT) << 16 | 
					
						
							|  |  |  | 		OLSH_          = uint32(OLSH) << 16 | 
					
						
							|  |  |  | 		ORSH_          = uint32(ORSH) << 16 | 
					
						
							|  |  |  | 		OADD_          = uint32(OADD) << 16 | 
					
						
							|  |  |  | 		OSUB_          = uint32(OSUB) << 16 | 
					
						
							|  |  |  | 		OMUL_          = uint32(OMUL) << 16 | 
					
						
							|  |  |  | 		ODIV_          = uint32(ODIV) << 16 | 
					
						
							|  |  |  | 		OMOD_          = uint32(OMOD) << 16 | 
					
						
							|  |  |  | 		OOR_           = uint32(OOR) << 16 | 
					
						
							|  |  |  | 		OAND_          = uint32(OAND) << 16 | 
					
						
							|  |  |  | 		OANDNOT_       = uint32(OANDNOT) << 16 | 
					
						
							|  |  |  | 		OXOR_          = uint32(OXOR) << 16 | 
					
						
							|  |  |  | 		OEQ_           = uint32(OEQ) << 16 | 
					
						
							|  |  |  | 		ONE_           = uint32(ONE) << 16 | 
					
						
							|  |  |  | 		OLT_           = uint32(OLT) << 16 | 
					
						
							|  |  |  | 		OLE_           = uint32(OLE) << 16 | 
					
						
							|  |  |  | 		OGE_           = uint32(OGE) << 16 | 
					
						
							|  |  |  | 		OGT_           = uint32(OGT) << 16 | 
					
						
							|  |  |  | 		OOROR_         = uint32(OOROR) << 16 | 
					
						
							|  |  |  | 		OANDAND_       = uint32(OANDAND) << 16 | 
					
						
							| 
									
										
										
										
											2015-10-26 16:00:59 -07:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	nr := n.Right | 
					
						
							|  |  |  | 	var rv Val | 
					
						
							| 
									
										
										
										
											2016-03-02 17:34:42 -08:00
										 |  |  | 	var lno int32 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:07:09 -08:00
										 |  |  | 	var wr EType | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	var v Val | 
					
						
							|  |  |  | 	var norig *Node | 
					
						
							| 
									
										
										
										
											2016-01-07 03:06:49 -08:00
										 |  |  | 	var nn *Node | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if nr == nil { | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 		// copy numeric value to avoid modifying | 
					
						
							|  |  |  | 		// nl, in case someone still refers to it (e.g. iota). | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		v = nl.Val() | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if wl == TIDEAL { | 
					
						
							|  |  |  | 			v = copyval(v) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 		switch uint32(n.Op)<<16 | uint32(v.Ctype()) { | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			if n.Diag == 0 { | 
					
						
							| 
									
										
										
										
											2016-03-07 08:23:55 -08:00
										 |  |  | 				Yyerror("illegal constant expression %v %v", Oconv(n.Op, 0), nl.Type) | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 				n.Diag = 1 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case OCONV_ | CTNIL_, | 
					
						
							|  |  |  | 			OARRAYBYTESTR_ | CTNIL_: | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 			if n.Type.Etype == TSTRING { | 
					
						
							|  |  |  | 				v = tostr(v) | 
					
						
							|  |  |  | 				nl.Type = n.Type | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			fallthrough | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// fall through | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case OCONV_ | CTINT_, | 
					
						
							|  |  |  | 			OCONV_ | CTRUNE_, | 
					
						
							|  |  |  | 			OCONV_ | CTFLT_, | 
					
						
							| 
									
										
										
										
											2016-01-05 12:26:55 -08:00
										 |  |  | 			OCONV_ | CTSTR_, | 
					
						
							|  |  |  | 			OCONV_ | CTBOOL_: | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 			convlit1(&nl, n.Type, true) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 			v = nl.Val() | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case OPLUS_ | CTINT_, | 
					
						
							|  |  |  | 			OPLUS_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 			break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case OMINUS_ | CTINT_, | 
					
						
							|  |  |  | 			OMINUS_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			v.U.(*Mpint).Neg() | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case OCOM_ | CTINT_, | 
					
						
							|  |  |  | 			OCOM_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:07:09 -08:00
										 |  |  | 			var et EType = Txxx | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 			if nl.Type != nil { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:07:09 -08:00
										 |  |  | 				et = nl.Type.Etype | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// calculate the mask in b | 
					
						
							|  |  |  | 			// result will be (a ^ mask) | 
					
						
							|  |  |  | 			var b Mpint | 
					
						
							|  |  |  | 			switch et { | 
					
						
							|  |  |  | 			// signed guys change sign | 
					
						
							|  |  |  | 			default: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 				b.SetInt64(-1) | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// unsigned guys invert their bits | 
					
						
							|  |  |  | 			case TUINT8, | 
					
						
							|  |  |  | 				TUINT16, | 
					
						
							|  |  |  | 				TUINT32, | 
					
						
							|  |  |  | 				TUINT64, | 
					
						
							|  |  |  | 				TUINT, | 
					
						
							|  |  |  | 				TUINTPTR: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 				b.Set(Maxintval[et]) | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			v.U.(*Mpint).Xor(&b) | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case OPLUS_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 			break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case OMINUS_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			v.U.(*Mpflt).Neg() | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case OPLUS_ | CTCPLX_: | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 			break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case OMINUS_ | CTCPLX_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			v.U.(*Mpcplx).Real.Neg() | 
					
						
							|  |  |  | 			v.U.(*Mpcplx).Imag.Neg() | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 		case ONOT_ | CTBOOL_: | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 			if !v.U.(bool) { | 
					
						
							| 
									
										
										
										
											2015-03-02 12:35:15 -05:00
										 |  |  | 				goto settrue | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			goto setfalse | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto ret | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if nr.Type == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if consttype(nr) < 0 { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-02-29 20:07:09 -08:00
										 |  |  | 	wr = nr.Type.Etype | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 	if Isint[wr] || Isfloat[wr] || Iscomplex[wr] { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		wr = TIDEAL | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check for compatible general types (numeric, string, etc) | 
					
						
							|  |  |  | 	if wl != wr { | 
					
						
							|  |  |  | 		goto illegal | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check for compatible types. | 
					
						
							|  |  |  | 	switch n.Op { | 
					
						
							|  |  |  | 	// ideal const mixes with anything but otherwise must match. | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		if nl.Type.Etype != TIDEAL { | 
					
						
							|  |  |  | 			defaultlit(&nr, nl.Type) | 
					
						
							|  |  |  | 			n.Right = nr | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if nr.Type.Etype != TIDEAL { | 
					
						
							|  |  |  | 			defaultlit(&nl, nr.Type) | 
					
						
							|  |  |  | 			n.Left = nl | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if nl.Type.Etype != nr.Type.Etype { | 
					
						
							|  |  |  | 			goto illegal | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// right must be unsigned. | 
					
						
							|  |  |  | 	// left can be ideal. | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case OLSH, ORSH: | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		defaultlit(&nr, Types[TUINT]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		n.Right = nr | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if nr.Type != nil && (Issigned[nr.Type.Etype] || !Isint[nr.Type.Etype]) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto illegal | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		if nl.Val().Ctype() != CTRUNE { | 
					
						
							|  |  |  | 			nl.SetVal(toint(nl.Val())) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		nr.SetVal(toint(nr.Val())) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// copy numeric value to avoid modifying | 
					
						
							|  |  |  | 	// n->left, in case someone still refers to it (e.g. iota). | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 	v = nl.Val() | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if wl == TIDEAL { | 
					
						
							|  |  |  | 		v = copyval(v) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 	rv = nr.Val() | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// convert to common ideal | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	if v.Ctype() == CTCPLX || rv.Ctype() == CTCPLX { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		v = tocplx(v) | 
					
						
							|  |  |  | 		rv = tocplx(rv) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	if v.Ctype() == CTFLT || rv.Ctype() == CTFLT { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		v = toflt(v) | 
					
						
							|  |  |  | 		rv = toflt(rv) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Rune and int turns into rune. | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	if v.Ctype() == CTRUNE && rv.Ctype() == CTINT { | 
					
						
							|  |  |  | 		i := new(Mpint) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		i.Set(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 		i.Rune = true | 
					
						
							|  |  |  | 		rv.U = i | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	if v.Ctype() == CTINT && rv.Ctype() == CTRUNE { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		if n.Op == OLSH || n.Op == ORSH { | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 			i := new(Mpint) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			i.Set(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 			rv.U = i | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 			i := new(Mpint) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			i.Set(v.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 			i.Rune = true | 
					
						
							|  |  |  | 			v.U = i | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	if v.Ctype() != rv.Ctype() { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		// Use of undefined name as constant? | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 		if (v.Ctype() == 0 || rv.Ctype() == 0) && nerrors > 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 		Fatalf("constant type mismatch %v(%d) %v(%d)", nl.Type, v.Ctype(), nr.Type, rv.Ctype()) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// run op | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	switch uint32(n.Op)<<16 | uint32(v.Ctype()) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		goto illegal | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OADD_ | CTINT_, | 
					
						
							|  |  |  | 		OADD_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).Add(rv.U.(*Mpint), 0) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OSUB_ | CTINT_, | 
					
						
							|  |  |  | 		OSUB_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).Sub(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OMUL_ | CTINT_, | 
					
						
							|  |  |  | 		OMUL_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).Mul(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ODIV_ | CTINT_, | 
					
						
							|  |  |  | 		ODIV_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if rv.U.(*Mpint).CmpInt64(0) == 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			Yyerror("division by zero") | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			v.U.(*Mpint).SetOverflow() | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).Quo(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OMOD_ | CTINT_, | 
					
						
							|  |  |  | 		OMOD_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if rv.U.(*Mpint).CmpInt64(0) == 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			Yyerror("division by zero") | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			v.U.(*Mpint).SetOverflow() | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).Rem(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OLSH_ | CTINT_, | 
					
						
							|  |  |  | 		OLSH_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).Lsh(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ORSH_ | CTINT_, | 
					
						
							|  |  |  | 		ORSH_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).Rsh(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OOR_ | CTINT_, | 
					
						
							|  |  |  | 		OOR_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).Or(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OAND_ | CTINT_, | 
					
						
							|  |  |  | 		OAND_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).And(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OANDNOT_ | CTINT_, | 
					
						
							|  |  |  | 		OANDNOT_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).AndNot(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OXOR_ | CTINT_, | 
					
						
							|  |  |  | 		OXOR_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpint).Xor(rv.U.(*Mpint)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OADD_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpflt).Add(rv.U.(*Mpflt)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OSUB_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpflt).Sub(rv.U.(*Mpflt)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OMUL_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpflt).Mul(rv.U.(*Mpflt)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ODIV_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if rv.U.(*Mpflt).CmpFloat64(0) == 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			Yyerror("division by zero") | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			v.U.(*Mpflt).SetFloat64(1.0) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpflt).Quo(rv.U.(*Mpflt)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// The default case above would print 'ideal % ideal', | 
					
						
							|  |  |  | 	// which is not quite an ideal error. | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OMOD_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		if n.Diag == 0 { | 
					
						
							| 
									
										
										
										
											2015-02-23 14:02:27 -05:00
										 |  |  | 			Yyerror("illegal constant expression: floating-point %% operation") | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			n.Diag = 1 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OADD_ | CTCPLX_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpcplx).Real.Add(&rv.U.(*Mpcplx).Real) | 
					
						
							|  |  |  | 		v.U.(*Mpcplx).Imag.Add(&rv.U.(*Mpcplx).Imag) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OSUB_ | CTCPLX_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		v.U.(*Mpcplx).Real.Sub(&rv.U.(*Mpcplx).Real) | 
					
						
							|  |  |  | 		v.U.(*Mpcplx).Imag.Sub(&rv.U.(*Mpcplx).Imag) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OMUL_ | CTCPLX_: | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		cmplxmpy(v.U.(*Mpcplx), rv.U.(*Mpcplx)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ODIV_ | CTCPLX_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if rv.U.(*Mpcplx).Real.CmpFloat64(0) == 0 && rv.U.(*Mpcplx).Imag.CmpFloat64(0) == 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			Yyerror("complex division by zero") | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			rv.U.(*Mpcplx).Real.SetFloat64(1.0) | 
					
						
							|  |  |  | 			rv.U.(*Mpcplx).Imag.SetFloat64(0.0) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		cmplxdiv(v.U.(*Mpcplx), rv.U.(*Mpcplx)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OEQ_ | CTNIL_: | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		goto settrue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ONE_ | CTNIL_: | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OEQ_ | CTINT_, | 
					
						
							|  |  |  | 		OEQ_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) == 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ONE_ | CTINT_, | 
					
						
							|  |  |  | 		ONE_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) != 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OLT_ | CTINT_, | 
					
						
							|  |  |  | 		OLT_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) < 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OLE_ | CTINT_, | 
					
						
							|  |  |  | 		OLE_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) <= 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OGE_ | CTINT_, | 
					
						
							|  |  |  | 		OGE_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) >= 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OGT_ | CTINT_, | 
					
						
							|  |  |  | 		OGT_ | CTRUNE_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) > 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OEQ_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) == 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ONE_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) != 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OLT_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) < 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OLE_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) <= 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OGE_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) >= 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OGT_ | CTFLT_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) > 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OEQ_ | CTCPLX_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpcplx).Real.Cmp(&rv.U.(*Mpcplx).Real) == 0 && v.U.(*Mpcplx).Imag.Cmp(&rv.U.(*Mpcplx).Imag) == 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ONE_ | CTCPLX_: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		if v.U.(*Mpcplx).Real.Cmp(&rv.U.(*Mpcplx).Real) != 0 || v.U.(*Mpcplx).Imag.Cmp(&rv.U.(*Mpcplx).Imag) != 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OEQ_ | CTSTR_: | 
					
						
							| 
									
										
										
										
											2015-09-17 21:01:29 +02:00
										 |  |  | 		if strlit(nl) == strlit(nr) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ONE_ | CTSTR_: | 
					
						
							| 
									
										
										
										
											2015-09-17 21:01:29 +02:00
										 |  |  | 		if strlit(nl) != strlit(nr) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OLT_ | CTSTR_: | 
					
						
							| 
									
										
										
										
											2015-09-17 21:01:29 +02:00
										 |  |  | 		if strlit(nl) < strlit(nr) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OLE_ | CTSTR_: | 
					
						
							| 
									
										
										
										
											2015-09-17 21:01:29 +02:00
										 |  |  | 		if strlit(nl) <= strlit(nr) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OGE_ | CTSTR_: | 
					
						
							| 
									
										
										
										
											2015-09-17 21:01:29 +02:00
										 |  |  | 		if strlit(nl) >= strlit(nr) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OGT_ | CTSTR_: | 
					
						
							| 
									
										
										
										
											2015-09-17 21:01:29 +02:00
										 |  |  | 		if strlit(nl) > strlit(nr) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OOROR_ | CTBOOL_: | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		if v.U.(bool) || rv.U.(bool) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OANDAND_ | CTBOOL_: | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		if v.U.(bool) && rv.U.(bool) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case OEQ_ | CTBOOL_: | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		if v.U.(bool) == rv.U.(bool) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | 	case ONE_ | CTBOOL_: | 
					
						
							| 
									
										
										
										
											2015-05-14 17:57:42 -07:00
										 |  |  | 		if v.U.(bool) != rv.U.(bool) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			goto settrue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		goto setfalse | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	goto ret | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ret: | 
					
						
							|  |  |  | 	norig = saveorig(n) | 
					
						
							|  |  |  | 	*n = *nl | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// restore value of n->orig. | 
					
						
							|  |  |  | 	n.Orig = norig | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 	n.SetVal(v) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// check range. | 
					
						
							| 
									
										
										
										
											2016-03-02 17:34:42 -08:00
										 |  |  | 	lno = setlineno(n) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	overflow(v, n.Type) | 
					
						
							| 
									
										
										
										
											2016-03-02 17:34:42 -08:00
										 |  |  | 	lineno = lno | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// truncate precision for non-ideal float. | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL { | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | settrue: | 
					
						
							| 
									
										
										
										
											2016-01-07 03:06:49 -08:00
										 |  |  | 	nn = Nodbool(true) | 
					
						
							|  |  |  | 	nn.Orig = saveorig(n) | 
					
						
							|  |  |  | 	if !iscmp[n.Op] { | 
					
						
							|  |  |  | 		nn.Type = nl.Type | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	*n = *nn | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | setfalse: | 
					
						
							| 
									
										
										
										
											2016-01-07 03:06:49 -08:00
										 |  |  | 	nn = Nodbool(false) | 
					
						
							|  |  |  | 	nn.Orig = saveorig(n) | 
					
						
							|  |  |  | 	if !iscmp[n.Op] { | 
					
						
							|  |  |  | 		nn.Type = nl.Type | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	*n = *nn | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | illegal: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if n.Diag == 0 { | 
					
						
							| 
									
										
										
										
											2016-03-07 08:23:55 -08:00
										 |  |  | 		Yyerror("illegal constant expression: %v %v %v", nl.Type, Oconv(n.Op, 0), nr.Type) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		n.Diag = 1 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func nodlit(v Val) *Node { | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	n := Nod(OLITERAL, nil, nil) | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 	n.SetVal(v) | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	switch v.Ctype() { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 		Fatalf("nodlit ctype %d", v.Ctype()) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTSTR: | 
					
						
							|  |  |  | 		n.Type = idealstring | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case CTBOOL: | 
					
						
							|  |  |  | 		n.Type = idealbool | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case CTINT, CTRUNE, CTFLT, CTCPLX: | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		n.Type = Types[TIDEAL] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case CTNIL: | 
					
						
							|  |  |  | 		n.Type = Types[TNIL] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func nodcplxlit(r Val, i Val) *Node { | 
					
						
							|  |  |  | 	r = toflt(r) | 
					
						
							|  |  |  | 	i = toflt(i) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	c := new(Mpcplx) | 
					
						
							|  |  |  | 	n := Nod(OLITERAL, nil, nil) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	n.Type = Types[TIDEAL] | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 	n.SetVal(Val{c}) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 22:50:45 -04:00
										 |  |  | 	if r.Ctype() != CTFLT || i.Ctype() != CTFLT { | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 		Fatalf("nodcplxlit ctype %d/%d", r.Ctype(), i.Ctype()) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	c.Real.Set(r.U.(*Mpflt)) | 
					
						
							|  |  |  | 	c.Imag.Set(i.U.(*Mpflt)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	return n | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // idealkind returns a constant kind like consttype | 
					
						
							|  |  |  | // but for an arbitrary "ideal" (untyped constant) expression. | 
					
						
							| 
									
										
										
										
											2015-10-26 16:00:59 -07:00
										 |  |  | func idealkind(n *Node) Ctype { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if n == nil || !isideal(n.Type) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return CTxxx | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch n.Op { | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return CTxxx | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OLITERAL: | 
					
						
							| 
									
										
										
										
											2015-10-26 16:00:59 -07:00
										 |  |  | 		return n.Val().Ctype() | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// numeric kinds. | 
					
						
							|  |  |  | 	case OADD, | 
					
						
							|  |  |  | 		OAND, | 
					
						
							|  |  |  | 		OANDNOT, | 
					
						
							|  |  |  | 		OCOM, | 
					
						
							|  |  |  | 		ODIV, | 
					
						
							|  |  |  | 		OMINUS, | 
					
						
							|  |  |  | 		OMOD, | 
					
						
							|  |  |  | 		OMUL, | 
					
						
							|  |  |  | 		OSUB, | 
					
						
							|  |  |  | 		OXOR, | 
					
						
							|  |  |  | 		OOR, | 
					
						
							|  |  |  | 		OPLUS: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		k1 := idealkind(n.Left) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		k2 := idealkind(n.Right) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		if k1 > k2 { | 
					
						
							|  |  |  | 			return k1 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			return k2 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case OREAL, OIMAG: | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return CTFLT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OCOMPLEX: | 
					
						
							|  |  |  | 		return CTCPLX | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OADDSTR: | 
					
						
							|  |  |  | 		return CTSTR | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OANDAND, | 
					
						
							|  |  |  | 		OEQ, | 
					
						
							|  |  |  | 		OGE, | 
					
						
							|  |  |  | 		OGT, | 
					
						
							|  |  |  | 		OLE, | 
					
						
							|  |  |  | 		OLT, | 
					
						
							|  |  |  | 		ONE, | 
					
						
							|  |  |  | 		ONOT, | 
					
						
							|  |  |  | 		OOROR, | 
					
						
							|  |  |  | 		OCMPSTR, | 
					
						
							|  |  |  | 		OCMPIFACE: | 
					
						
							|  |  |  | 		return CTBOOL | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// shifts (beware!). | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case OLSH, ORSH: | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return idealkind(n.Left) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func defaultlit(np **Node, t *Type) { | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	n := *np | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if n == nil || !isideal(n.Type) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if n.Op == OLITERAL { | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		nn := Nod(OXXX, nil, nil) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		*nn = *n | 
					
						
							|  |  |  | 		n = nn | 
					
						
							|  |  |  | 		*np = n | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-02 17:34:42 -08:00
										 |  |  | 	lno := setlineno(n) | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	ctype := idealkind(n) | 
					
						
							|  |  |  | 	var t1 *Type | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	switch ctype { | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		if t != nil { | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 			convlit(np, t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		if n.Val().Ctype() == CTNIL { | 
					
						
							| 
									
										
										
										
											2016-03-02 17:34:42 -08:00
										 |  |  | 			lineno = lno | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			if n.Diag == 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 				Yyerror("use of untyped nil") | 
					
						
							|  |  |  | 				n.Diag = 1 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			n.Type = nil | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		if n.Val().Ctype() == CTSTR { | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 			t1 := Types[TSTRING] | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 			convlit(np, t1) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 12:03:22 -04:00
										 |  |  | 		Yyerror("defaultlit: unknown literal: %v", n) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTxxx: | 
					
						
							| 
									
										
										
										
											2016-03-15 13:06:58 -07:00
										 |  |  | 		Fatalf("defaultlit: idealkind is CTxxx: %v", Nconv(n, FmtSign)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTBOOL: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		t1 := Types[TBOOL] | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		if t != nil && t.Etype == TBOOL { | 
					
						
							|  |  |  | 			t1 = t | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 		convlit(np, t1) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case CTINT: | 
					
						
							|  |  |  | 		t1 = Types[TINT] | 
					
						
							|  |  |  | 		goto num | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case CTRUNE: | 
					
						
							|  |  |  | 		t1 = runetype | 
					
						
							|  |  |  | 		goto num | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case CTFLT: | 
					
						
							|  |  |  | 		t1 = Types[TFLOAT64] | 
					
						
							|  |  |  | 		goto num | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case CTCPLX: | 
					
						
							|  |  |  | 		t1 = Types[TCOMPLEX128] | 
					
						
							|  |  |  | 		goto num | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-02 17:34:42 -08:00
										 |  |  | 	lineno = lno | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | num: | 
					
						
							| 
									
										
										
										
											2015-11-17 16:34:06 -05:00
										 |  |  | 	// Note: n.Val().Ctype() can be CTxxx (not a constant) here | 
					
						
							|  |  |  | 	// in the case of an untyped non-constant value, like 1<<i. | 
					
						
							|  |  |  | 	v1 := n.Val() | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if t != nil { | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if Isint[t.Etype] { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			t1 = t | 
					
						
							| 
									
										
										
										
											2015-11-17 16:34:06 -05:00
										 |  |  | 			v1 = toint(n.Val()) | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		} else if Isfloat[t.Etype] { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			t1 = t | 
					
						
							| 
									
										
										
										
											2015-11-17 16:34:06 -05:00
										 |  |  | 			v1 = toflt(n.Val()) | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		} else if Iscomplex[t.Etype] { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			t1 = t | 
					
						
							| 
									
										
										
										
											2015-11-17 16:34:06 -05:00
										 |  |  | 			v1 = tocplx(n.Val()) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if n.Val().Ctype() != CTxxx { | 
					
						
							|  |  |  | 			n.SetVal(v1) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-17 16:34:06 -05:00
										 |  |  | 	if n.Val().Ctype() != CTxxx { | 
					
						
							|  |  |  | 		overflow(n.Val(), t1) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 	convlit(np, t1) | 
					
						
							| 
									
										
										
										
											2016-03-02 17:34:42 -08:00
										 |  |  | 	lineno = lno | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-22 09:51:12 +09:00
										 |  |  | // defaultlit on both nodes simultaneously; | 
					
						
							|  |  |  | // if they're both ideal going in they better | 
					
						
							|  |  |  | // get the same type going out. | 
					
						
							|  |  |  | // force means must assign concrete (non-ideal) type. | 
					
						
							| 
									
										
										
										
											2016-03-01 00:15:27 -08:00
										 |  |  | func defaultlit2(lp **Node, rp **Node, force bool) { | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	l := *lp | 
					
						
							|  |  |  | 	r := *rp | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if l.Type == nil || r.Type == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if !isideal(l.Type) { | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 		convlit(rp, l.Type) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if !isideal(r.Type) { | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 		convlit(lp, r.Type) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-01 00:15:27 -08:00
										 |  |  | 	if !force { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-01 00:15:27 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if l.Type.Etype == TBOOL { | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 		convlit(lp, Types[TBOOL]) | 
					
						
							|  |  |  | 		convlit(rp, Types[TBOOL]) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	lkind := idealkind(l) | 
					
						
							|  |  |  | 	rkind := idealkind(r) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if lkind == CTCPLX || rkind == CTCPLX { | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 		convlit(lp, Types[TCOMPLEX128]) | 
					
						
							|  |  |  | 		convlit(rp, Types[TCOMPLEX128]) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if lkind == CTFLT || rkind == CTFLT { | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 		convlit(lp, Types[TFLOAT64]) | 
					
						
							|  |  |  | 		convlit(rp, Types[TFLOAT64]) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if lkind == CTRUNE || rkind == CTRUNE { | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 		convlit(lp, runetype) | 
					
						
							|  |  |  | 		convlit(rp, runetype) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 19:41:43 -07:00
										 |  |  | 	convlit(lp, Types[TINT]) | 
					
						
							|  |  |  | 	convlit(rp, Types[TINT]) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-17 21:01:29 +02:00
										 |  |  | // strlit returns the value of a literal string Node as a string. | 
					
						
							|  |  |  | func strlit(n *Node) string { | 
					
						
							|  |  |  | 	return n.Val().U.(string) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | func Smallintconst(n *Node) bool { | 
					
						
							|  |  |  | 	if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		switch Simtype[n.Type.Etype] { | 
					
						
							|  |  |  | 		case TINT8, | 
					
						
							|  |  |  | 			TUINT8, | 
					
						
							|  |  |  | 			TINT16, | 
					
						
							|  |  |  | 			TUINT16, | 
					
						
							|  |  |  | 			TINT32, | 
					
						
							|  |  |  | 			TUINT32, | 
					
						
							|  |  |  | 			TBOOL, | 
					
						
							|  |  |  | 			TPTR32: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 		case TIDEAL, TINT64, TUINT64, TPTR64: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			if n.Val().U.(*Mpint).Cmp(Minintval[TINT32]) < 0 || n.Val().U.(*Mpint).Cmp(Maxintval[TINT32]) > 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	return false | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func nonnegconst(n *Node) int { | 
					
						
							|  |  |  | 	if n.Op == OLITERAL && n.Type != nil { | 
					
						
							|  |  |  | 		switch Simtype[n.Type.Etype] { | 
					
						
							|  |  |  | 		// check negative and 2^31 | 
					
						
							|  |  |  | 		case TINT8, | 
					
						
							|  |  |  | 			TUINT8, | 
					
						
							|  |  |  | 			TINT16, | 
					
						
							|  |  |  | 			TUINT16, | 
					
						
							|  |  |  | 			TINT32, | 
					
						
							|  |  |  | 			TUINT32, | 
					
						
							|  |  |  | 			TINT64, | 
					
						
							|  |  |  | 			TUINT64, | 
					
						
							|  |  |  | 			TIDEAL: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			if n.Val().U.(*Mpint).Cmp(Minintval[TUINT32]) < 0 || n.Val().U.(*Mpint).Cmp(Maxintval[TINT32]) > 0 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			return int(n.Val().U.(*Mpint).Int64()) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return -1 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-22 09:51:12 +09:00
										 |  |  | // convert x to type et and back to int64 | 
					
						
							|  |  |  | // for sign extension and truncation. | 
					
						
							| 
									
										
										
										
											2015-09-24 23:21:18 +02:00
										 |  |  | func iconv(x int64, et EType) int64 { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	switch et { | 
					
						
							|  |  |  | 	case TINT8: | 
					
						
							|  |  |  | 		x = int64(int8(x)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case TUINT8: | 
					
						
							|  |  |  | 		x = int64(uint8(x)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case TINT16: | 
					
						
							|  |  |  | 		x = int64(int16(x)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case TUINT16: | 
					
						
							|  |  |  | 		x = int64(uint64(x)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case TINT32: | 
					
						
							|  |  |  | 		x = int64(int32(x)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case TUINT32: | 
					
						
							|  |  |  | 		x = int64(uint32(x)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case TINT64, TUINT64: | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		break | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return x | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-07 18:43:03 -07:00
										 |  |  | // Convconst converts constant node n to type t and | 
					
						
							|  |  |  | // places the result in con. | 
					
						
							|  |  |  | func (n *Node) Convconst(con *Node, t *Type) { | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	tt := Simsimtype(t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// copy the constant for conversion | 
					
						
							|  |  |  | 	Nodconst(con, Types[TINT8], 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	con.Type = t | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 	con.SetVal(n.Val()) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 	if Isint[tt] { | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		con.SetVal(Val{new(Mpint)}) | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		var i int64 | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		switch n.Val().Ctype() { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2016-03-15 13:06:58 -07:00
										 |  |  | 			Fatalf("convconst ctype=%d %v", n.Val().Ctype(), Tconv(t, FmtLong)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 		case CTINT, CTRUNE: | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 			i = n.Val().U.(*Mpint).Int64() | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case CTBOOL: | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 			i = int64(obj.Bool2int(n.Val().U.(bool))) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case CTNIL: | 
					
						
							|  |  |  | 			i = 0 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		i = iconv(i, tt) | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 		con.Val().U.(*Mpint).SetInt64(i) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 	if Isfloat[tt] { | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		con.SetVal(toflt(con.Val())) | 
					
						
							|  |  |  | 		if con.Val().Ctype() != CTFLT { | 
					
						
							| 
									
										
										
										
											2015-08-30 23:10:03 +02:00
										 |  |  | 			Fatalf("convconst ctype=%d %v", con.Val().Ctype(), t) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if tt == TFLOAT32 { | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 			con.SetVal(Val{truncfltlit(con.Val().U.(*Mpflt), t)}) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 	if Iscomplex[tt] { | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		con.SetVal(tocplx(con.Val())) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		if tt == TCOMPLEX64 { | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 			con.Val().U.(*Mpcplx).Real = *truncfltlit(&con.Val().U.(*Mpcplx).Real, Types[TFLOAT32]) | 
					
						
							|  |  |  | 			con.Val().U.(*Mpcplx).Imag = *truncfltlit(&con.Val().U.(*Mpcplx).Imag, Types[TFLOAT32]) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-15 13:06:58 -07:00
										 |  |  | 	Fatalf("convconst %v constant", Tconv(t, FmtLong)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // complex multiply v *= rv | 
					
						
							|  |  |  | //	(a, b) * (c, d) = (a*c - b*d, b*c + a*d) | 
					
						
							|  |  |  | func cmplxmpy(v *Mpcplx, rv *Mpcplx) { | 
					
						
							|  |  |  | 	var ac Mpflt | 
					
						
							|  |  |  | 	var bd Mpflt | 
					
						
							|  |  |  | 	var bc Mpflt | 
					
						
							|  |  |  | 	var ad Mpflt | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	ac.Set(&v.Real) | 
					
						
							|  |  |  | 	ac.Mul(&rv.Real) // ac | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	bd.Set(&v.Imag) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	bd.Mul(&rv.Imag) // bd | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	bc.Set(&v.Imag) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	bc.Mul(&rv.Real) // bc | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	ad.Set(&v.Real) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	ad.Mul(&rv.Imag) // ad | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	v.Real.Set(&ac) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	v.Real.Sub(&bd) // ac-bd | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	v.Imag.Set(&bc) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	v.Imag.Add(&ad) // bc+ad | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // complex divide v /= rv | 
					
						
							|  |  |  | //	(a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d) | 
					
						
							|  |  |  | func cmplxdiv(v *Mpcplx, rv *Mpcplx) { | 
					
						
							|  |  |  | 	var ac Mpflt | 
					
						
							|  |  |  | 	var bd Mpflt | 
					
						
							|  |  |  | 	var bc Mpflt | 
					
						
							|  |  |  | 	var ad Mpflt | 
					
						
							|  |  |  | 	var cc_plus_dd Mpflt | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	cc_plus_dd.Set(&rv.Real) | 
					
						
							|  |  |  | 	cc_plus_dd.Mul(&rv.Real) // cc | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	ac.Set(&rv.Imag) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	ac.Mul(&rv.Imag) // dd | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	cc_plus_dd.Add(&ac) // cc+dd | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	ac.Set(&v.Real) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	ac.Mul(&rv.Real) // ac | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	bd.Set(&v.Imag) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	bd.Mul(&rv.Imag) // bd | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	bc.Set(&v.Imag) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	bc.Mul(&rv.Real) // bc | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	ad.Set(&v.Real) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	ad.Mul(&rv.Imag) // ad | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	v.Real.Set(&ac) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	v.Real.Add(&bd)         // ac+bd | 
					
						
							|  |  |  | 	v.Real.Quo(&cc_plus_dd) // (ac+bd)/(cc+dd) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	v.Imag.Set(&bc) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 13:55:42 -07:00
										 |  |  | 	v.Imag.Sub(&ad)         // bc-ad | 
					
						
							|  |  |  | 	v.Imag.Quo(&cc_plus_dd) // (bc+ad)/(cc+dd) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Is n a Go language constant (as opposed to a compile-time constant)? | 
					
						
							|  |  |  | // Expressions derived from nil, like string([]byte(nil)), while they | 
					
						
							|  |  |  | // may be known at compile time, are not Go language constants. | 
					
						
							|  |  |  | // Only called for expressions known to evaluated to compile-time | 
					
						
							|  |  |  | // constants. | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | func isgoconst(n *Node) bool { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if n.Orig != nil { | 
					
						
							|  |  |  | 		n = n.Orig | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch n.Op { | 
					
						
							|  |  |  | 	case OADD, | 
					
						
							|  |  |  | 		OADDSTR, | 
					
						
							|  |  |  | 		OAND, | 
					
						
							|  |  |  | 		OANDAND, | 
					
						
							|  |  |  | 		OANDNOT, | 
					
						
							|  |  |  | 		OCOM, | 
					
						
							|  |  |  | 		ODIV, | 
					
						
							|  |  |  | 		OEQ, | 
					
						
							|  |  |  | 		OGE, | 
					
						
							|  |  |  | 		OGT, | 
					
						
							|  |  |  | 		OLE, | 
					
						
							|  |  |  | 		OLSH, | 
					
						
							|  |  |  | 		OLT, | 
					
						
							|  |  |  | 		OMINUS, | 
					
						
							|  |  |  | 		OMOD, | 
					
						
							|  |  |  | 		OMUL, | 
					
						
							|  |  |  | 		ONE, | 
					
						
							|  |  |  | 		ONOT, | 
					
						
							|  |  |  | 		OOR, | 
					
						
							|  |  |  | 		OOROR, | 
					
						
							|  |  |  | 		OPLUS, | 
					
						
							|  |  |  | 		ORSH, | 
					
						
							|  |  |  | 		OSUB, | 
					
						
							|  |  |  | 		OXOR, | 
					
						
							|  |  |  | 		OIOTA, | 
					
						
							|  |  |  | 		OCOMPLEX, | 
					
						
							|  |  |  | 		OREAL, | 
					
						
							|  |  |  | 		OIMAG: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		if isgoconst(n.Left) && (n.Right == nil || isgoconst(n.Right)) { | 
					
						
							|  |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OCONV: | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if okforconst[n.Type.Etype] && isgoconst(n.Left) { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 	case OLEN, OCAP: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		l := n.Left | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		if isgoconst(l) { | 
					
						
							|  |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Special case: len/cap is constant when applied to array or | 
					
						
							|  |  |  | 		// pointer to array when the expression does not contain | 
					
						
							|  |  |  | 		// function calls or channel receive operations. | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		t := l.Type | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-01 07:54:01 +00:00
										 |  |  | 		if t != nil && Isptr[t.Etype] { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			t = t.Type | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		if Isfixedarray(t) && !hascallchan(l) { | 
					
						
							|  |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OLITERAL: | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		if n.Val().Ctype() != CTNIL { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case ONAME: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		l := n.Sym.Def | 
					
						
							| 
									
										
										
										
											2015-05-27 00:47:05 -04:00
										 |  |  | 		if l != nil && l.Op == OLITERAL && n.Val().Ctype() != CTNIL { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case ONONAME: | 
					
						
							|  |  |  | 		if n.Sym.Def != nil && n.Sym.Def.Op == OIOTA { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Only constant calls are unsafe.Alignof, Offsetof, and Sizeof. | 
					
						
							|  |  |  | 	case OCALL: | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 		l := n.Left | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for l.Op == OPAREN { | 
					
						
							|  |  |  | 			l = l.Left | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if l.Op != ONAME || l.Sym.Pkg != unsafepkg { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if l.Sym.Name == "Alignof" || l.Sym.Name == "Offsetof" || l.Sym.Name == "Sizeof" { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//dump("nonconst", n); | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	return false | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | func hascallchan(n *Node) bool { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	if n == nil { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		return false | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	switch n.Op { | 
					
						
							|  |  |  | 	case OAPPEND, | 
					
						
							|  |  |  | 		OCALL, | 
					
						
							|  |  |  | 		OCALLFUNC, | 
					
						
							|  |  |  | 		OCALLINTER, | 
					
						
							|  |  |  | 		OCALLMETH, | 
					
						
							|  |  |  | 		OCAP, | 
					
						
							|  |  |  | 		OCLOSE, | 
					
						
							|  |  |  | 		OCOMPLEX, | 
					
						
							|  |  |  | 		OCOPY, | 
					
						
							|  |  |  | 		ODELETE, | 
					
						
							|  |  |  | 		OIMAG, | 
					
						
							|  |  |  | 		OLEN, | 
					
						
							|  |  |  | 		OMAKE, | 
					
						
							|  |  |  | 		ONEW, | 
					
						
							|  |  |  | 		OPANIC, | 
					
						
							|  |  |  | 		OPRINT, | 
					
						
							|  |  |  | 		OPRINTN, | 
					
						
							|  |  |  | 		OREAL, | 
					
						
							|  |  |  | 		ORECOVER, | 
					
						
							|  |  |  | 		ORECV: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if hascallchan(n.Left) || hascallchan(n.Right) { | 
					
						
							|  |  |  | 		return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-08 15:10:26 -08:00
										 |  |  | 	for _, n1 := range n.List.Slice() { | 
					
						
							|  |  |  | 		if hascallchan(n1) { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-08 15:10:26 -08:00
										 |  |  | 	for _, n2 := range n.Rlist.Slice() { | 
					
						
							|  |  |  | 		if hascallchan(n2) { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	return false | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } |