How to use Builtin method of ast Package

Best Syzkaller code snippet using ast.Builtin

const.go

Source:const.go Github

copy

Full Screen

...5 "math"6 "math/big"7 "unicode/utf8"8)9func convertBool(dst *ast.BuiltinType, val ast.Bool) ast.Value {10 if dst.Kind != ast.BUILTIN_BOOL {11 return nil12 }13 return val14}15func convertInt(dst *ast.BuiltinType, src *ast.BuiltinType, val uint64) ast.Value {16 sval := int64(val)17 switch dst.Kind {18 case ast.BUILTIN_BOOL:19 return nil20 case ast.BUILTIN_INT8:21 if src.IsSigned() {22 if sval < math.MinInt8 || sval > math.MaxInt8 {23 return nil24 }25 } else if val > math.MaxInt8 {26 return nil27 }28 return ast.Int(val)29 case ast.BUILTIN_INT16:30 if src.IsSigned() {31 if sval < math.MinInt16 || sval > math.MaxInt16 {32 return nil33 }34 } else if val > math.MaxInt16 {35 return nil36 }37 return ast.Int(val)38 case ast.BUILTIN_INT32:39 if src.IsSigned() {40 if sval < math.MinInt32 || sval > math.MaxInt32 {41 return nil42 }43 } else if val > math.MaxInt32 {44 return nil45 }46 return ast.Int(val)47 case ast.BUILTIN_INT:48 fallthrough // XXX: 64-bit assumption49 case ast.BUILTIN_INT64:50 if !src.IsSigned() && val > math.MaxInt64 {51 return nil52 }53 return ast.Int(val)54 case ast.BUILTIN_UINT8:55 if src.IsSigned() {56 if sval < 0 || sval > math.MaxUint8 {57 return nil58 }59 } else if val > math.MaxUint8 {60 return nil61 }62 return ast.Int(val)63 case ast.BUILTIN_UINT16:64 if src.IsSigned() {65 if sval < 0 || sval > math.MaxUint16 {66 return nil67 }68 } else if val > math.MaxUint16 {69 return nil70 }71 return ast.Int(val)72 case ast.BUILTIN_UINT32:73 if src.IsSigned() {74 if sval < 0 || sval > math.MaxUint32 {75 return nil76 }77 } else if val > math.MaxUint32 {78 return nil79 }80 return ast.Int(val)81 case ast.BUILTIN_UINT:82 fallthrough // XXX 64-bit assumption83 case ast.BUILTIN_UINTPTR:84 fallthrough // XXX 64-bit assumption85 case ast.BUILTIN_UINT64:86 if src.IsSigned() && sval < 0 {87 return nil88 }89 return ast.Int(val)90 case ast.BUILTIN_COMPLEX64:91 fallthrough92 case ast.BUILTIN_FLOAT32:93 var f float3294 if src.IsSigned() && sval < 0 {95 f = float32(sval)96 } else {97 f = float32(val)98 }99 if dst.Kind == ast.BUILTIN_FLOAT32 {100 return ast.Float(f)101 } else {102 return ast.Complex(complex(f, 0))103 }104 case ast.BUILTIN_COMPLEX128:105 fallthrough106 case ast.BUILTIN_FLOAT64:107 var f float64108 if src.IsSigned() && sval < 0 {109 f = float64(sval)110 } else {111 f = float64(val)112 }113 if dst.Kind == ast.BUILTIN_FLOAT64 {114 return ast.Float(f)115 } else {116 return ast.Complex(complex(f, 0))117 }118 case ast.BUILTIN_STRING:119 r := rune(val)120 if src.IsSigned() {121 if sval <= 0 || sval > math.MaxInt32 || !utf8.ValidRune(r) {122 r = 0xfffd123 }124 } else if val == 0 || val > math.MaxInt32 || !utf8.ValidRune(r) {125 r = 0xfffd126 }127 return ast.String(r)128 default:129 panic("not reached")130 }131}132var (133 minInt64, maxInt64, maxUint64, zeroInt big.Int134 zeroFloat big.Float135)136func init() {137 minInt64.SetInt64(math.MinInt64)138 maxInt64.SetInt64(math.MaxInt64)139 maxUint64.SetUint64(math.MaxUint64)140 zeroFloat.SetPrec(ast.UNTYPED_FLOAT_PRECISION).SetMode(big.ToNearestEven)141}142const MaxShift = 511143func convertUntypedInt(dst *ast.BuiltinType, val *big.Int) ast.Value {144 if dst.IsInteger() || dst.Kind == ast.BUILTIN_STRING {145 // If the destination type is integral, a successful conversion it not146 // possible if the untyped constant is outside the range of (u)int64.147 if val.Cmp(&minInt64) < 0 || val.Cmp(&maxUint64) > 0 {148 if dst.Kind == ast.BUILTIN_STRING {149 return ast.String(0xfffd)150 } else {151 return nil152 }153 }154 if val.Sign() < 0 {155 return convertInt(dst, ast.BuiltinInt64, uint64(val.Int64()))156 } else {157 return convertInt(dst, ast.BuiltinUint64, val.Uint64())158 }159 }160 switch dst.Kind {161 case ast.BUILTIN_BOOL:162 return nil163 case ast.BUILTIN_COMPLEX64:164 fallthrough165 case ast.BUILTIN_FLOAT32:166 f := new(big.Float).SetInt(val)167 f32, _ := f.Float32()168 if math.IsInf(float64(f32), 0) {169 return nil170 }171 if dst.Kind == ast.BUILTIN_FLOAT32 {172 return ast.Float(f32)173 } else {174 return ast.Complex(complex(float64(f32), 0))175 }176 case ast.BUILTIN_COMPLEX128:177 fallthrough178 case ast.BUILTIN_FLOAT64:179 f := new(big.Float).SetInt(val)180 f64, _ := f.Float64()181 if math.IsInf(f64, 0) {182 return nil183 }184 if dst.Kind == ast.BUILTIN_FLOAT64 {185 return ast.Float(f64)186 } else {187 return ast.Complex(complex(f64, 0))188 }189 default:190 panic("not reached")191 }192}193func floatToUint64(x float64) (uint64, bool) {194 if x < 0 {195 return 0, false196 }197 b := math.Float64bits(x)198 e := int((b >> 52) & 0x7ff)199 if e == 0 {200 return 0, true // zero201 }202 f := (b & 0x000fffffffffffff) | 0x0010000000000000203 e = e - 1023 - 52204 if e < -52 {205 return 0, true // too small206 }207 if e > 11 {208 return 0, false209 }210 if e < 0 {211 return f >> uint(-e), true212 } else {213 return f << uint(e), true214 }215}216func floatToInt64(x float64) (int64, bool) {217 neg := x < 0218 u, ok := uint64(0), false219 if neg {220 u, ok = floatToUint64(-x)221 } else {222 u, ok = floatToUint64(x)223 }224 if !ok {225 return 0, false226 }227 if neg && u > math.MaxInt64+1 {228 return 0, false229 }230 if !neg && u > math.MaxInt64 {231 return 0, false232 }233 if neg {234 return -int64(u), true235 } else {236 return int64(u), true237 }238}239func float64To32(x float64) (float64, bool) {240 v := float64(float32(x))241 return v, !math.IsInf(v, 0)242}243func convertFloat(dst *ast.BuiltinType, val float64) ast.Value {244 if dst.IsInteger() {245 if val != math.Floor(val) {246 return nil247 }248 if val < 0 {249 v, ok := floatToInt64(val)250 if !ok {251 return nil252 }253 return convertInt(dst, ast.BuiltinInt64, uint64(v))254 } else {255 v, ok := floatToUint64(val)256 if !ok {257 return nil258 }259 return convertInt(dst, ast.BuiltinUint64, v)260 }261 }262 switch dst.Kind {263 case ast.BUILTIN_BOOL:264 return nil265 case ast.BUILTIN_FLOAT32:266 u, ok := float64To32(val)267 if !ok {268 return nil269 }270 val = u271 fallthrough272 case ast.BUILTIN_FLOAT64:273 return ast.Float(val)274 case ast.BUILTIN_COMPLEX64:275 val = float64(float32(val))276 fallthrough277 case ast.BUILTIN_COMPLEX128:278 return ast.Complex(complex(val, 0))279 case ast.BUILTIN_STRING:280 return nil281 default:282 panic("not reached")283 }284}285func convertComplex(dst *ast.BuiltinType, re float64, im float64) ast.Value {286 if dst.IsInteger() ||287 dst.Kind == ast.BUILTIN_FLOAT32 || dst.Kind == ast.BUILTIN_FLOAT64 {288 if im != 0.0 {289 return nil290 }291 return convertFloat(dst, re)292 }293 switch dst.Kind {294 case ast.BUILTIN_BOOL:295 return nil296 case ast.BUILTIN_COMPLEX64:297 u, ok := float64To32(re)298 if !ok {299 return nil300 }301 v, ok := float64To32(im)302 if !ok {303 return nil304 }305 re = u306 im = v307 fallthrough308 case ast.BUILTIN_COMPLEX128:309 return ast.Complex(complex(re, im))310 case ast.BUILTIN_STRING:311 return nil312 default:313 panic("not reached")314 }315}316func convert(dst, src *ast.BuiltinType, val ast.Value) ast.Value {317 if dst.Kind == ast.BUILTIN_NIL_TYPE || dst.Kind == ast.BUILTIN_VOID {318 panic("not reached")319 }320 var res ast.Value321 switch src.Kind {322 case ast.BUILTIN_BOOL, ast.BUILTIN_UNTYPED_BOOL:323 res = convertBool(dst, val.(ast.Bool))324 case ast.BUILTIN_UNTYPED_RUNE:325 res = convertUntypedInt(dst, val.(ast.UntypedRune).Int)326 case ast.BUILTIN_UNTYPED_INT:327 res = convertUntypedInt(dst, val.(ast.UntypedInt).Int)328 case ast.BUILTIN_UNTYPED_FLOAT:329 v := val.(ast.UntypedFloat)330 if dst.IsInteger() {331 if v.IsInt() {332 i, _ := v.Int(nil)333 res = convertUntypedInt(dst, i)334 }335 } else {336 x, _ := v.Float64()337 if !math.IsInf(x, 0) {338 res = convertFloat(dst, x)339 }340 }341 case ast.BUILTIN_FLOAT32, ast.BUILTIN_FLOAT64:342 res = convertFloat(dst, float64(val.(ast.Float)))343 case ast.BUILTIN_UNTYPED_COMPLEX:344 v := val.(ast.UntypedComplex)345 if dst.IsInteger() {346 if v.Re.IsInt() && v.Im.Sign() == 0 {347 i, _ := v.Re.Int(nil)348 res = convertUntypedInt(dst, i)349 } else {350 res = nil351 }352 } else {353 re, _ := v.Re.Float64()354 im, _ := v.Im.Float64()355 if math.IsInf(re, 0) || math.IsInf(im, 0) {356 res = nil357 } else {358 res = convertComplex(dst, re, im)359 }360 }361 case ast.BUILTIN_COMPLEX64, ast.BUILTIN_COMPLEX128:362 v := val.(ast.Complex)363 re, im := real(v), imag(v)364 res = convertComplex(dst, re, im)365 case ast.BUILTIN_STRING, ast.BUILTIN_UNTYPED_STRING:366 if dst.Kind == ast.BUILTIN_STRING {367 res = val368 } else {369 res = nil370 }371 default:372 if !src.IsInteger() {373 panic("not reached")374 }375 res = convertInt(dst, src, uint64(val.(ast.Int)))376 }377 return res378}379func Convert(dst ast.Type, cst *ast.ConstValue) (*ast.ConstValue, error) {380 if d := builtinType(dst); d != nil {381 if v := convert(d, builtinType(cst.Typ), cst.Value); v != nil {382 return &ast.ConstValue{Typ: dst, Value: v}, nil383 }384 }385 return nil, &badConstConversion{Dst: dst, Src: cst}386}387func ToInt(c *ast.ConstValue) (int64, error) {388 v := convert(ast.BuiltinInt, builtinType(c.Typ), c.Value)389 if v == nil {390 return 0, &badConstConversion{Dst: ast.BuiltinInt, Src: c}391 }392 return int64(v.(ast.Int)), nil393}394func ToUint(c *ast.ConstValue) (uint64, error) {395 v := convert(ast.BuiltinUint, builtinType(c.Typ), c.Value)396 if v == nil {397 return 0, &badConstConversion{Dst: ast.BuiltinUint, Src: c}398 }399 return uint64(v.(ast.Int)), nil400}401func ToInt64(c *ast.ConstValue) (int64, error) {402 v := convert(ast.BuiltinInt64, builtinType(c.Typ), c.Value)403 if v == nil {404 return 0, &badConstConversion{Dst: ast.BuiltinInt64, Src: c}405 }406 return int64(v.(ast.Int)), nil407}408func ToUint64(c *ast.ConstValue) (uint64, error) {409 v := convert(ast.BuiltinUint64, builtinType(c.Typ), c.Value)410 if v == nil {411 return 0, &badConstConversion{Dst: ast.BuiltinUint64, Src: c}412 }413 return uint64(v.(ast.Int)), nil414}415func ToFloat(c *ast.ConstValue) (float64, error) {416 v := convert(ast.BuiltinFloat64, builtinType(c.Typ), c.Value)417 if v == nil {418 return 0, &badConstConversion{Dst: ast.BuiltinFloat64, Src: c}419 }420 return float64(v.(ast.Float)), nil421}422func ToComplex(c *ast.ConstValue) (complex128, error) {423 v := convert(ast.BuiltinComplex128, builtinType(c.Typ), c.Value)424 if v == nil {425 return 0, &badConstConversion{Dst: ast.BuiltinComplex128, Src: c}426 }427 return complex128(v.(ast.Complex)), nil428}429func ToString(c *ast.ConstValue) (string, error) {430 v := convert(ast.BuiltinString, builtinType(c.Typ), c.Value)431 if v == nil {432 return "", &badConstConversion{Dst: ast.BuiltinString, Src: c}433 }434 return string(v.(ast.String)), nil435}436func Minus(cst *ast.ConstValue) (*ast.ConstValue, error) {437 typ, val := builtinType(cst.Typ), cst.Value438 var res ast.Value439 switch typ.Kind {440 case ast.BUILTIN_BOOL, ast.BUILTIN_UNTYPED_BOOL:441 res = nil442 case ast.BUILTIN_UNTYPED_RUNE:443 res = ast.UntypedRune{Int: new(big.Int).Neg(val.(ast.UntypedRune).Int)}444 case ast.BUILTIN_UNTYPED_INT:445 res = ast.UntypedInt{Int: new(big.Int).Neg(val.(ast.UntypedInt).Int)}446 case ast.BUILTIN_UNTYPED_FLOAT:447 res = ast.UntypedFloat{Float: new(big.Float).Neg(val.(ast.UntypedFloat).Float)}448 case ast.BUILTIN_FLOAT32, ast.BUILTIN_FLOAT64:449 res = ast.Float(-float64(val.(ast.Float)))450 case ast.BUILTIN_UNTYPED_COMPLEX:451 v := val.(ast.UntypedComplex)452 res = ast.UntypedComplex{453 Re: new(big.Float).Neg(v.Re),454 Im: new(big.Float).Neg(v.Im),455 }456 case ast.BUILTIN_COMPLEX64, ast.BUILTIN_COMPLEX128:457 v := val.(ast.Complex)458 res = ast.Complex(complex(-real(v), -imag(v)))459 case ast.BUILTIN_STRING, ast.BUILTIN_UNTYPED_STRING:460 res = nil461 default:462 if !typ.IsInteger() {463 panic("not reached")464 }465 if !typ.IsSigned() {466 res = nil467 } else {468 res = ast.Int(-int64(val.(ast.Int)))469 }470 }471 if res == nil {472 return nil, &badOperandType{Op: '-', Type: "arithmetic type", X: cst}473 }474 return &ast.ConstValue{Typ: cst.Typ, Value: res}, nil475}476func Complement(cst *ast.ConstValue) (*ast.ConstValue, error) {477 typ, val := builtinType(cst.Typ), cst.Value478 var res ast.Value479 switch typ.Kind {480 case ast.BUILTIN_UNTYPED_INT:481 v := val.(ast.UntypedInt)482 res = ast.UntypedInt{Int: new(big.Int).Not(v.Int)}483 case ast.BUILTIN_UNTYPED_RUNE:484 v := val.(ast.UntypedRune)485 res = ast.UntypedRune{Int: new(big.Int).Not(v.Int)}486 default:487 if !typ.IsInteger() {488 res = nil489 } else {490 v := val.(ast.Int)491 switch typ.Kind {492 case ast.BUILTIN_INT8:493 res = ast.Int(^int8(v))494 case ast.BUILTIN_INT16:495 res = ast.Int(^int16(v))496 case ast.BUILTIN_INT32:497 res = ast.Int(^int32(v))498 case ast.BUILTIN_INT64, ast.BUILTIN_INT:499 res = ast.Int(^int64(v))500 case ast.BUILTIN_UINT8:501 res = ast.Int(^uint8(v))502 case ast.BUILTIN_UINT16:503 res = ast.Int(^uint16(v))504 case ast.BUILTIN_UINT32:505 res = ast.Int(^uint32(v))506 case ast.BUILTIN_UINT64, ast.BUILTIN_UINT, ast.BUILTIN_UINTPTR:507 res = ast.Int(^uint64(v))508 default:509 panic("not reached")510 }511 }512 }513 if res == nil {514 return nil, &badOperandType{Op: '-', Type: "integral type", X: cst}515 }516 return &ast.ConstValue{Typ: cst.Typ, Value: res}, nil517}518func Not(cst *ast.ConstValue) (*ast.ConstValue, error) {519 typ, val := builtinType(cst.Typ), cst.Value520 if typ.Kind != ast.BUILTIN_BOOL && typ.Kind != ast.BUILTIN_UNTYPED_BOOL {521 return nil, &badOperandType{Op: '!', Type: "boolean type", X: cst}522 }523 return &ast.ConstValue{Typ: cst.Typ, Value: ast.Bool(!val.(ast.Bool))}, nil524}525func Shift(526 x *ast.ConstValue, y *ast.ConstValue, op ast.Operation) (*ast.ConstValue, error) {527 // Get the shift count in a native uint.528 v := convert(ast.BuiltinUint64, builtinType(y.Typ), y.Value)529 if v == nil {530 return nil, &badShiftCount{X: y}531 }532 s := uint64(v.(ast.Int))533 if s > MaxShift {534 return nil, &bigShiftCount{X: s}535 }536 // Perform the shift.537 var res ast.Value538 switch t := builtinType(x.Typ); t.Kind {539 case ast.BUILTIN_UNTYPED_INT:540 v := x.Value.(ast.UntypedInt)541 if op == ast.SHL {542 res = ast.UntypedInt{Int: new(big.Int).Lsh(v.Int, uint(s))}543 } else {544 res = ast.UntypedInt{Int: new(big.Int).Rsh(v.Int, uint(s))}545 }546 return &ast.ConstValue{Off: x.Off, Typ: ast.BuiltinUntypedInt, Value: res}, nil547 case ast.BUILTIN_UNTYPED_FLOAT:548 v := x.Value.(ast.UntypedFloat)549 u, a := v.Int(new(big.Int))550 if a != big.Exact {551 return nil, &badOperandValue{Op: op, X: x}552 }553 if op == ast.SHL {554 res = ast.UntypedInt{Int: u.Lsh(u, uint(s))}555 } else {556 res = ast.UntypedInt{Int: u.Rsh(u, uint(s))}557 }558 return &ast.ConstValue{Off: x.Off, Typ: ast.BuiltinUntypedInt, Value: res}, nil559 case ast.BUILTIN_UNTYPED_COMPLEX:560 v := x.Value.(ast.UntypedComplex)561 if z, a := v.Im.Int64(); a != big.Exact || z != 0 {562 return nil, &badOperandValue{Op: op, X: x}563 }564 u, a := v.Re.Int(new(big.Int))565 if a != big.Exact {566 return nil, &badOperandValue{Op: op, X: x}567 }568 if op == ast.SHL {569 res = ast.UntypedInt{Int: u.Lsh(u, uint(s))}570 } else {571 res = ast.UntypedInt{Int: u.Rsh(u, uint(s))}572 }573 return &ast.ConstValue{Off: x.Off, Typ: ast.BuiltinUntypedInt, Value: res}, nil574 case ast.BUILTIN_UNTYPED_RUNE:575 v := x.Value.(ast.UntypedRune)576 if op == ast.SHL {577 res = ast.UntypedRune{Int: new(big.Int).Lsh(v.Int, uint(s))}578 } else {579 res = ast.UntypedRune{Int: new(big.Int).Rsh(v.Int, uint(s))}580 }581 return &ast.ConstValue{Off: x.Off, Typ: ast.BuiltinUntypedRune, Value: res}, nil582 default:583 if !t.IsInteger() {584 return nil, &badOperandType{Op: op, Type: "integer type", X: x}585 }586 v := x.Value.(ast.Int)587 if op == ast.SHL {588 res = ast.Int(v << s)589 } else if builtinType(x.Typ).IsSigned() {590 res = ast.Int(int64(v) >> s)591 } else {592 res = ast.Int(v >> s)593 }594 return &ast.ConstValue{Off: x.Off, Typ: x.Typ, Value: res}, nil595 }596}597func untypedConvPanic(ast.Value) ast.Value { panic("not reached") }598func untypedConvIntToRune(x ast.Value) ast.Value {599 return ast.UntypedRune{Int: new(big.Int).Set(x.(ast.UntypedInt).Int)}600}601func bigIntToFloat(x *big.Int) *big.Float {602 v := new(big.Float).SetPrec(ast.UNTYPED_FLOAT_PRECISION).SetMode(big.ToNearestEven)603 return v.SetInt(x)604}605func untypedConvIntToFloat(x ast.Value) ast.Value {606 return ast.UntypedFloat{Float: bigIntToFloat(x.(ast.UntypedInt).Int)}607}608func untypedConvIntToComplex(x ast.Value) ast.Value {609 return ast.UntypedComplex{610 Re: bigIntToFloat(x.(ast.UntypedInt).Int),611 Im: new(big.Float).612 SetPrec(ast.UNTYPED_FLOAT_PRECISION).613 SetMode(big.ToNearestEven),614 }615}616func untypedConvRuneToFloat(x ast.Value) ast.Value {617 return ast.UntypedFloat{Float: bigIntToFloat(x.(ast.UntypedRune).Int)}618}619func untypedConvRuneToComplex(x ast.Value) ast.Value {620 return ast.UntypedComplex{621 Re: bigIntToFloat(x.(ast.UntypedRune).Int),622 Im: new(big.Float).623 SetPrec(ast.UNTYPED_FLOAT_PRECISION).624 SetMode(big.ToNearestEven),625 }626}627func untypedConvFloatToComplex(x ast.Value) ast.Value {628 return ast.UntypedComplex{629 Re: new(big.Float).Set(x.(ast.UntypedFloat).Float),630 Im: new(big.Float).631 SetPrec(ast.UNTYPED_FLOAT_PRECISION).632 SetMode(big.ToNearestEven),633 }634}635type untypedKind int636const (637 _UNTYPED_ERR untypedKind = iota - 1638 _UNTYPED_INT639 _UNTYPED_RUNE640 _UNTYPED_FLOAT641 _UNTYPED_COMPLEX642 _UNTYPED_BOOL643 _UNTYPED_STRING644)645func untypedToKind(x ast.Value) untypedKind {646 switch x.(type) {647 case ast.UntypedInt:648 return _UNTYPED_INT649 case ast.UntypedRune:650 return _UNTYPED_RUNE651 case ast.UntypedFloat:652 return _UNTYPED_FLOAT653 case ast.UntypedComplex:654 return _UNTYPED_COMPLEX655 case ast.Bool:656 return _UNTYPED_BOOL657 case ast.String:658 return _UNTYPED_STRING659 default:660 panic("not reached")661 }662}663var untypedConvTable = [...][4]func(ast.Value) ast.Value{664 {665 untypedConvPanic,666 untypedConvIntToRune, untypedConvIntToFloat, untypedConvIntToComplex,667 },668 {669 untypedConvPanic, untypedConvPanic,670 untypedConvRuneToFloat, untypedConvRuneToComplex,671 },672 {673 untypedConvPanic, untypedConvPanic, untypedConvPanic,674 untypedConvFloatToComplex,675 },676}677func untypedConvert(x ast.Value, y ast.Value) (untypedKind, ast.Value, ast.Value) {678 i, j := untypedToKind(x), untypedToKind(y)679 if i > _UNTYPED_COMPLEX || j > _UNTYPED_COMPLEX {680 return _UNTYPED_ERR, nil, nil681 }682 if i == j {683 return i, x, y684 }685 swap := false686 if i > j {687 swap = true688 i, j = j, i689 x, y = y, x690 }691 x = untypedConvTable[i][j](x)692 if swap {693 x, y = y, x694 }695 return j, x, y696}697func Compare(698 x *ast.ConstValue, y *ast.ConstValue, op ast.Operation) (*ast.ConstValue, error) {699 var res ast.Value700 var err error701 // If the constants are typed, they must have the same type.702 if t := builtinType(x.Typ); t != nil && !t.IsUntyped() {703 if x.Typ != y.Typ {704 return nil, &mismatchedTypes{Op: op, X: x, Y: y}705 }706 res, err = compareTyped(t, x.Value, y.Value, op)707 } else {708 // If the operands are untyped, they must either both be bool,709 // or strings, or use the type later in the sequence int, rune, float,710 // complex, by converting one of the operands to the type of the711 // other.712 var (713 t untypedKind714 u, v ast.Value715 )716 switch x.Value.(type) {717 case ast.Bool:718 if _, ok := y.Value.(ast.Bool); !ok {719 return nil, &mismatchedTypes{Op: op, X: x, Y: y}720 }721 t, u, v = _UNTYPED_BOOL, x.Value, y.Value722 case ast.String:723 if _, ok := y.Value.(ast.String); !ok {724 return nil, &mismatchedTypes{Op: op, X: x, Y: y}725 }726 t, u, v = _UNTYPED_STRING, x.Value, y.Value727 default:728 t, u, v = untypedConvert(x.Value, y.Value)729 if t == _UNTYPED_ERR {730 return nil, &mismatchedTypes{Op: op, X: x, Y: y}731 }732 }733 res, err = compareUntyped(t, u, v, op)734 }735 if err != nil {736 return nil, err737 }738 return &ast.ConstValue{Typ: ast.BuiltinUntypedBool, Value: res}, nil739}740func compareTyped(741 typ *ast.BuiltinType, x ast.Value, y ast.Value, op ast.Operation) (ast.Value, error) {742 c := 0743 switch typ.Kind {744 case ast.BUILTIN_BOOL:745 u, v := x.(ast.Bool), y.(ast.Bool)746 switch op {747 case ast.EQ:748 return ast.Bool(u == v), nil749 case ast.NE:750 return ast.Bool(u != v), nil751 default:752 return nil, &invalidOperation{Op: op, Type: typ}753 }754 case ast.BUILTIN_UINT8, ast.BUILTIN_UINT16, ast.BUILTIN_UINT32,755 ast.BUILTIN_UINT64, ast.BUILTIN_UINT, ast.BUILTIN_UINTPTR:756 u, v := x.(ast.Int), y.(ast.Int)757 if u < v {758 c = -1759 } else if u > v {760 c = 1761 }762 case ast.BUILTIN_INT8, ast.BUILTIN_INT16, ast.BUILTIN_INT32,763 ast.BUILTIN_INT64, ast.BUILTIN_INT:764 u, v := int64(x.(ast.Int)), int64(y.(ast.Int))765 if u < v {766 c = -1767 } else if u > v {768 c = 1769 }770 case ast.BUILTIN_FLOAT32, ast.BUILTIN_FLOAT64:771 u, v := x.(ast.Float), y.(ast.Float)772 if u < v {773 c = -1774 } else if u > v {775 c = 1776 }777 case ast.BUILTIN_COMPLEX64, ast.BUILTIN_COMPLEX128:778 u, v := x.(ast.Complex), y.(ast.Complex)779 switch op {780 case ast.EQ:781 return ast.Bool(u == v), nil782 case ast.NE:783 return ast.Bool(u != v), nil784 default:785 return nil, &invalidOperation{Op: op, Type: typ}786 }787 case ast.BUILTIN_STRING:788 u, v := x.(ast.String), y.(ast.String)789 if u < v {790 c = -1791 } else if u > v {792 c = 1793 }794 default:795 panic("not reached")796 }797 return cmpToBool(c, op), nil798}799func compareUntyped(800 t untypedKind, x ast.Value, y ast.Value, op ast.Operation) (ast.Value, error) {801 c := 0802 switch t {803 case _UNTYPED_INT:804 x, y := x.(ast.UntypedInt), y.(ast.UntypedInt)805 c = x.Cmp(y.Int)806 case _UNTYPED_RUNE:807 x, y := x.(ast.UntypedRune), y.(ast.UntypedRune)808 c = x.Cmp(y.Int)809 case _UNTYPED_FLOAT:810 x, y := x.(ast.UntypedFloat), y.(ast.UntypedFloat)811 c = x.Cmp(y.Float)812 case _UNTYPED_COMPLEX:813 if op != ast.EQ && op != ast.NE {814 return nil, &invalidOperation{Op: op, Type: ast.BuiltinUntypedComplex}815 }816 x, y := x.(ast.UntypedComplex), y.(ast.UntypedComplex)817 u, v := x.Re.Cmp(y.Re), x.Im.Cmp(y.Im)818 if op == ast.EQ {819 return ast.Bool(u == 0 && v == 0), nil820 } else {821 return ast.Bool(u != 0 || v != 0), nil822 }823 case _UNTYPED_BOOL:824 if op != ast.EQ && op != ast.NE {825 return nil, &invalidOperation{Op: op, Type: ast.BuiltinUntypedBool}826 }827 x, y := x.(ast.Bool), y.(ast.Bool)828 if op == ast.EQ {829 return ast.Bool(x == y), nil830 } else {831 return ast.Bool(x != y), nil832 }833 case _UNTYPED_STRING:834 x, y := x.(ast.String), y.(ast.String)835 if x < y {836 c = -1837 } else if x > y {838 c = 1839 }840 default:841 panic("not reached")842 }843 return cmpToBool(c, op), nil844}845func cmpToBool(c int, op ast.Operation) ast.Bool {846 switch op {847 case ast.LT:848 return ast.Bool(c == -1)849 case ast.GT:850 return ast.Bool(c == 1)851 case ast.EQ:852 return ast.Bool(c == 0)853 case ast.NE:854 return ast.Bool(c != 0)855 case ast.LE:856 return ast.Bool(c <= 0)857 case ast.GE:858 return ast.Bool(c >= 0)859 default:860 panic("not reached")861 }862}863var untypedType = [...]*ast.BuiltinType{864 ast.BuiltinUntypedInt,865 ast.BuiltinUntypedRune,866 ast.BuiltinUntypedFloat,867 ast.BuiltinUntypedComplex,868 ast.BuiltinUntypedBool,869 ast.BuiltinUntypedString,870}871func Add(x *ast.ConstValue, y *ast.ConstValue) (*ast.ConstValue, error) {872 // If the constants are typed, they must have the same type.873 if t := builtinType(x.Typ); t != nil && !t.IsUntyped() {874 if x.Typ != y.Typ {875 return nil, &mismatchedTypes{Op: '+', X: x, Y: y}876 }877 if t.Kind == ast.BUILTIN_BOOL {878 return nil, &invalidOperation{Op: '+', Type: t}879 }880 return &ast.ConstValue{Typ: x.Typ, Value: addTyped(t, x.Value, y.Value)}, nil881 }882 // If the operands are untyped, they must either both strings, or use the883 // type later in the sequence int, rune, float, complex, by converting one884 // of the operands to the type of the other.885 var t untypedKind886 var u, v ast.Value887 switch x.Value.(type) {888 case ast.Bool:889 return nil, &invalidOperation{Op: '+', Type: ast.BuiltinUntypedBool}890 case ast.String:891 if _, ok := y.Value.(ast.String); !ok {892 return nil, &mismatchedTypes{Op: '+', X: x, Y: y}893 }894 t, u, v = _UNTYPED_STRING, x.Value, y.Value895 default:896 t, u, v = untypedConvert(x.Value, y.Value)897 if t == _UNTYPED_ERR {898 return nil, &mismatchedTypes{Op: '+', X: x, Y: y}899 }900 }901 return &ast.ConstValue{Typ: untypedType[t], Value: addUntyped(t, u, v)}, nil902}903func addTyped(typ *ast.BuiltinType, x ast.Value, y ast.Value) ast.Value {904 switch typ.Kind {905 case ast.BUILTIN_UINT8, ast.BUILTIN_UINT16, ast.BUILTIN_UINT32,906 ast.BUILTIN_UINT64, ast.BUILTIN_UINT, ast.BUILTIN_UINTPTR:907 u, v := x.(ast.Int), y.(ast.Int)908 return ast.Int(u + v)909 case ast.BUILTIN_INT8, ast.BUILTIN_INT16, ast.BUILTIN_INT32,910 ast.BUILTIN_INT64, ast.BUILTIN_INT:911 u, v := int64(x.(ast.Int)), int64(y.(ast.Int))912 return ast.Int(u + v)913 case ast.BUILTIN_FLOAT32:914 u, v := float32(x.(ast.Float)), float32(y.(ast.Float))915 return ast.Float(u + v)916 case ast.BUILTIN_FLOAT64:917 u, v := x.(ast.Float), y.(ast.Float)918 return ast.Float(u + v)919 case ast.BUILTIN_COMPLEX64:920 u, v := complex64(x.(ast.Complex)), complex64(y.(ast.Complex))921 return ast.Complex(u + v)922 case ast.BUILTIN_COMPLEX128:923 u, v := x.(ast.Complex), y.(ast.Complex)924 return ast.Complex(u + v)925 case ast.BUILTIN_STRING:926 u, v := x.(ast.String), y.(ast.String)927 return ast.String(u + v)928 default:929 panic("not reached")930 }931}932func addUntyped(t untypedKind, x ast.Value, y ast.Value) ast.Value {933 switch t {934 case _UNTYPED_INT:935 x, y := x.(ast.UntypedInt), y.(ast.UntypedInt)936 return ast.UntypedInt{Int: new(big.Int).Add(x.Int, y.Int)}937 case _UNTYPED_RUNE:938 x, y := x.(ast.UntypedRune), y.(ast.UntypedRune)939 return ast.UntypedRune{Int: new(big.Int).Add(x.Int, y.Int)}940 case _UNTYPED_FLOAT:941 x, y := x.(ast.UntypedFloat), y.(ast.UntypedFloat)942 return ast.UntypedFloat{Float: new(big.Float).Add(x.Float, y.Float)}943 case _UNTYPED_COMPLEX:944 x, y := x.(ast.UntypedComplex), y.(ast.UntypedComplex)945 return ast.UntypedComplex{946 Re: new(big.Float).Add(x.Re, y.Re),947 Im: new(big.Float).Add(x.Im, y.Im),948 }949 case _UNTYPED_STRING:950 x, y := x.(ast.String), y.(ast.String)951 return ast.String(x + y)952 default:953 panic("not reached")954 }955}956func Sub(x *ast.ConstValue, y *ast.ConstValue) (*ast.ConstValue, error) {957 // If the constants are typed, they must have the same type.958 if t := builtinType(x.Typ); t != nil && !t.IsUntyped() {959 if x.Typ != y.Typ {960 return nil, &mismatchedTypes{Op: '-', X: x, Y: y}961 }962 if t.Kind == ast.BUILTIN_BOOL || t.Kind == ast.BUILTIN_STRING {963 return nil, &invalidOperation{Op: '-', Type: t}964 }965 return &ast.ConstValue{Typ: x.Typ, Value: subTyped(t, x.Value, y.Value)}, nil966 }967 // If the operands are untyped, use the type later in the sequence int,968 // rune, float, complex, by converting one of the operands to the type of969 // the other.970 var t untypedKind971 var u, v ast.Value972 switch x.Value.(type) {973 case ast.Bool:974 return nil, &invalidOperation{Op: '-', Type: ast.BuiltinUntypedBool}975 case ast.String:976 return nil, &invalidOperation{Op: '-', Type: ast.BuiltinUntypedString}977 default:978 t, u, v = untypedConvert(x.Value, y.Value)979 if t == _UNTYPED_ERR {980 return nil, &mismatchedTypes{Op: '-', X: x, Y: y}981 }982 }983 return &ast.ConstValue{Typ: untypedType[t], Value: subUntyped(t, u, v)}, nil984}985func subTyped(typ *ast.BuiltinType, x ast.Value, y ast.Value) ast.Value {986 switch typ.Kind {987 case ast.BUILTIN_UINT8, ast.BUILTIN_UINT16, ast.BUILTIN_UINT32,988 ast.BUILTIN_UINT64, ast.BUILTIN_UINT, ast.BUILTIN_UINTPTR:989 u, v := x.(ast.Int), y.(ast.Int)990 return ast.Int(u - v)991 case ast.BUILTIN_INT8, ast.BUILTIN_INT16, ast.BUILTIN_INT32,992 ast.BUILTIN_INT64, ast.BUILTIN_INT:993 u, v := int64(x.(ast.Int)), int64(y.(ast.Int))994 return ast.Int(u - v)995 case ast.BUILTIN_FLOAT32:996 u, v := float32(x.(ast.Float)), float32(y.(ast.Float))997 return ast.Float(u - v)998 case ast.BUILTIN_FLOAT64:999 u, v := x.(ast.Float), y.(ast.Float)1000 return ast.Float(u - v)1001 case ast.BUILTIN_COMPLEX64:1002 u, v := complex64(x.(ast.Complex)), complex64(y.(ast.Complex))1003 return ast.Complex(u - v)1004 case ast.BUILTIN_COMPLEX128:1005 u, v := x.(ast.Complex), y.(ast.Complex)1006 return ast.Complex(u - v)1007 default:1008 panic("not reached")1009 }1010}1011func subUntyped(t untypedKind, x ast.Value, y ast.Value) ast.Value {1012 switch t {1013 case _UNTYPED_INT:1014 x, y := x.(ast.UntypedInt), y.(ast.UntypedInt)1015 return ast.UntypedInt{Int: new(big.Int).Sub(x.Int, y.Int)}1016 case _UNTYPED_RUNE:1017 x, y := x.(ast.UntypedRune), y.(ast.UntypedRune)1018 return ast.UntypedRune{Int: new(big.Int).Sub(x.Int, y.Int)}1019 case _UNTYPED_FLOAT:1020 x, y := x.(ast.UntypedFloat), y.(ast.UntypedFloat)1021 return ast.UntypedFloat{Float: new(big.Float).Sub(x.Float, y.Float)}1022 case _UNTYPED_COMPLEX:1023 x, y := x.(ast.UntypedComplex), y.(ast.UntypedComplex)1024 return ast.UntypedComplex{1025 Re: new(big.Float).Sub(x.Re, y.Re),1026 Im: new(big.Float).Sub(x.Im, y.Im),1027 }1028 default:1029 panic("not reached")1030 }1031}1032func Mul(x *ast.ConstValue, y *ast.ConstValue) (*ast.ConstValue, error) {1033 // If the constants are typed, they must have the same type.1034 if t := builtinType(x.Typ); t != nil && !t.IsUntyped() {1035 if x.Typ != y.Typ {1036 return nil, &mismatchedTypes{Op: '*', X: x, Y: y}1037 }1038 if t.Kind == ast.BUILTIN_BOOL || t.Kind == ast.BUILTIN_STRING {1039 return nil, &invalidOperation{Op: '*', Type: t}1040 }1041 return &ast.ConstValue{Typ: x.Typ, Value: mulTyped(t, x.Value, y.Value)}, nil1042 }1043 // If the operands are untyped, use the type later in the sequence int,1044 // rune, float, complex, by converting one of the operands to the type of1045 // the other.1046 var t untypedKind1047 var u, v ast.Value1048 switch x.Value.(type) {1049 case ast.Bool:1050 return nil, &invalidOperation{Op: '*', Type: ast.BuiltinUntypedBool}1051 case ast.String:1052 return nil, &invalidOperation{Op: '*', Type: ast.BuiltinUntypedString}1053 default:1054 t, u, v = untypedConvert(x.Value, y.Value)1055 if t == _UNTYPED_ERR {1056 return nil, &mismatchedTypes{Op: '*', X: x, Y: y}1057 }1058 }1059 return &ast.ConstValue{Typ: untypedType[t], Value: mulUntyped(t, u, v)}, nil1060}1061func mulTyped(typ *ast.BuiltinType, x ast.Value, y ast.Value) ast.Value {1062 switch typ.Kind {1063 case ast.BUILTIN_UINT8, ast.BUILTIN_UINT16, ast.BUILTIN_UINT32,1064 ast.BUILTIN_UINT64, ast.BUILTIN_UINT, ast.BUILTIN_UINTPTR:1065 u, v := x.(ast.Int), y.(ast.Int)1066 return ast.Int(u * v)1067 case ast.BUILTIN_INT8, ast.BUILTIN_INT16, ast.BUILTIN_INT32,1068 ast.BUILTIN_INT64, ast.BUILTIN_INT:1069 u, v := int64(x.(ast.Int)), int64(y.(ast.Int))1070 return ast.Int(u * v)1071 case ast.BUILTIN_FLOAT32:1072 u, v := float32(x.(ast.Float)), float32(y.(ast.Float))1073 return ast.Float(u * v)1074 case ast.BUILTIN_FLOAT64:1075 u, v := x.(ast.Float), y.(ast.Float)1076 return ast.Float(u * v)1077 case ast.BUILTIN_COMPLEX64:1078 u, v := complex64(x.(ast.Complex)), complex64(y.(ast.Complex))1079 return ast.Complex(u * v)1080 case ast.BUILTIN_COMPLEX128:1081 u, v := x.(ast.Complex), y.(ast.Complex)1082 return ast.Complex(u * v)1083 default:1084 panic("not reached")1085 }1086}1087func mulUntyped(t untypedKind, x ast.Value, y ast.Value) ast.Value {1088 switch t {1089 case _UNTYPED_INT:1090 x, y := x.(ast.UntypedInt), y.(ast.UntypedInt)1091 return ast.UntypedInt{Int: new(big.Int).Mul(x.Int, y.Int)}1092 case _UNTYPED_RUNE:1093 x, y := x.(ast.UntypedRune), y.(ast.UntypedRune)1094 return ast.UntypedRune{Int: new(big.Int).Mul(x.Int, y.Int)}1095 case _UNTYPED_FLOAT:1096 x, y := x.(ast.UntypedFloat), y.(ast.UntypedFloat)1097 return ast.UntypedFloat{Float: new(big.Float).Mul(x.Float, y.Float)}1098 case _UNTYPED_COMPLEX:1099 x, y := x.(ast.UntypedComplex), y.(ast.UntypedComplex)1100 t0 := new(big.Float).Mul(x.Re, y.Re)1101 t1 := new(big.Float).Mul(x.Im, y.Im)1102 re := new(big.Float).Sub(t0, t1)1103 t0.Mul(x.Re, y.Im)1104 t1.Mul(y.Re, x.Im)1105 im := new(big.Float).Add(t0, t1)1106 return ast.UntypedComplex{Re: re, Im: im}1107 default:1108 panic("not reached")1109 }1110}1111func Div(x *ast.ConstValue, y *ast.ConstValue) (*ast.ConstValue, error) {1112 // If the constants are typed, they must have the same type.1113 if t := builtinType(x.Typ); t != nil && !t.IsUntyped() {1114 if x.Typ != y.Typ {1115 return nil, &mismatchedTypes{Op: '/', X: x, Y: y}1116 }1117 if t.Kind == ast.BUILTIN_BOOL || t.Kind == ast.BUILTIN_STRING {1118 return nil, &invalidOperation{Op: '/', Type: t}1119 }1120 v, err := divTyped(t, x.Value, y.Value)1121 if err != nil {1122 return nil, err1123 }1124 return &ast.ConstValue{Typ: x.Typ, Value: v}, nil1125 }1126 // If the operands are untyped, use the type later in the sequence int,1127 // rune, float, complex, by converting one of the operands to the type of1128 // the other.1129 var t untypedKind1130 var u, v ast.Value1131 switch x.Value.(type) {1132 case ast.Bool:1133 return nil, &invalidOperation{Op: '/', Type: ast.BuiltinUntypedBool}1134 case ast.String:1135 return nil, &invalidOperation{Op: '/', Type: ast.BuiltinUntypedString}1136 default:1137 t, u, v = untypedConvert(x.Value, y.Value)1138 if t == _UNTYPED_ERR {1139 return nil, &mismatchedTypes{Op: '/', X: x, Y: y}1140 }1141 }1142 v, err := divUntyped(t, u, v)1143 if err != nil {1144 return nil, err1145 }1146 return &ast.ConstValue{Typ: untypedType[t], Value: v}, nil1147}1148func divTyped(typ *ast.BuiltinType, x ast.Value, y ast.Value) (ast.Value, error) {1149 if typ.IsInteger() {1150 u, v := x.(ast.Int), y.(ast.Int)1151 if v == 0 {1152 return nil, &divisionByZero{}1153 }1154 if typ.IsSigned() {1155 return ast.Int(int64(u) / int64(v)), nil1156 } else {1157 return ast.Int(u / v), nil1158 }1159 }1160 switch typ.Kind {1161 case ast.BUILTIN_FLOAT32:1162 u, v := float32(x.(ast.Float)), float32(y.(ast.Float))1163 if v == 0 {1164 return nil, &divisionByZero{}1165 }1166 return ast.Float(u / v), nil1167 case ast.BUILTIN_FLOAT64:1168 u, v := x.(ast.Float), y.(ast.Float)1169 if v == 0 {1170 return nil, &divisionByZero{}1171 }1172 return ast.Float(u / v), nil1173 case ast.BUILTIN_COMPLEX64:1174 u, v := complex64(x.(ast.Complex)), complex64(y.(ast.Complex))1175 a, b, c, d := real(u), imag(u), real(v), imag(v)1176 z := c*c + d*d1177 if z == 0 {1178 return nil, &divisionByZero{}1179 }1180 re := float64((a*c + b*d) / z)1181 im := float64((b*c - a*d) / z)1182 return ast.Complex(complex(re, im)), nil1183 case ast.BUILTIN_COMPLEX128:1184 u, v := x.(ast.Complex), y.(ast.Complex)1185 a, b, c, d := real(u), imag(u), real(v), imag(v)1186 z := c*c + d*d1187 if z == 0 {1188 return nil, &divisionByZero{}1189 }1190 re := (a*c + b*d) / z1191 im := (b*c - a*d) / z1192 return ast.Complex(complex(re, im)), nil1193 default:1194 panic("not reached")1195 }1196}1197func divUntyped(t untypedKind, x ast.Value, y ast.Value) (ast.Value, error) {1198 switch t {1199 case _UNTYPED_INT:1200 x, y := x.(ast.UntypedInt), y.(ast.UntypedInt)1201 if y.Int.Cmp(&zeroInt) == 0 {1202 return nil, &divisionByZero{}1203 }1204 return ast.UntypedInt{Int: new(big.Int).Div(x.Int, y.Int)}, nil1205 case _UNTYPED_RUNE:1206 x, y := x.(ast.UntypedRune), y.(ast.UntypedRune)1207 if y.Int.Cmp(&zeroInt) == 0 {1208 return nil, &divisionByZero{}1209 }1210 return ast.UntypedRune{Int: new(big.Int).Div(x.Int, y.Int)}, nil1211 case _UNTYPED_FLOAT:1212 x, y := x.(ast.UntypedFloat), y.(ast.UntypedFloat)1213 if y.Float.Cmp(&zeroFloat) == 0 {1214 return nil, &divisionByZero{}1215 }1216 return ast.UntypedFloat{Float: new(big.Float).Quo(x.Float, y.Float)}, nil1217 case _UNTYPED_COMPLEX:1218 x, y := x.(ast.UntypedComplex), y.(ast.UntypedComplex)1219 a, b, c, d := x.Re, x.Im, y.Re, y.Im1220 t0 := new(big.Float).Mul(c, c)1221 t1 := new(big.Float).Mul(d, d)1222 z := new(big.Float).Add(t0, t1)1223 if z.Cmp(&zeroFloat) == 0 {1224 return nil, &divisionByZero{}1225 }1226 t0.Mul(a, c)1227 t1.Mul(b, d)1228 re := new(big.Float).Add(t0, t1)1229 re.Quo(re, z)1230 t0.Mul(b, c)1231 t1.Mul(a, d)1232 im := t0.Sub(t0, t1).Quo(t0, z)1233 return ast.UntypedComplex{Re: re, Im: im}, nil1234 default:1235 panic("not reached")1236 }1237}1238func Rem(x *ast.ConstValue, y *ast.ConstValue) (*ast.ConstValue, error) {1239 // If the constants are typed, they must have the same type.1240 tx := builtinType(x.Typ)1241 if !tx.IsUntyped() {1242 if x.Typ != y.Typ {1243 return nil, &mismatchedTypes{Op: '%', X: x, Y: y}1244 }1245 // Only integer operands.1246 if !tx.IsInteger() {1247 return nil, &invalidOperation{Op: '%', Type: tx}1248 }1249 u, v := x.Value.(ast.Int), y.Value.(ast.Int)1250 if v == 0 {1251 return nil, &divisionByZero{}1252 }1253 if tx.IsSigned() {1254 return &ast.ConstValue{Typ: x.Typ, Value: ast.Int(int64(u) % int64(v))}, nil1255 } else {1256 return &ast.ConstValue{Typ: x.Typ, Value: ast.Int(u % v)}, nil1257 }1258 }1259 // Only untyped integers and runes allowed.1260 var u, v *big.Int1261 switch {1262 case tx == ast.BuiltinUntypedInt:1263 u = x.Value.(ast.UntypedInt).Int1264 case tx == ast.BuiltinUntypedRune:1265 u = x.Value.(ast.UntypedRune).Int1266 default:1267 return nil, &invalidOperation{Op: '%', Type: tx}1268 }1269 ty := builtinType(y.Typ)1270 switch {1271 case ty == ast.BuiltinUntypedInt:1272 v = y.Value.(ast.UntypedInt).Int1273 case ty == ast.BuiltinUntypedRune:1274 v = y.Value.(ast.UntypedRune).Int1275 tx = ast.BuiltinUntypedRune1276 default:1277 return nil, &invalidOperation{Op: '%', Type: ty}1278 }1279 if v.Cmp(&zeroInt) == 0 {1280 return nil, &divisionByZero{}1281 }1282 var res ast.Value1283 r := new(big.Int).Rem(u, v)1284 if tx == ast.BuiltinUntypedRune {1285 res = ast.UntypedRune{Int: r}1286 } else {1287 res = ast.UntypedInt{Int: r}1288 }1289 return &ast.ConstValue{Typ: tx, Value: res}, nil1290}1291func Bit(op ast.Operation, x *ast.ConstValue, y *ast.ConstValue) (*ast.ConstValue, error) {1292 // If the constants are typed, they must have the same type.1293 tx := builtinType(x.Typ)1294 if !tx.IsUntyped() {1295 if x.Typ != y.Typ {1296 return nil, &mismatchedTypes{Op: op, X: x, Y: y}1297 }1298 // Only integer operands.1299 if !tx.IsInteger() {1300 return nil, &invalidOperation{Op: op, Type: tx}1301 }1302 v := bitTyped(op, x.Value.(ast.Int), y.Value.(ast.Int))1303 return &ast.ConstValue{Typ: x.Typ, Value: v}, nil1304 }1305 // Only untyped integers and runes allowed.1306 var u, v *big.Int1307 switch {1308 case tx == ast.BuiltinUntypedInt:1309 u = x.Value.(ast.UntypedInt).Int1310 case tx == ast.BuiltinUntypedRune:1311 u = x.Value.(ast.UntypedRune).Int1312 default:1313 return nil, &invalidOperation{Op: op, Type: tx}1314 }1315 ty := builtinType(y.Typ)1316 switch {1317 case ty == ast.BuiltinUntypedInt:1318 v = y.Value.(ast.UntypedInt).Int1319 case ty == ast.BuiltinUntypedRune:1320 v = y.Value.(ast.UntypedRune).Int1321 tx = ast.BuiltinUntypedRune1322 default:1323 return nil, &invalidOperation{Op: op, Type: ty}1324 }1325 r := bitUntyped(op, u, v)1326 var res ast.Value1327 if tx == ast.BuiltinUntypedRune {1328 res = ast.UntypedRune{Int: r}1329 } else {1330 res = ast.UntypedInt{Int: r}1331 }1332 return &ast.ConstValue{Typ: tx, Value: res}, nil1333}1334func bitTyped(op ast.Operation, x ast.Int, y ast.Int) ast.Int {1335 switch op {1336 case '&':1337 return x & y1338 case '|':1339 return x | y1340 case '^':1341 return x ^ y1342 case ast.ANDN:1343 return x &^ y1344 default:1345 panic("not reached")1346 }1347}1348func bitUntyped(op ast.Operation, x *big.Int, y *big.Int) *big.Int {1349 switch op {1350 case '&':1351 return new(big.Int).And(x, y)1352 case '|':1353 return new(big.Int).Or(x, y)1354 case '^':1355 return new(big.Int).Xor(x, y)1356 case ast.ANDN:1357 return new(big.Int).AndNot(x, y)1358 default:1359 panic("not reached")1360 }1361}1362func Logical(1363 op ast.Operation, x *ast.ConstValue, y *ast.ConstValue) (*ast.ConstValue, error) {1364 tx, ty := builtinType(x.Typ), builtinType(y.Typ)1365 if tx.Kind != ast.BUILTIN_BOOL && tx.Kind != ast.BUILTIN_UNTYPED_BOOL {1366 return nil, &invalidOperation{Op: op, Type: tx}1367 }1368 if ty.Kind != ast.BUILTIN_BOOL && ty.Kind != ast.BUILTIN_UNTYPED_BOOL {1369 return nil, &invalidOperation{Op: op, Type: ty}1370 }1371 if x.Typ != y.Typ {1372 return nil, &mismatchedTypes{Op: op, X: x, Y: y}1373 }1374 var v bool1375 if op == ast.AND {1376 v = bool(x.Value.(ast.Bool)) && bool(y.Value.(ast.Bool))1377 } else {1378 v = bool(x.Value.(ast.Bool)) || bool(y.Value.(ast.Bool))1379 }1380 return &ast.ConstValue{Typ: x.Typ, Value: ast.Bool(v)}, nil1381}1382func Real(x *ast.ConstValue) (*ast.ConstValue, error) {1383 tx := builtinType(x.Typ)1384 switch tx.Kind {1385 case ast.BUILTIN_COMPLEX64:1386 v := float32(real(x.Value.(ast.Complex)))1387 return &ast.ConstValue{Typ: ast.BuiltinFloat32, Value: ast.Float(v)}, nil1388 case ast.BUILTIN_COMPLEX128:1389 v := real(x.Value.(ast.Complex))1390 return &ast.ConstValue{Typ: ast.BuiltinFloat64, Value: ast.Float(v)}, nil1391 case ast.BUILTIN_UNTYPED_COMPLEX:1392 re := new(big.Float).Copy(x.Value.(ast.UntypedComplex).Re)1393 return &ast.ConstValue{1394 Typ: ast.BuiltinUntypedFloat,1395 Value: ast.UntypedFloat{Float: re}}, nil1396 case ast.BUILTIN_UNTYPED_FLOAT:1397 re := x.Value.(ast.UntypedFloat).Float1398 return &ast.ConstValue{1399 Typ: tx,1400 Value: ast.UntypedFloat{Float: re}}, nil1401 case ast.BUILTIN_UNTYPED_INT:1402 re := bigIntToFloat(x.Value.(ast.UntypedInt).Int)1403 return &ast.ConstValue{1404 Typ: ast.BuiltinUntypedFloat,1405 Value: ast.UntypedFloat{Float: re}}, nil1406 case ast.BUILTIN_UNTYPED_RUNE:1407 re := bigIntToFloat(x.Value.(ast.UntypedRune).Int)1408 return &ast.ConstValue{1409 Typ: ast.BuiltinUntypedFloat,1410 Value: ast.UntypedFloat{Float: re}}, nil1411 default:1412 return nil, &invalidOperation{Op: ast.REAL, Type: tx}1413 }1414}1415func Imag(x *ast.ConstValue) (*ast.ConstValue, error) {1416 tx := builtinType(x.Typ)1417 switch tx.Kind {1418 case ast.BUILTIN_COMPLEX64:1419 v := float32(imag(x.Value.(ast.Complex)))1420 return &ast.ConstValue{Typ: ast.BuiltinFloat32, Value: ast.Float(v)}, nil1421 case ast.BUILTIN_COMPLEX128:1422 v := imag(x.Value.(ast.Complex))1423 return &ast.ConstValue{Typ: ast.BuiltinFloat64, Value: ast.Float(v)}, nil1424 case ast.BUILTIN_UNTYPED_COMPLEX:1425 im := new(big.Float).Copy(x.Value.(ast.UntypedComplex).Im)1426 return &ast.ConstValue{1427 Typ: ast.BuiltinUntypedFloat,1428 Value: ast.UntypedFloat{Float: im}}, nil1429 case ast.BUILTIN_UNTYPED_FLOAT:1430 zero := new(big.Float).1431 SetPrec(ast.UNTYPED_FLOAT_PRECISION).1432 SetMode(big.ToNearestEven)1433 return &ast.ConstValue{1434 Typ: tx,1435 Value: ast.UntypedFloat{Float: zero}}, nil1436 case ast.BUILTIN_UNTYPED_INT:1437 zero := new(big.Float).1438 SetPrec(ast.UNTYPED_FLOAT_PRECISION).1439 SetMode(big.ToNearestEven)1440 return &ast.ConstValue{1441 Typ: ast.BuiltinUntypedFloat,1442 Value: ast.UntypedFloat{Float: zero}}, nil1443 case ast.BUILTIN_UNTYPED_RUNE:1444 zero := new(big.Float).1445 SetPrec(ast.UNTYPED_FLOAT_PRECISION).1446 SetMode(big.ToNearestEven)1447 return &ast.ConstValue{1448 Typ: ast.BuiltinUntypedFloat,1449 Value: ast.UntypedFloat{Float: zero}}, nil1450 default:1451 return nil, &invalidOperation{Op: ast.IMAG, Type: tx}1452 }1453}1454func Complex(x *ast.ConstValue, y *ast.ConstValue) (*ast.ConstValue, error) {1455 tx, ty := builtinType(x.Typ), builtinType(y.Typ)1456 if !tx.IsUntyped() {1457 // If the operands are typed, they should be of the same type, and1458 // either `float32` or `float64`1459 if tx != ast.BuiltinFloat32 && tx != ast.BuiltinFloat64 {1460 return nil, &invalidOperation{Op: ast.CMPLX, Type: tx}1461 }1462 if ty != ast.BuiltinFloat32 && ty != ast.BuiltinFloat64 {1463 return nil, &invalidOperation{Op: ast.CMPLX, Type: ty}1464 }1465 if tx != ty {1466 return nil, &mismatchedTypes{Op: ast.CMPLX, X: x, Y: y}1467 }1468 u, v := x.Value.(ast.Float), y.Value.(ast.Float)1469 typ := ast.BuiltinComplex1281470 if tx == ast.BuiltinFloat32 {1471 typ = ast.BuiltinComplex641472 }1473 return &ast.ConstValue{Typ: typ, Value: ast.Complex(complex(u, v))}, nil1474 }1475 // If the operands are untyped, they should be of a numeric type, and, if1476 // complex, the imaginary part must be zero.1477 var u *big.Float1478 switch tx.Kind {1479 case ast.BUILTIN_UNTYPED_INT:1480 u = bigIntToFloat(x.Value.(ast.UntypedInt).Int)1481 case ast.BUILTIN_UNTYPED_RUNE:1482 u = bigIntToFloat(x.Value.(ast.UntypedRune).Int)1483 case ast.BUILTIN_UNTYPED_FLOAT:1484 u = new(big.Float).Copy(x.Value.(ast.UntypedFloat).Float)1485 case ast.BUILTIN_UNTYPED_COMPLEX:1486 c := x.Value.(ast.UntypedComplex)1487 if c.Im.Cmp(&zeroFloat) != 0 {1488 return nil, &badOperandValue{Op: ast.CMPLX, X: x}1489 }1490 u = new(big.Float).Copy(c.Re)1491 default:1492 return nil, &invalidOperation{Op: ast.CMPLX, Type: tx}1493 }1494 var v *big.Float1495 switch ty.Kind {1496 case ast.BUILTIN_UNTYPED_INT:1497 v = bigIntToFloat(y.Value.(ast.UntypedInt).Int)1498 case ast.BUILTIN_UNTYPED_RUNE:1499 v = bigIntToFloat(y.Value.(ast.UntypedRune).Int)1500 case ast.BUILTIN_UNTYPED_FLOAT:1501 v = new(big.Float).Copy(y.Value.(ast.UntypedFloat).Float)1502 case ast.BUILTIN_UNTYPED_COMPLEX:1503 c := y.Value.(ast.UntypedComplex)1504 if c.Im.Cmp(&zeroFloat) != 0 {1505 return nil, &badOperandValue{Op: ast.CMPLX, X: y}1506 }1507 v = new(big.Float).Copy(c.Re)1508 default:1509 return nil, &invalidOperation{Op: ast.CMPLX, Type: ty}1510 }1511 return &ast.ConstValue{1512 Typ: ast.BuiltinUntypedComplex, Value: ast.UntypedComplex{Re: u, Im: v}}, nil1513}1514// The badConversion error is returned when the destination type cannot1515// represent the value of the converted constant.1516type badConstConversion struct {1517 Dst ast.Type1518 Src *ast.ConstValue1519}1520func (e *badConstConversion) Error() string {1521 return fmt.Sprintf("%s (`%s`) cannot be converted to `%s`",1522 e.Src, e.Src.TypeString(), e.Dst)1523}1524type badShiftCount struct {1525 X *ast.ConstValue1526}1527func (e *badShiftCount) Error() string {1528 return fmt.Sprintf("invalid shift count `%s` (`%s`)", e.X, e.X.Typ)1529}1530type bigShiftCount struct {1531 X uint641532}1533func (e *bigShiftCount) Error() string {1534 return fmt.Sprintf("shift count too big: %d", e.X)1535}1536type badOperandValue struct {1537 Op ast.Operation1538 X *ast.ConstValue1539}1540func (e *badOperandValue) Error() string {1541 return fmt.Sprintf("invalid operand to `%s`: `%s`", e.Op, e.X)1542}1543type badOperandType struct {1544 Op ast.Operation1545 Type string1546 X *ast.ConstValue1547}1548func (e *badOperandType) Error() string {1549 return fmt.Sprintf("invalid operand to `%s`: operand must have %s (`%s` given)",1550 e.Op, e.Type, e.X.TypeString())1551}1552type invalidOperation struct {1553 Op ast.Operation1554 Type *ast.BuiltinType1555}1556func (e *invalidOperation) Error() string {1557 return fmt.Sprintf("operation `%s` not supported for `%s`", e.Op, e.Type)1558}1559type mismatchedTypes struct {1560 Op ast.Operation1561 X, Y *ast.ConstValue1562}1563func (e *mismatchedTypes) Error() string {1564 return fmt.Sprintf("invalid operation `%s`: mismatched types `%s` and `%s`",1565 e.Op, e.X.TypeString(), e.Y.TypeString())1566}1567type divisionByZero struct{}1568func (e *divisionByZero) Error() string {...

Full Screen

Full Screen

builtin.go

Source:builtin.go Github

copy

Full Screen

...33 "github.com/pingcap/tidb/types"34 "github.com/pingcap/tidb/util/chunk"35 "github.com/pingcap/tipb/go-tipb"36)37// baseBuiltinFunc will be contained in every struct that implement builtinFunc interface.38type baseBuiltinFunc struct {39 bufAllocator columnBufferAllocator40 args []Expression41 ctx sessionctx.Context42 tp *types.FieldType43 pbCode tipb.ScalarFuncSig44 childrenVectorizedOnce *sync.Once45 childrenVectorized bool46}47func (b *baseBuiltinFunc) PbCode() tipb.ScalarFuncSig {48 return b.pbCode49}50// metadata returns the metadata of a function.51// metadata means some functions contain extra inner fields which will not52// contain in `tipb.Expr.children` but must be pushed down to coprocessor53func (b *baseBuiltinFunc) metadata() proto.Message {54 // We will not use a field to store them because of only55 // a few functions contain implicit parameters56 return nil57}58func (b *baseBuiltinFunc) setPbCode(c tipb.ScalarFuncSig) {59 b.pbCode = c60}61func newBaseBuiltinFunc(ctx sessionctx.Context, args []Expression) baseBuiltinFunc {62 if ctx == nil {63 panic("ctx should not be nil")64 }65 return baseBuiltinFunc{66 bufAllocator: newLocalSliceBuffer(len(args)),67 childrenVectorizedOnce: new(sync.Once),68 args: args,69 ctx: ctx,70 tp: types.NewFieldType(mysql.TypeUnspecified),71 }72}73// newBaseBuiltinFuncWithTp creates a built-in function signature with specified types of arguments and the return type of the function.74// argTps indicates the types of the args, retType indicates the return type of the built-in function.75// Every built-in function needs determined argTps and retType when we create it.76func newBaseBuiltinFuncWithTp(ctx sessionctx.Context, args []Expression, retType types.EvalType, argTps ...types.EvalType) (bf baseBuiltinFunc) {77 if len(args) != len(argTps) {78 panic("unexpected length of args and argTps")79 }80 if ctx == nil {81 panic("ctx should not be nil")82 }83 for i := range args {84 if argTps[i] != args[i].GetType().EvalType() {85 log.Warn(fmt.Sprintf("unmatched arg type %v with %v", argTps[i], args[i].GetType().EvalType()))86 }87 }88 var fieldType *types.FieldType89 switch retType {90 case types.ETInt:91 fieldType = &types.FieldType{92 Tp: mysql.TypeLonglong,93 Flen: mysql.MaxIntWidth,94 Decimal: 0,95 Flag: mysql.BinaryFlag,96 }97 case types.ETReal:98 fieldType = &types.FieldType{99 Tp: mysql.TypeDouble,100 Flen: mysql.MaxRealWidth,101 Decimal: types.UnspecifiedLength,102 Flag: mysql.BinaryFlag,103 }104 case types.ETString:105 fieldType = &types.FieldType{106 Tp: mysql.TypeVarString,107 Flen: 0,108 Decimal: types.UnspecifiedLength,109 }110 }111 if mysql.HasBinaryFlag(fieldType.Flag) {112 fieldType.Charset, fieldType.Collate = charset.CharsetBin, charset.CollationBin113 } else {114 fieldType.Charset, fieldType.Collate = charset.GetDefaultCharsetAndCollate()115 }116 return baseBuiltinFunc{117 bufAllocator: newLocalSliceBuffer(len(args)),118 childrenVectorizedOnce: new(sync.Once),119 args: args,120 ctx: ctx,121 tp: fieldType,122 }123}124func (b *baseBuiltinFunc) getArgs() []Expression {125 return b.args126}127func (b *baseBuiltinFunc) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error {128 return errors.Errorf("baseBuiltinFunc.vecEvalInt() should never be called, please contact the TiDB team for help")129}130func (b *baseBuiltinFunc) vecEvalReal(input *chunk.Chunk, result *chunk.Column) error {131 return errors.Errorf("baseBuiltinFunc.vecEvalReal() should never be called, please contact the TiDB team for help")132}133func (b *baseBuiltinFunc) vecEvalString(input *chunk.Chunk, result *chunk.Column) error {134 return errors.Errorf("baseBuiltinFunc.vecEvalString() should never be called, please contact the TiDB team for help")135}136func (b *baseBuiltinFunc) vecEvalDecimal(input *chunk.Chunk, result *chunk.Column) error {137 return errors.Errorf("baseBuiltinFunc.vecEvalDecimal() should never be called, please contact the TiDB team for help")138}139func (b *baseBuiltinFunc) vecEvalTime(input *chunk.Chunk, result *chunk.Column) error {140 return errors.Errorf("baseBuiltinFunc.vecEvalTime() should never be called, please contact the TiDB team for help")141}142func (b *baseBuiltinFunc) vecEvalDuration(input *chunk.Chunk, result *chunk.Column) error {143 return errors.Errorf("baseBuiltinFunc.vecEvalDuration() should never be called, please contact the TiDB team for help")144}145func (b *baseBuiltinFunc) vecEvalJSON(input *chunk.Chunk, result *chunk.Column) error {146 return errors.Errorf("baseBuiltinFunc.vecEvalJSON() should never be called, please contact the TiDB team for help")147}148func (b *baseBuiltinFunc) evalInt(row chunk.Row) (int64, bool, error) {149 return 0, false, errors.Errorf("baseBuiltinFunc.evalInt() should never be called, please contact the TiDB team for help")150}151func (b *baseBuiltinFunc) evalReal(row chunk.Row) (float64, bool, error) {152 return 0, false, errors.Errorf("baseBuiltinFunc.evalReal() should never be called, please contact the TiDB team for help")153}154func (b *baseBuiltinFunc) evalString(row chunk.Row) (string, bool, error) {155 return "", false, errors.Errorf("baseBuiltinFunc.evalString() should never be called, please contact the TiDB team for help")156}157func (b *baseBuiltinFunc) vectorized() bool {158 return false159}160func (b *baseBuiltinFunc) isChildrenVectorized() bool {161 b.childrenVectorizedOnce.Do(func() {162 b.childrenVectorized = true163 for _, arg := range b.args {164 if !arg.Vectorized() {165 b.childrenVectorized = false166 break167 }168 }169 })170 return b.childrenVectorized171}172func (b *baseBuiltinFunc) getRetTp() *types.FieldType {173 switch b.tp.EvalType() {174 case types.ETString:175 if b.tp.Flen >= mysql.MaxBlobWidth {176 b.tp.Tp = mysql.TypeLongBlob177 } else if b.tp.Flen >= 65536 {178 b.tp.Tp = mysql.TypeMediumBlob179 }180 if len(b.tp.Charset) <= 0 {181 b.tp.Charset, b.tp.Collate = charset.GetDefaultCharsetAndCollate()182 }183 }184 return b.tp185}186func (b *baseBuiltinFunc) equal(fun builtinFunc) bool {187 funArgs := fun.getArgs()188 if len(funArgs) != len(b.args) {189 return false190 }191 for i := range b.args {192 if !b.args[i].Equal(b.ctx, funArgs[i]) {193 return false194 }195 }196 return true197}198func (b *baseBuiltinFunc) getCtx() sessionctx.Context {199 return b.ctx200}201func (b *baseBuiltinFunc) cloneFrom(from *baseBuiltinFunc) {202 b.args = make([]Expression, 0, len(b.args))203 for _, arg := range from.args {204 b.args = append(b.args, arg.Clone())205 }206 b.ctx = from.ctx207 b.tp = from.tp208 b.pbCode = from.pbCode209 b.bufAllocator = newLocalSliceBuffer(len(b.args))210 b.childrenVectorizedOnce = new(sync.Once)211}212func (b *baseBuiltinFunc) Clone() builtinFunc {213 panic("you should not call this method.")214}215// vecBuiltinFunc contains all vectorized methods for a builtin function.216type vecBuiltinFunc interface {217 // vectorized returns if this builtin function itself supports vectorized evaluation.218 vectorized() bool219 // isChildrenVectorized returns if its all children support vectorized evaluation.220 isChildrenVectorized() bool221 // vecEvalInt evaluates this builtin function in a vectorized manner.222 vecEvalInt(input *chunk.Chunk, result *chunk.Column) error223 // vecEvalReal evaluates this builtin function in a vectorized manner.224 vecEvalReal(input *chunk.Chunk, result *chunk.Column) error225 // vecEvalString evaluates this builtin function in a vectorized manner.226 vecEvalString(input *chunk.Chunk, result *chunk.Column) error227 // vecEvalDecimal evaluates this builtin function in a vectorized manner.228 vecEvalDecimal(input *chunk.Chunk, result *chunk.Column) error229 // vecEvalTime evaluates this builtin function in a vectorized manner.230 vecEvalTime(input *chunk.Chunk, result *chunk.Column) error231 // vecEvalDuration evaluates this builtin function in a vectorized manner.232 vecEvalDuration(input *chunk.Chunk, result *chunk.Column) error233 // vecEvalJSON evaluates this builtin function in a vectorized manner.234 vecEvalJSON(input *chunk.Chunk, result *chunk.Column) error235}236// builtinFunc stands for a particular function signature.237type builtinFunc interface {238 vecBuiltinFunc239 // evalInt evaluates int result of builtinFunc by given row.240 evalInt(row chunk.Row) (val int64, isNull bool, err error)241 // evalReal evaluates real representation of builtinFunc by given row.242 evalReal(row chunk.Row) (val float64, isNull bool, err error)243 // evalString evaluates string representation of builtinFunc by given row.244 evalString(row chunk.Row) (val string, isNull bool, err error)245 // getArgs returns the arguments expressions.246 getArgs() []Expression247 // equal check if this function equals to another function.248 equal(builtinFunc) bool249 // getCtx returns this function's context.250 getCtx() sessionctx.Context251 // getRetTp returns the return type of the built-in function.252 getRetTp() *types.FieldType253 // setPbCode sets pbCode for signature.254 setPbCode(tipb.ScalarFuncSig)255 // PbCode returns PbCode of this signature.256 PbCode() tipb.ScalarFuncSig257 // metadata returns the metadata of a function.258 // metadata means some functions contain extra inner fields which will not259 // contain in `tipb.Expr.children` but must be pushed down to coprocessor260 metadata() proto.Message261 // Clone returns a copy of itself.262 Clone() builtinFunc263}264// baseFunctionClass will be contained in every struct that implement functionClass interface.265type baseFunctionClass struct {266 funcName string267 minArgs int268 maxArgs int269}270func (b *baseFunctionClass) verifyArgs(args []Expression) error {271 l := len(args)272 if l < b.minArgs || (b.maxArgs != -1 && l > b.maxArgs) {273 return ErrIncorrectParameterCount.GenWithStackByArgs(b.funcName)274 }275 return nil276}277// functionClass is the interface for a function which may contains multiple functions.278type functionClass interface {279 // getFunction gets a function signature by the types and the counts of given arguments.280 getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error)281}282// funcs holds all registered builtin functions. When new function is added,283// check expression/function_traits.go to see if it should be appended to284// any set there.285var funcs = map[string]functionClass{286 // common functions287 ast.IsNull: &isNullFunctionClass{baseFunctionClass{ast.IsNull, 1, 1}},288 // string functions289 ast.Length: &lengthFunctionClass{baseFunctionClass{ast.Length, 1, 1}},290 ast.OctetLength: &lengthFunctionClass{baseFunctionClass{ast.OctetLength, 1, 1}},291 ast.Strcmp: &strcmpFunctionClass{baseFunctionClass{ast.Strcmp, 2, 2}},292 // control functions293 ast.If: &ifFunctionClass{baseFunctionClass{ast.If, 3, 3}},294 ast.Ifnull: &ifNullFunctionClass{baseFunctionClass{ast.Ifnull, 2, 2}},295 ast.LogicAnd: &logicAndFunctionClass{baseFunctionClass{ast.LogicAnd, 2, 2}},296 ast.LogicOr: &logicOrFunctionClass{baseFunctionClass{ast.LogicOr, 2, 2}},297 ast.GE: &compareFunctionClass{baseFunctionClass{ast.GE, 2, 2}, opcode.GE},298 ast.LE: &compareFunctionClass{baseFunctionClass{ast.LE, 2, 2}, opcode.LE},299 ast.EQ: &compareFunctionClass{baseFunctionClass{ast.EQ, 2, 2}, opcode.EQ},300 ast.NE: &compareFunctionClass{baseFunctionClass{ast.NE, 2, 2}, opcode.NE},301 ast.LT: &compareFunctionClass{baseFunctionClass{ast.LT, 2, 2}, opcode.LT},302 ast.GT: &compareFunctionClass{baseFunctionClass{ast.GT, 2, 2}, opcode.GT},303 ast.Plus: &arithmeticPlusFunctionClass{baseFunctionClass{ast.Plus, 2, 2}},304 ast.Minus: &arithmeticMinusFunctionClass{baseFunctionClass{ast.Minus, 2, 2}},305 ast.Div: &arithmeticDivideFunctionClass{baseFunctionClass{ast.Div, 2, 2}},306 ast.Mul: &arithmeticMultiplyFunctionClass{baseFunctionClass{ast.Mul, 2, 2}},307 ast.UnaryNot: &unaryNotFunctionClass{baseFunctionClass{ast.UnaryNot, 1, 1}},308 ast.UnaryMinus: &unaryMinusFunctionClass{baseFunctionClass{ast.UnaryMinus, 1, 1}},309 ast.In: &inFunctionClass{baseFunctionClass{ast.In, 2, -1}},310 ast.RowFunc: &rowFunctionClass{baseFunctionClass{ast.RowFunc, 2, -1}},311 ast.SetVar: &setVarFunctionClass{baseFunctionClass{ast.SetVar, 2, 2}},312 ast.GetVar: &getVarFunctionClass{baseFunctionClass{ast.GetVar, 1, 1}},313}314// IsFunctionSupported check if given function name is a builtin sql function.315func IsFunctionSupported(name string) bool {316 _, ok := funcs[name]317 return ok318}319// GetBuiltinList returns a list of builtin functions320func GetBuiltinList() []string {321 res := make([]string, 0, len(funcs))322 notImplementedFunctions := []string{ast.RowFunc}323 for funcName := range funcs {324 skipFunc := false325 // Skip not implemented functions326 for _, notImplFunc := range notImplementedFunctions {327 if funcName == notImplFunc {328 skipFunc = true329 }330 }331 // Skip literal functions332 // (their names are not readable: 'tidb`.(dateliteral, for example)333 // See: https://github.com/pingcap/tidb/parser/pull/591334 if strings.HasPrefix(funcName, "'tidb`.(") {...

Full Screen

Full Screen

types.go

Source:types.go Github

copy

Full Screen

...51 Name: s,52 Node: ast.NewIdent("__" + s),53 }54}55func (p *protoConverter) setBuiltin(from string, to func() ast.Expr, pkg *protoConverter) {56 p.scope[0][from] = mapping{to, pkg}57}58func (p *protoConverter) setBuiltinParse(from, to string, pkg *protoConverter) {59 f := func() ast.Expr {60 expr, err := parser.ParseExpr("", to, parser.ParseComments)61 if err != nil {62 panic(fmt.Sprintf("error parsing name %q: %v", to, err))63 }64 return expr65 }66 p.scope[0][from] = mapping{f, pkg}67}68var (69 pkgTime = &protoConverter{cuePkgPath: "time"}70 pkgStruct = &protoConverter{cuePkgPath: "struct"}71 importTime = ast.NewImport(nil, "time")72 importStruct = ast.NewImport(nil, "struct")73)74func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, required bool) (generate bool) {75 // Map some builtin types to their JSON/CUE mappings.76 switch file {77 case "gogoproto/gogo.proto":78 case "google/protobuf/struct.proto":79 p.setBuiltin("google.protobuf.Struct", func() ast.Expr {80 return ast.NewStruct()81 }, nil)82 p.setBuiltin("google.protobuf.Value", func() ast.Expr {83 return ast.NewIdent("_")84 }, nil)85 p.setBuiltin("google.protobuf.NullValue", func() ast.Expr {86 return ast.NewNull()87 }, nil)88 p.setBuiltin("google.protobuf.ListValue", func() ast.Expr {89 return ast.NewList(&ast.Ellipsis{})90 }, nil)91 p.setBuiltin("google.protobuf.StringValue", func() ast.Expr {92 return predeclared("string")93 }, nil)94 p.setBuiltin("google.protobuf.BoolValue", func() ast.Expr {95 return predeclared("bool")96 }, nil)97 p.setBuiltin("google.protobuf.NumberValue", func() ast.Expr {98 return predeclared("number")99 }, nil)100 return false101 case "google/protobuf/empty.proto":102 f := func() ast.Expr {103 time := &ast.Ident{Name: "struct", Node: importStruct}104 return ast.NewCall(105 ast.NewSel(time, "MaxFields"),106 ast.NewLit(token.INT, "0"),107 )108 }109 p.setBuiltin("google.protobuf.Empty", f, pkgStruct)110 return false111 case "google/protobuf/duration.proto":112 f := func() ast.Expr {113 time := &ast.Ident{Name: "time", Node: importTime}114 return ast.NewSel(time, "Duration")115 }116 p.setBuiltin("google.protobuf.Duration", f, pkgTime)117 return false118 case "google/protobuf/timestamp.proto":119 f := func() ast.Expr {120 time := &ast.Ident{Name: "time", Node: importTime}121 return ast.NewSel(time, "Time")122 }123 p.setBuiltin("google.protobuf.Timestamp", f, pkgTime)124 return false125 case "google/protobuf/any.proto":126 // TODO: technically, the value should be `_` (anything), but that127 // will not convert to a valid OpenAPI value. In practice, all128 // "well-known" types except wrapper types (which will likely not129 // be used here) are represented as strings.130 //131 // In Structural OpenAPI this type cannot be represented.132 p.setBuiltinParse("google.protobuf.Any", `{133 // A URL/resource name that uniquely identifies the type of the serialized protocol buffer message. This string must contain at least one "/" character. The last segment of the URL's path must represent the fully qualified name of the type (as in `+134 "`type.googleapis.com/google.protobuf.Duration`"+`). The name should be in a canonical form (e.g., leading "." is not accepted).135 // The remaining fields of this object correspond to fields of the proto messsage. If the embedded message is well-known and has a custom JSON representation, that representation is assigned to the 'value' field.136 "@type": string,137}`, nil)138 return false139 case "google/protobuf/wrappers.proto":140 p.setBuiltinParse("google.protobuf.DoubleValue", `null | float`, nil)141 p.setBuiltinParse("google.protobuf.FloatValue", `null | float`, nil)142 p.setBuiltinParse("google.protobuf.Int64Value", `null | int64`, nil)143 p.setBuiltinParse("google.protobuf.UInt64Value", `null | uint64`, nil)144 p.setBuiltinParse("google.protobuf.Int32Value", `null | int32`, nil)145 p.setBuiltinParse("google.protobuf.UInt32Value", `null | uint32`, nil)146 p.setBuiltinParse("google.protobuf.BoolValue", `null | bool`, nil)147 p.setBuiltinParse("google.protobuf.StringValue", `null | string`, nil)148 p.setBuiltinParse("google.protobuf.BytesValue", `null | bytes`, nil)149 return false150 // case "google/protobuf/field_mask.proto":151 // p.setBuiltin("google.protobuf.FieldMask", "protobuf.FieldMask", nil)152 // protobuf.Any153 default:154 if required {155 failf(pos, "import %q not found", file)156 }157 }158 return true159}...

Full Screen

Full Screen

Builtin

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 f, err := parser.ParseFile(fset, "1.go", nil, 0)4 if err != nil {5 fmt.Println("error parsing file")6 }7 ast.Print(fset, f)8 fmt.Println("ast.String():")9 fmt.Println(ast.String(f))10}11import (12func main() {13 f, err := parser.ParseFile(fset, "1.go", nil, 0)14 if err != nil {15 fmt.Println("error parsing file")16 }17 ast.Print(fset, f)18 fmt.Println("ast.String():")19 fmt.Println(ast.String(f))20 fmt.Println("ast.CommentMap():")21 fmt.Println(ast.CommentMap(fset, f, f.Comments))22}

Full Screen

Full Screen

Builtin

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 f, err := parser.ParseFile(fset, "2.go", nil, 0)4 if err != nil {5 fmt.Println(err)6 }7 ast.Print(fset, f)8}9import (10func main() {11 f, err := parser.ParseFile(fset, "3.go", nil, 0)12 if err != nil {13 fmt.Println(err)14 }15 ast.Print(fset, f)16}17import (18func main() {19 f, err := parser.ParseFile(fset, "4.go", nil, 0)20 if err != nil {21 fmt.Println(err)22 }23 ast.Print(fset, f)24}25import (26func main() {27 f, err := parser.ParseFile(fset, "5.go", nil, 0)28 if err != nil {29 fmt.Println(err)30 }31 ast.Print(fset, f)32}33import (34func main() {

Full Screen

Full Screen

Builtin

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 node, err := parser.ParseFile(fset, "2.go", nil, 0)4 if err != nil {5 panic(err)6 }7 ast.Inspect(node, func(n ast.Node) bool {8 switch x := n.(type) {9 fmt.Println(x.Name)10 }11 })12}132.go:6:2: expected 'package', found 'import'142.go:11:6: expected ';', found 'main'152.go:11:10: expected ';', found 'func'162.go:11:14: expected ';', found 'ast'172.go:11:17: expected ';', found 'ast'182.go:11:20: expected ';', found 'ast'192.go:11:23: expected ';', found 'ast'202.go:11:26: expected ';', found 'ast'212.go:11:29: expected ';', found 'ast'222.go:11:32: expected ';', found 'ast'232.go:11:35: expected ';', found 'ast'242.go:11:38: expected ';', found 'ast'252.go:11:41: expected ';', found 'ast'262.go:11:44: expected ';', found 'ast'272.go:11:47: expected ';', found 'ast'282.go:11:50: expected ';', found 'ast'292.go:11:53: expected ';', found 'ast'302.go:11:56: expected ';', found 'ast'312.go:11:59: expected ';', found 'ast'322.go:11:62: expected ';', found 'ast'332.go:11:65: expected ';', found 'ast'342.go:11:68: expected ';', found 'ast'352.go:11:71: expected ';', found 'ast'362.go:11:74: expected ';', found 'ast'372.go:11:77: expected ';', found 'ast'

Full Screen

Full Screen

Builtin

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 node, err := parser.ParseFile(fset, "1.go", nil, parser.ParseComments)4 if err != nil {5 fmt.Println(err)6 }7 ast.Print(fset, node)8}

Full Screen

Full Screen

Builtin

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(basicLit.Value)4}5Recommended Posts: Go | ast.NewIdent() method6Go | ast.NewAssignStmt() method7Go | ast.NewReturnStmt() method8Go | ast.NewFuncDecl() method9Go | ast.NewField() method10Go | ast.NewFieldList() method11Go | ast.NewGenDecl() method12Go | ast.NewImportSpec() method13Go | ast.NewPackage() method14Go | ast.NewValueSpec() method15Go | ast.NewObj() method16Go | ast.NewScope() method17Go | ast.NewBlockStmt() method18Go | ast.NewBranchStmt() method19Go | ast.NewCallExpr() method20Go | ast.NewCaseClause() method21Go | ast.NewChanType() method22Go | ast.NewCommClause() method23Go | ast.NewComment() method24Go | ast.NewCommentGroup() method25Go | ast.NewDeclStmt() method26Go | ast.NewEllipsis() method27Go | ast.NewExprStmt() method28Go | ast.NewFile() method29Go | ast.NewForStmt() method30Go | ast.NewIdent() method31Go | ast.NewIfStmt() method32Go | ast.NewImportSpec() method33Go | ast.NewIncDecStmt() method34Go | ast.NewInterfaceType() method35Go | ast.NewKeyValueExpr() method36Go | ast.NewLabeledStmt() method37Go | ast.NewMapType() method38Go | ast.NewParenExpr() method39Go | ast.NewRangeStmt() method40Go | ast.NewSelectorExpr() method41Go | ast.NewSliceExpr() method42Go | ast.NewStarExpr() method43Go | ast.NewStructType() method44Go | ast.NewSwitchStmt() method45Go | ast.NewTypeAssertExpr() method46Go | ast.NewTypeSpec() method47Go | ast.NewTypeSwitchStmt() method48Go | ast.NewValueSpec()

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful