github.com/gmemcc/yaegi@v0.12.1-0.20221128122509-aa99124c5d16/internal/cmd/genop/genop.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "go/format" 6 "log" 7 "os" 8 "strings" 9 "text/template" 10 ) 11 12 const model = `package interp 13 14 // Code generated by 'go run ../internal/cmd/genop/genop.go'. DO NOT EDIT. 15 16 import ( 17 "go/constant" 18 "go/token" 19 "reflect" 20 "github.com/spf13/cast" 21 ) 22 23 // Arithmetic operators 24 {{range $name, $op := .Arithmetic}} 25 func {{$name}}(n *node) { 26 next := getExec(n.tnext) 27 typ := n.typ.concrete().TypeOf() 28 isInterface := n.typ.TypeOf().Kind() == reflect.Interface 29 dest := genValueOutput(n, typ) 30 c0, c1 := n.child[0], n.child[1] 31 32 switch typ.Kind() { 33 case reflect.Interface, reflect.String: 34 v0 := genValue(c0) 35 v1 := genValue(c1) 36 n.exec = func(f *frame) bltn { 37 val0 := v0(f) 38 val1 := v1(f) 39 var value reflect.Value 40 {{- if $op.Str}} 41 if val0.Kind() == reflect.String || (val0.Kind() == reflect.Interface || val0.Kind() == reflect.Ptr) && val0.Elem().Kind() == reflect.String { 42 value = reflect.ValueOf(rconvToString(val0) + rconvToString(val1)) 43 } else { 44 {{- end}} 45 val0 = rconvNumber(val0) 46 val1 = rconvNumber(val1) 47 typ0 := val0.Type() 48 typ1 := val1.Type() 49 if isNumber(typ0) && isNumber(typ1) { 50 switch { 51 case isUint(typ0): 52 switch { 53 case isUint(typ1): 54 value = reflect.ValueOf(val0.Uint() {{$op.Name}} val1.Uint()) 55 case isInt(typ1): 56 value = reflect.ValueOf(val0.Uint() {{$op.Name}} uint64(val1.Int())) 57 case isFloat(typ1): 58 value = reflect.ValueOf(val0.Uint() {{$op.Name}} uint64(val1.Float())) 59 } 60 case isInt(typ0): 61 switch { 62 case isUint(typ1): 63 value = reflect.ValueOf(val0.Int() {{$op.Name}} int64(val1.Uint())) 64 case isInt(typ1): 65 value = reflect.ValueOf(val0.Int() {{$op.Name}} val1.Int()) 66 case isFloat(typ1): 67 value = reflect.ValueOf(val0.Int() {{$op.Name}} int64(val1.Float())) 68 } 69 {{- if $op.Float}} 70 case isFloat(typ0): 71 switch { 72 case isUint(typ1): 73 value = reflect.ValueOf(val0.Float() {{$op.Name}} float64(val1.Uint())) 74 case isInt(typ1): 75 value = reflect.ValueOf(val0.Float() {{$op.Name}} float64(val1.Int())) 76 case isFloat(typ1): 77 value = reflect.ValueOf(val0.Float() {{$op.Name}} float64(val1.Float())) 78 } 79 {{- else}} 80 case isFloat(typ0): 81 switch { 82 case isUint(typ1): 83 value = reflect.ValueOf(int64(val0.Float()) {{$op.Name}} int64(val1.Uint())) 84 case isInt(typ1): 85 value = reflect.ValueOf(int64(val0.Float()) {{$op.Name}} int64(val1.Int())) 86 case isFloat(typ1): 87 value = reflect.ValueOf(int64(val0.Float()) {{$op.Name}} int64(val1.Float())) 88 } 89 {{- end}} 90 } 91 } else { 92 panic(n.runErrorf("only numbers support {{$op.Name}} operator")) 93 } 94 {{- if $op.Str}} 95 } 96 {{- end}} 97 v, _ := rconv(value, typ) 98 dest(f).Set(v) 99 return next 100 } 101 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 102 switch { 103 case isInterface: 104 v0 := genValueInt(c0) 105 {{- if $op.Shift}} 106 v1 := genValueUint(c1) 107 {{else}} 108 v1 := genValueInt(c1) 109 {{end -}} 110 n.exec = func(f *frame) bltn { 111 _, i := v0(f) 112 _, j := v1(f) 113 dest(f).Set(reflect.ValueOf(i {{$op.Name}} j).Convert(typ)) 114 return next 115 } 116 case c0.rval.IsValid(): 117 i := vInt(c0.rval) 118 {{- if $op.Shift}} 119 v1 := genValueUint(c1) 120 {{else}} 121 v1 := genValueInt(c1) 122 {{end -}} 123 n.exec = func(f *frame) bltn { 124 _, j := v1(f) 125 dest(f).SetInt(i {{$op.Name}} j) 126 return next 127 } 128 case c1.rval.IsValid(): 129 v0 := genValueInt(c0) 130 {{- if $op.Shift}} 131 j := vUint(c1.rval) 132 {{else}} 133 j := vInt(c1.rval) 134 {{end -}} 135 n.exec = func(f *frame) bltn { 136 _, i := v0(f) 137 dest(f).SetInt(i {{$op.Name}} j) 138 return next 139 } 140 default: 141 v0 := genValueInt(c0) 142 {{- if $op.Shift}} 143 v1 := genValueUint(c1) 144 {{else}} 145 v1 := genValueInt(c1) 146 {{end -}} 147 n.exec = func(f *frame) bltn { 148 _, i := v0(f) 149 _, j := v1(f) 150 dest(f).SetInt(i {{$op.Name}} j) 151 return next 152 } 153 } 154 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 155 switch { 156 case isInterface: 157 v0 := genValueUint(c0) 158 v1 := genValueUint(c1) 159 n.exec = func(f *frame) bltn { 160 _, i := v0(f) 161 _, j := v1(f) 162 dest(f).Set(reflect.ValueOf(i {{$op.Name}} j).Convert(typ)) 163 return next 164 } 165 case c0.rval.IsValid(): 166 i := vUint(c0.rval) 167 v1 := genValueUint(c1) 168 n.exec = func(f *frame) bltn { 169 _, j := v1(f) 170 dest(f).SetUint(i {{$op.Name}} j) 171 return next 172 } 173 case c1.rval.IsValid(): 174 j := vUint(c1.rval) 175 v0 := genValueUint(c0) 176 n.exec = func(f *frame) bltn { 177 _, i := v0(f) 178 dest(f).SetUint(i {{$op.Name}} j) 179 return next 180 } 181 default: 182 v0 := genValueUint(c0) 183 v1 := genValueUint(c1) 184 n.exec = func(f *frame) bltn { 185 _, i := v0(f) 186 _, j := v1(f) 187 dest(f).SetUint(i {{$op.Name}} j) 188 return next 189 } 190 } 191 {{- if $op.Float}} 192 case reflect.Float32, reflect.Float64: 193 switch { 194 case isInterface: 195 v0 := genValueFloat(c0) 196 v1 := genValueFloat(c1) 197 n.exec = func(f *frame) bltn { 198 _, i := v0(f) 199 _, j := v1(f) 200 dest(f).Set(reflect.ValueOf(i {{$op.Name}} j).Convert(typ)) 201 return next 202 } 203 case c0.rval.IsValid(): 204 i := vFloat(c0.rval) 205 v1 := genValueFloat(c1) 206 n.exec = func(f *frame) bltn { 207 _, j := v1(f) 208 dest(f).SetFloat(i {{$op.Name}} j) 209 return next 210 } 211 case c1.rval.IsValid(): 212 j := vFloat(c1.rval) 213 v0 := genValueFloat(c0) 214 n.exec = func(f *frame) bltn { 215 _, i := v0(f) 216 dest(f).SetFloat(i {{$op.Name}} j) 217 return next 218 } 219 default: 220 v0 := genValueFloat(c0) 221 v1 := genValueFloat(c1) 222 n.exec = func(f *frame) bltn { 223 _, i := v0(f) 224 _, j := v1(f) 225 dest(f).SetFloat(i {{$op.Name}} j) 226 return next 227 } 228 } 229 case reflect.Complex64, reflect.Complex128: 230 switch { 231 case isInterface: 232 v0 := genComplex(c0) 233 v1 := genComplex(c1) 234 n.exec = func(f *frame) bltn { 235 dest(f).Set(reflect.ValueOf(v0(f) {{$op.Name}} v1(f)).Convert(typ)) 236 return next 237 } 238 case c0.rval.IsValid(): 239 r0 := vComplex(c0.rval) 240 v1 := genComplex(c1) 241 n.exec = func(f *frame) bltn { 242 dest(f).SetComplex(r0 {{$op.Name}} v1(f)) 243 return next 244 } 245 case c1.rval.IsValid(): 246 r1 := vComplex(c1.rval) 247 v0 := genComplex(c0) 248 n.exec = func(f *frame) bltn { 249 dest(f).SetComplex(v0(f) {{$op.Name}} r1) 250 return next 251 } 252 default: 253 v0 := genComplex(c0) 254 v1 := genComplex(c1) 255 n.exec = func(f *frame) bltn { 256 dest(f).SetComplex(v0(f) {{$op.Name}} v1(f)) 257 return next 258 } 259 } 260 {{- end}} 261 } 262 } 263 264 func {{$name}}Const(n *node) { 265 v0, v1 := n.child[0].rval, n.child[1].rval 266 {{- if $op.Shift}} 267 isConst := (v0.IsValid() && isConstantValue(v0.Type())) 268 {{- else}} 269 isConst := (v0.IsValid() && isConstantValue(v0.Type())) && (v1.IsValid() && isConstantValue(v1.Type())) 270 {{- end}} 271 t := n.typ.rtype 272 if isConst { 273 t = constVal 274 } 275 n.rval = reflect.New(t).Elem() 276 switch { 277 case isConst: 278 {{- if $op.Shift}} 279 v := constant.Shift(vConstantValue(v0), token.{{tokenFromName $name}}, uint(vUint(v1))) 280 n.rval.Set(reflect.ValueOf(v)) 281 {{- else if (eq $op.Name "/")}} 282 var operator token.Token 283 // When the result of the operation is expected to be an int (because both 284 // operands are ints), we want to force the type of the whole expression to be an 285 // int (and not a float), which is achieved by using the QUO_ASSIGN operator. 286 if n.typ.untyped && isInt(n.typ.rtype) { 287 operator = token.QUO_ASSIGN 288 } else { 289 operator = token.QUO 290 } 291 cv0 := rconvConstInt(vConstantValue(v0)) 292 cv1 := rconvConstInt(vConstantValue(v1)) 293 v := constant.BinaryOp(cv0, operator, cv1) 294 n.rval.Set(reflect.ValueOf(v)) 295 {{- else}} 296 {{- if $op.Int}} 297 cv0 := rconvConstInt(vConstantValue(v0)) 298 cv1 := rconvConstInt(vConstantValue(v1)) 299 v := constant.BinaryOp(constant.ToInt(cv0), token.{{tokenFromName $name}}, constant.ToInt(cv1)) 300 {{- else if $op.Str}} 301 cv0 := vConstantValue(v0) 302 cv1 := vConstantValue(v1) 303 cv1 = rconvConst(cv1, cv0.Kind()) 304 v := constant.BinaryOp(cv0, token.{{tokenFromName $name}}, cv1) 305 {{- else}} 306 cv0 := rconvConstNumber(vConstantValue(v0)) 307 cv1 := rconvConstNumber(vConstantValue(v1)) 308 v := constant.BinaryOp(cv0, token.{{tokenFromName $name}}, cv1) 309 {{- end}} 310 n.rval.Set(reflect.ValueOf(v)) 311 {{- end}} 312 {{- if $op.Str}} 313 case isString(t): 314 n.rval.SetString(vString(v0) {{$op.Name}} vString(v1)) 315 {{- end}} 316 {{- if $op.Float}} 317 case isComplex(t): 318 n.rval.SetComplex(vComplex(v0) {{$op.Name}} vComplex(v1)) 319 case isFloat(t): 320 n.rval.SetFloat(vFloat(v0) {{$op.Name}} vFloat(v1)) 321 {{- end}} 322 case isUint(t): 323 n.rval.SetUint(vUint(v0) {{$op.Name}} vUint(v1)) 324 case isInt(t): 325 {{- if $op.Shift}} 326 n.rval.SetInt(vInt(v0) {{$op.Name}} vUint(v1)) 327 {{- else}} 328 n.rval.SetInt(vInt(v0) {{$op.Name}} vInt(v1)) 329 {{- end}} 330 } 331 } 332 {{end}} 333 // Assign operators 334 {{range $name, $op := .Arithmetic}} 335 func {{$name}}Assign(n *node) { 336 next := getExec(n.tnext) 337 typ := n.typ.TypeOf() 338 c0, c1 := n.child[0], n.child[1] 339 setMap := isMapEntry(c0) 340 var mapValue, indexValue func(*frame) reflect.Value 341 342 if setMap { 343 mapValue = genValue(c0.child[0]) 344 indexValue = genValue(c0.child[1]) 345 } 346 347 if c1.rval.IsValid() { 348 switch typ.Kind() { 349 {{- if $op.Str}} 350 case reflect.String: 351 v0 := genValueString(c0) 352 v1 := vString(c1.rval) 353 n.exec = func(f *frame) bltn { 354 v, s := v0(f) 355 v.SetString(s {{$op.Name}} v1) 356 if setMap { 357 mapValue(f).SetMapIndex(indexValue(f), v) 358 } 359 return next 360 } 361 {{- end}} 362 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 363 v0 := genValueInt(c0) 364 {{- if $op.Shift}} 365 j := vUint(c1.rval) 366 {{else}} 367 j := vInt(c1.rval) 368 {{end -}} 369 n.exec = func(f *frame) bltn { 370 v, i := v0(f) 371 v.SetInt(i {{$op.Name}} j) 372 if setMap { 373 mapValue(f).SetMapIndex(indexValue(f), v) 374 } 375 return next 376 } 377 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 378 v0 := genValueUint(c0) 379 j := vUint(c1.rval) 380 n.exec = func(f *frame) bltn { 381 v, i := v0(f) 382 v.SetUint(i {{$op.Name}} j) 383 if setMap { 384 mapValue(f).SetMapIndex(indexValue(f), v) 385 } 386 return next 387 } 388 {{- if $op.Float}} 389 case reflect.Float32, reflect.Float64: 390 v0 := genValueFloat(c0) 391 j := vFloat(c1.rval) 392 n.exec = func(f *frame) bltn { 393 v, i := v0(f) 394 v.SetFloat(i {{$op.Name}} j) 395 if setMap { 396 mapValue(f).SetMapIndex(indexValue(f), v) 397 } 398 return next 399 } 400 case reflect.Complex64, reflect.Complex128: 401 v0 := genValue(c0) 402 v1 := vComplex(c1.rval) 403 n.exec = func(f *frame) bltn { 404 v := v0(f) 405 v.SetComplex(v.Complex() {{$op.Name}} v1) 406 if setMap { 407 mapValue(f).SetMapIndex(indexValue(f), v) 408 } 409 return next 410 } 411 {{- end}} 412 } 413 } else { 414 switch typ.Kind() { 415 {{- if $op.Str}} 416 case reflect.String: 417 v0 := genValueString(c0) 418 v1 := genValue(c1) 419 n.exec = func(f *frame) bltn { 420 v, s := v0(f) 421 v.SetString(s {{$op.Name}} v1(f).String()) 422 if setMap { 423 mapValue(f).SetMapIndex(indexValue(f), v) 424 } 425 return next 426 } 427 {{- end}} 428 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 429 v0 := genValueInt(c0) 430 {{- if $op.Shift}} 431 v1 := genValueUint(c1) 432 {{else}} 433 v1 := genValueInt(c1) 434 {{end -}} 435 n.exec = func(f *frame) bltn { 436 v, i := v0(f) 437 _, j := v1(f) 438 v.SetInt(i {{$op.Name}} j) 439 if setMap { 440 mapValue(f).SetMapIndex(indexValue(f), v) 441 } 442 return next 443 } 444 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 445 v0 := genValueUint(c0) 446 v1 := genValueUint(c1) 447 n.exec = func(f *frame) bltn { 448 v, i := v0(f) 449 _, j := v1(f) 450 v.SetUint(i {{$op.Name}} j) 451 if setMap { 452 mapValue(f).SetMapIndex(indexValue(f), v) 453 } 454 return next 455 } 456 {{- if $op.Float}} 457 case reflect.Float32, reflect.Float64: 458 v0 := genValueFloat(c0) 459 v1 := genValueFloat(c1) 460 n.exec = func(f *frame) bltn { 461 v, i := v0(f) 462 _, j := v1(f) 463 v.SetFloat(i {{$op.Name}} j) 464 if setMap { 465 mapValue(f).SetMapIndex(indexValue(f), v) 466 } 467 return next 468 } 469 case reflect.Complex64, reflect.Complex128: 470 v0 := genValue(c0) 471 v1 := genValue(c1) 472 n.exec = func(f *frame) bltn { 473 v := v0(f) 474 v.SetComplex(v.Complex() {{$op.Name}} v1(f).Complex()) 475 if setMap { 476 mapValue(f).SetMapIndex(indexValue(f), v) 477 } 478 return next 479 } 480 {{- end}} 481 } 482 } 483 } 484 {{end}} 485 {{range $name, $op := .IncDec}} 486 func {{$name}}(n *node) { 487 next := getExec(n.tnext) 488 typ := n.typ.TypeOf() 489 c0 := n.child[0] 490 setMap := isMapEntry(c0) 491 var mapValue, indexValue func(*frame) reflect.Value 492 493 if setMap { 494 mapValue = genValue(c0.child[0]) 495 indexValue = genValue(c0.child[1]) 496 } 497 498 switch typ.Kind() { 499 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 500 v0 := genValueInt(c0) 501 n.exec = func(f *frame) bltn { 502 v, i := v0(f) 503 v.SetInt(i {{$op.Name}} 1) 504 if setMap { 505 mapValue(f).SetMapIndex(indexValue(f), v) 506 } 507 return next 508 } 509 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 510 v0 := genValueUint(c0) 511 n.exec = func(f *frame) bltn { 512 v, i := v0(f) 513 v.SetUint(i {{$op.Name}} 1) 514 if setMap { 515 mapValue(f).SetMapIndex(indexValue(f), v) 516 } 517 return next 518 } 519 case reflect.Float32, reflect.Float64: 520 v0 := genValueFloat(c0) 521 n.exec = func(f *frame) bltn { 522 v, i := v0(f) 523 v.SetFloat(i {{$op.Name}} 1) 524 if setMap { 525 mapValue(f).SetMapIndex(indexValue(f), v) 526 } 527 return next 528 } 529 case reflect.Complex64, reflect.Complex128: 530 v0 := genValue(c0) 531 n.exec = func(f *frame) bltn { 532 v := v0(f) 533 v.SetComplex(v.Complex() {{$op.Name}} 1) 534 if setMap { 535 mapValue(f).SetMapIndex(indexValue(f), v) 536 } 537 return next 538 } 539 } 540 } 541 {{end}} 542 {{range $name, $op := .Unary}} 543 func {{$name}}Const(n *node) { 544 v0 := n.child[0].rval 545 isConst := v0.IsValid() && isConstantValue(v0.Type()) 546 t := n.typ.rtype 547 if isConst { 548 t = constVal 549 } 550 n.rval = reflect.New(t).Elem() 551 552 {{- if $op.Bool}} 553 if isConst { 554 v := constant.UnaryOp(token.{{tokenFromName $name}}, rconvConstBool(vConstantValue(v0)), 0) 555 n.rval.Set(reflect.ValueOf(v)) 556 } else { 557 n.rval.SetBool({{$op.Name}} v0.Bool()) 558 } 559 {{- else}} 560 switch { 561 case isConst: 562 v := constant.UnaryOp(token.{{tokenFromName $name}}, vConstantValue(v0), 0) 563 n.rval.Set(reflect.ValueOf(v)) 564 case isUint(t): 565 n.rval.SetUint({{$op.Name}} v0.Uint()) 566 case isInt(t): 567 n.rval.SetInt({{$op.Name}} v0.Int()) 568 {{- if $op.Float}} 569 case isFloat(t): 570 n.rval.SetFloat({{$op.Name}} v0.Float()) 571 case isComplex(t): 572 n.rval.SetComplex({{$op.Name}} v0.Complex()) 573 {{- end}} 574 } 575 {{- end}} 576 } 577 {{end}} 578 {{range $name, $op := .Comparison}} 579 func {{$name}}(n *node) { 580 tnext := getExec(n.tnext) 581 dest := genValueOutput(n, reflect.TypeOf(true)) 582 typ := n.typ.concrete().TypeOf() 583 isInterface := n.typ.TypeOf().Kind() == reflect.Interface 584 c0, c1 := n.child[0], n.child[1] 585 t0, t1 := c0.typ.TypeOf(), c1.typ.TypeOf() 586 587 {{- if or (eq $op.Name "==") (eq $op.Name "!=") }} 588 589 if c0.typ.cat == aliasT || c1.typ.cat == aliasT { 590 switch { 591 case isInterface: 592 v0 := genValue(c0) 593 v1 := genValue(c1) 594 dest := genValue(n) 595 n.exec = func(f *frame) bltn { 596 i0 := v0(f).Interface() 597 i1 := v1(f).Interface() 598 dest(f).Set(reflect.ValueOf(i0 {{$op.Name}} i1).Convert(typ)) 599 return tnext 600 } 601 case c0.rval.IsValid(): 602 i0 := c0.rval.Interface() 603 v1 := genValue(c1) 604 if n.fnext != nil { 605 fnext := getExec(n.fnext) 606 n.exec = func(f *frame) bltn { 607 i1 := v1(f).Interface() 608 if i0 {{$op.Name}} i1 { 609 dest(f).SetBool(true) 610 return tnext 611 } 612 dest(f).SetBool(false) 613 return fnext 614 } 615 } else { 616 dest := genValue(n) 617 n.exec = func(f *frame) bltn { 618 i1 := v1(f).Interface() 619 dest(f).SetBool(i0 {{$op.Name}} i1) 620 return tnext 621 } 622 } 623 case c1.rval.IsValid(): 624 i1 := c1.rval.Interface() 625 v0 := genValue(c0) 626 if n.fnext != nil { 627 fnext := getExec(n.fnext) 628 n.exec = func(f *frame) bltn { 629 i0 := v0(f).Interface() 630 if i0 {{$op.Name}} i1 { 631 dest(f).SetBool(true) 632 return tnext 633 } 634 dest(f).SetBool(false) 635 return fnext 636 } 637 } else { 638 dest := genValue(n) 639 n.exec = func(f *frame) bltn { 640 i0 := v0(f).Interface() 641 dest(f).SetBool(i0 {{$op.Name}} i1) 642 return tnext 643 } 644 } 645 default: 646 v0 := genValue(c0) 647 v1 := genValue(c1) 648 if n.fnext != nil { 649 fnext := getExec(n.fnext) 650 n.exec = func(f *frame) bltn { 651 i0 := v0(f).Interface() 652 i1 := v1(f).Interface() 653 if i0 {{$op.Name}} i1 { 654 dest(f).SetBool(true) 655 return tnext 656 } 657 dest(f).SetBool(false) 658 return fnext 659 } 660 } else { 661 dest := genValue(n) 662 n.exec = func(f *frame) bltn { 663 i0 := v0(f).Interface() 664 i1 := v1(f).Interface() 665 dest(f).SetBool(i0 {{$op.Name}} i1) 666 return tnext 667 } 668 } 669 } 670 return 671 } 672 673 // Do not attempt to optimize '==' or '!=' if an operand is an interface. 674 // This will preserve proper dynamic type checking at runtime. For static types, 675 // type checks are already performed, so bypass them if possible. 676 if t0.Kind() == reflect.Interface || t1.Kind() == reflect.Interface { 677 v0 := genValue(c0) 678 v1 := genValue(c1) 679 if n.fnext != nil { 680 fnext := getExec(n.fnext) 681 n.exec = func(f *frame) bltn { 682 val0 := v0(f) 683 val1 := v1(f) 684 var err error 685 var typ0 reflect.Type 686 if val0.Kind() == reflect.Interface && val0.Elem().IsValid() { 687 typ0 = val0.Elem().Type() 688 } else { 689 typ0 = val0.Type() 690 } 691 val1, err = rconv(val1, typ0) 692 if err != nil { 693 panic(err) 694 } 695 i0 := val0.Interface() 696 i1 := val1.Interface() 697 if i0 {{$op.Name}} i1 { 698 dest(f).SetBool(true) 699 return tnext 700 } 701 dest(f).SetBool(false) 702 return fnext 703 } 704 } else { 705 dest := genValue(n) 706 n.exec = func(f *frame) bltn { 707 i0 := v0(f).Interface() 708 i1 := v1(f).Interface() 709 x := i0 {{$op.Name}} i1 710 dest(f).Set(reflect.ValueOf(x)) 711 return tnext 712 } 713 } 714 return 715 } 716 {{- end}} 717 718 switch { 719 case isString(t0) || isString(t1): 720 switch { 721 case isInterface: 722 v0 := genValueString(c0) 723 v1 := genValueString(c1) 724 n.exec = func(f *frame) bltn { 725 _, s0 := v0(f) 726 _, s1 := v1(f) 727 dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ)) 728 return tnext 729 } 730 case c0.rval.IsValid(): 731 s0 := vString(c0.rval) 732 {{- if eq $op.Name "=="}} 733 c0Bool := c0.rval.Kind() == reflect.Bool 734 {{- end}} 735 v1 := genValueString(c1) 736 if n.fnext != nil { 737 fnext := getExec(n.fnext) 738 n.exec = func(f *frame) bltn { 739 _, s1 := v1(f) 740 if s0 {{$op.Name}} s1 {{if eq $op.Name "=="}}|| c0Bool && cast.ToBool(s1) {{end}}{ 741 dest(f).SetBool(true) 742 return tnext 743 } 744 dest(f).SetBool(false) 745 return fnext 746 } 747 } else { 748 n.exec = func(f *frame) bltn { 749 _, s1 := v1(f) 750 dest(f).SetBool(s0 {{$op.Name}} s1) 751 return tnext 752 } 753 } 754 case c1.rval.IsValid(): 755 s1 := vString(c1.rval) 756 v0 := genValueString(c0) 757 if n.fnext != nil { 758 fnext := getExec(n.fnext) 759 n.exec = func(f *frame) bltn { 760 _, s0 := v0(f) 761 if s0 {{$op.Name}} s1 { 762 dest(f).SetBool(true) 763 return tnext 764 } 765 dest(f).SetBool(false) 766 return fnext 767 } 768 } else { 769 n.exec = func(f *frame) bltn { 770 _, s0 := v0(f) 771 dest(f).SetBool(s0 {{$op.Name}} s1) 772 return tnext 773 } 774 } 775 default: 776 v0 := genValueString(c0) 777 v1 := genValueString(c1) 778 if n.fnext != nil { 779 fnext := getExec(n.fnext) 780 n.exec = func(f *frame) bltn { 781 _, s0 := v0(f) 782 _, s1 := v1(f) 783 if s0 {{$op.Name}} s1 { 784 dest(f).SetBool(true) 785 return tnext 786 } 787 dest(f).SetBool(false) 788 return fnext 789 } 790 } else { 791 n.exec = func(f *frame) bltn { 792 _, s0 := v0(f) 793 _, s1 := v1(f) 794 dest(f).SetBool(s0 {{$op.Name}} s1) 795 return tnext 796 } 797 } 798 } 799 case isFloat(t0) || isFloat(t1): 800 switch { 801 case isInterface: 802 v0 := genValueFloat(c0) 803 v1 := genValueFloat(c1) 804 n.exec = func(f *frame) bltn { 805 _, s0 := v0(f) 806 _, s1 := v1(f) 807 dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ)) 808 return tnext 809 } 810 case c0.rval.IsValid(): 811 s0 := vFloat(c0.rval) 812 v1 := genValueFloat(c1) 813 if n.fnext != nil { 814 fnext := getExec(n.fnext) 815 n.exec = func(f *frame) bltn { 816 _, s1 := v1(f) 817 if s0 {{$op.Name}} s1 { 818 dest(f).SetBool(true) 819 return tnext 820 } 821 dest(f).SetBool(false) 822 return fnext 823 } 824 } else { 825 n.exec = func(f *frame) bltn { 826 _, s1 := v1(f) 827 dest(f).SetBool(s0 {{$op.Name}} s1) 828 return tnext 829 } 830 } 831 case c1.rval.IsValid(): 832 s1 := vFloat(c1.rval) 833 v0 := genValueFloat(c0) 834 if n.fnext != nil { 835 fnext := getExec(n.fnext) 836 n.exec = func(f *frame) bltn { 837 _, s0 := v0(f) 838 if s0 {{$op.Name}} s1 { 839 dest(f).SetBool(true) 840 return tnext 841 } 842 dest(f).SetBool(false) 843 return fnext 844 } 845 } else { 846 dest := genValue(n) 847 n.exec = func(f *frame) bltn { 848 _, s0 := v0(f) 849 dest(f).SetBool(s0 {{$op.Name}} s1) 850 return tnext 851 } 852 } 853 default: 854 v0 := genValueFloat(c0) 855 v1 := genValueFloat(c1) 856 if n.fnext != nil { 857 fnext := getExec(n.fnext) 858 n.exec = func(f *frame) bltn { 859 _, s0 := v0(f) 860 _, s1 := v1(f) 861 if s0 {{$op.Name}} s1 { 862 dest(f).SetBool(true) 863 return tnext 864 } 865 dest(f).SetBool(false) 866 return fnext 867 } 868 } else { 869 dest := genValue(n) 870 n.exec = func(f *frame) bltn { 871 _, s0 := v0(f) 872 _, s1 := v1(f) 873 dest(f).SetBool(s0 {{$op.Name}} s1) 874 return tnext 875 } 876 } 877 } 878 case isUint(t0) || isUint(t1): 879 switch { 880 case isInterface: 881 v0 := genValueUint(c0) 882 v1 := genValueUint(c1) 883 n.exec = func(f *frame) bltn { 884 _, s0 := v0(f) 885 _, s1 := v1(f) 886 dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ)) 887 return tnext 888 } 889 case c0.rval.IsValid(): 890 s0 := vUint(c0.rval) 891 v1 := genValueUint(c1) 892 if n.fnext != nil { 893 fnext := getExec(n.fnext) 894 n.exec = func(f *frame) bltn { 895 _, s1 := v1(f) 896 if s0 {{$op.Name}} s1 { 897 dest(f).SetBool(true) 898 return tnext 899 } 900 dest(f).SetBool(false) 901 return fnext 902 } 903 } else { 904 dest := genValue(n) 905 n.exec = func(f *frame) bltn { 906 _, s1 := v1(f) 907 dest(f).SetBool(s0 {{$op.Name}} s1) 908 return tnext 909 } 910 } 911 case c1.rval.IsValid(): 912 s1 := vUint(c1.rval) 913 v0 := genValueUint(c0) 914 if n.fnext != nil { 915 fnext := getExec(n.fnext) 916 n.exec = func(f *frame) bltn { 917 _, s0 := v0(f) 918 if s0 {{$op.Name}} s1 { 919 dest(f).SetBool(true) 920 return tnext 921 } 922 dest(f).SetBool(false) 923 return fnext 924 } 925 } else { 926 dest := genValue(n) 927 n.exec = func(f *frame) bltn { 928 _, s0 := v0(f) 929 dest(f).SetBool(s0 {{$op.Name}} s1) 930 return tnext 931 } 932 } 933 default: 934 v0 := genValueUint(c0) 935 v1 := genValueUint(c1) 936 if n.fnext != nil { 937 fnext := getExec(n.fnext) 938 n.exec = func(f *frame) bltn { 939 _, s0 := v0(f) 940 _, s1 := v1(f) 941 if s0 {{$op.Name}} s1 { 942 dest(f).SetBool(true) 943 return tnext 944 } 945 dest(f).SetBool(false) 946 return fnext 947 } 948 } else { 949 dest := genValue(n) 950 n.exec = func(f *frame) bltn { 951 _, s0 := v0(f) 952 _, s1 := v1(f) 953 dest(f).SetBool(s0 {{$op.Name}} s1) 954 return tnext 955 } 956 } 957 } 958 case isInt(t0) || isInt(t1): 959 switch { 960 case isInterface: 961 v0 := genValueInt(c0) 962 v1 := genValueInt(c1) 963 n.exec = func(f *frame) bltn { 964 _, s0 := v0(f) 965 _, s1 := v1(f) 966 dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ)) 967 return tnext 968 } 969 case c0.rval.IsValid(): 970 s0 := vInt(c0.rval) 971 v1 := genValueInt(c1) 972 if n.fnext != nil { 973 fnext := getExec(n.fnext) 974 n.exec = func(f *frame) bltn { 975 _, s1 := v1(f) 976 if s0 {{$op.Name}} s1 { 977 dest(f).SetBool(true) 978 return tnext 979 } 980 dest(f).SetBool(false) 981 return fnext 982 } 983 } else { 984 dest := genValue(n) 985 n.exec = func(f *frame) bltn { 986 _, s1 := v1(f) 987 dest(f).SetBool(s0 {{$op.Name}} s1) 988 return tnext 989 } 990 } 991 case c1.rval.IsValid(): 992 s1 := vInt(c1.rval) 993 v0 := genValueInt(c0) 994 if n.fnext != nil { 995 fnext := getExec(n.fnext) 996 n.exec = func(f *frame) bltn { 997 _, s0 := v0(f) 998 if s0 {{$op.Name}} s1 { 999 dest(f).SetBool(true) 1000 return tnext 1001 } 1002 dest(f).SetBool(false) 1003 return fnext 1004 } 1005 } else { 1006 dest := genValue(n) 1007 n.exec = func(f *frame) bltn { 1008 _, s0 := v0(f) 1009 dest(f).SetBool(s0 {{$op.Name}} s1) 1010 return tnext 1011 } 1012 } 1013 default: 1014 v0 := genValueInt(c0) 1015 v1 := genValueInt(c1) 1016 if n.fnext != nil { 1017 fnext := getExec(n.fnext) 1018 n.exec = func(f *frame) bltn { 1019 _, s0 := v0(f) 1020 _, s1 := v1(f) 1021 if s0 {{$op.Name}} s1 { 1022 dest(f).SetBool(true) 1023 return tnext 1024 } 1025 dest(f).SetBool(false) 1026 return fnext 1027 } 1028 } else { 1029 dest := genValue(n) 1030 n.exec = func(f *frame) bltn { 1031 _, s0 := v0(f) 1032 _, s1 := v1(f) 1033 dest(f).SetBool(s0 {{$op.Name}} s1) 1034 return tnext 1035 } 1036 } 1037 } 1038 {{- if $op.Complex}} 1039 case isComplex(t0) || isComplex(t1): 1040 switch { 1041 case isInterface: 1042 v0 := genComplex(c0) 1043 v1 := genComplex(c1) 1044 n.exec = func(f *frame) bltn { 1045 s0 := v0(f) 1046 s1 := v1(f) 1047 dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ)) 1048 return tnext 1049 } 1050 case c0.rval.IsValid(): 1051 s0 := vComplex(c0.rval) 1052 v1 := genComplex(c1) 1053 if n.fnext != nil { 1054 fnext := getExec(n.fnext) 1055 n.exec = func(f *frame) bltn { 1056 s1 := v1(f) 1057 if s0 {{$op.Name}} s1 { 1058 dest(f).SetBool(true) 1059 return tnext 1060 } 1061 dest(f).SetBool(false) 1062 return fnext 1063 } 1064 } else { 1065 n.exec = func(f *frame) bltn { 1066 s1 := v1(f) 1067 dest(f).SetBool(s0 {{$op.Name}} s1) 1068 return tnext 1069 } 1070 } 1071 case c1.rval.IsValid(): 1072 s1 := vComplex(c1.rval) 1073 v0 := genComplex(c0) 1074 if n.fnext != nil { 1075 fnext := getExec(n.fnext) 1076 n.exec = func(f *frame) bltn { 1077 s0 := v0(f) 1078 if s0 {{$op.Name}} s1 { 1079 dest(f).SetBool(true) 1080 return tnext 1081 } 1082 dest(f).SetBool(false) 1083 return fnext 1084 } 1085 } else { 1086 dest := genValue(n) 1087 n.exec = func(f *frame) bltn { 1088 s0 := v0(f) 1089 dest(f).SetBool(s0 {{$op.Name}} s1) 1090 return tnext 1091 } 1092 } 1093 default: 1094 v0 := genComplex(c0) 1095 v1 := genComplex(c1) 1096 if n.fnext != nil { 1097 fnext := getExec(n.fnext) 1098 n.exec = func(f *frame) bltn { 1099 s0 := v0(f) 1100 s1 := v1(f) 1101 if s0 {{$op.Name}} s1 { 1102 dest(f).SetBool(true) 1103 return tnext 1104 } 1105 dest(f).SetBool(false) 1106 return fnext 1107 } 1108 } else { 1109 n.exec = func(f *frame) bltn { 1110 s0 := v0(f) 1111 s1 := v1(f) 1112 dest(f).SetBool(s0 {{$op.Name}} s1) 1113 return tnext 1114 } 1115 } 1116 } 1117 default: 1118 switch { 1119 case isInterface: 1120 v0 := genValue(c0) 1121 v1 := genValue(c1) 1122 n.exec = func(f *frame) bltn { 1123 i0 := v0(f).Interface() 1124 i1 := v1(f).Interface() 1125 dest(f).Set(reflect.ValueOf(i0 {{$op.Name}} i1).Convert(typ)) 1126 return tnext 1127 } 1128 case c0.rval.IsValid(): 1129 i0 := c0.rval.Interface() 1130 v1 := genValue(c1) 1131 if n.fnext != nil { 1132 fnext := getExec(n.fnext) 1133 n.exec = func(f *frame) bltn { 1134 i1 := v1(f).Interface() 1135 if i0 {{$op.Name}} i1 { 1136 dest(f).SetBool(true) 1137 return tnext 1138 } 1139 dest(f).SetBool(false) 1140 return fnext 1141 } 1142 } else { 1143 dest := genValue(n) 1144 n.exec = func(f *frame) bltn { 1145 i1 := v1(f).Interface() 1146 dest(f).SetBool(i0 {{$op.Name}} i1) 1147 return tnext 1148 } 1149 } 1150 case c1.rval.IsValid(): 1151 i1 := c1.rval.Interface() 1152 v0 := genValue(c0) 1153 if n.fnext != nil { 1154 fnext := getExec(n.fnext) 1155 n.exec = func(f *frame) bltn { 1156 i0 := v0(f).Interface() 1157 if i0 {{$op.Name}} i1 { 1158 dest(f).SetBool(true) 1159 return tnext 1160 } 1161 dest(f).SetBool(false) 1162 return fnext 1163 } 1164 } else { 1165 dest := genValue(n) 1166 n.exec = func(f *frame) bltn { 1167 i0 := v0(f).Interface() 1168 dest(f).SetBool(i0 {{$op.Name}} i1) 1169 return tnext 1170 } 1171 } 1172 default: 1173 v0 := genValue(c0) 1174 v1 := genValue(c1) 1175 if n.fnext != nil { 1176 fnext := getExec(n.fnext) 1177 n.exec = func(f *frame) bltn { 1178 i0 := v0(f).Interface() 1179 i1 := v1(f).Interface() 1180 if i0 {{$op.Name}} i1 { 1181 dest(f).SetBool(true) 1182 return tnext 1183 } 1184 dest(f).SetBool(false) 1185 return fnext 1186 } 1187 } else { 1188 dest := genValue(n) 1189 n.exec = func(f *frame) bltn { 1190 i0 := v0(f).Interface() 1191 i1 := v1(f).Interface() 1192 dest(f).SetBool(i0 {{$op.Name}} i1) 1193 return tnext 1194 } 1195 } 1196 } 1197 {{- else}} 1198 default: 1199 v0 := genValue(c0) 1200 v1 := genValue(c1) 1201 if n.fnext != nil { 1202 fnext := getExec(n.fnext) 1203 n.exec = func(f *frame) bltn { 1204 val0 := v0(f) 1205 val1 := v1(f) 1206 v, e := rcompare(val0, val1, "{{$op.Name}}") 1207 if e != nil { 1208 panic(n.runErrorf(e.Error())) 1209 } 1210 if v { 1211 dest(f).SetBool(true) 1212 return tnext 1213 } 1214 dest(f).SetBool(false) 1215 return fnext 1216 } 1217 } else { 1218 n.exec = func(f *frame) bltn { 1219 val0 := v0(f) 1220 val1 := v1(f) 1221 v, e := rcompare(val0, val1, "{{$op.Name}}") 1222 if e != nil { 1223 panic(n.runErrorf(e.Error())) 1224 } 1225 dest(f).SetBool(v) 1226 return tnext 1227 } 1228 } 1229 {{- end}} 1230 } 1231 } 1232 {{end}} 1233 ` 1234 1235 // Op define operator name and properties. 1236 type Op struct { 1237 Name string // +, -, ... 1238 Str bool // true if operator applies to string 1239 Float bool // true if operator applies to float 1240 Complex bool // true if operator applies to complex 1241 Shift bool // true if operator is a shift operation 1242 Bool bool // true if operator applies to bool 1243 Int bool // true if operator applies to int only 1244 } 1245 1246 func main() { 1247 base := template.New("genop") 1248 base.Funcs(template.FuncMap{ 1249 "tokenFromName": func(name string) string { 1250 switch name { 1251 case "andNot": 1252 return "AND_NOT" 1253 case "neg": 1254 return "SUB" 1255 case "pos": 1256 return "ADD" 1257 case "bitNot": 1258 return "XOR" 1259 default: 1260 return strings.ToUpper(name) 1261 } 1262 }, 1263 }) 1264 parse, err := base.Parse(model) 1265 if err != nil { 1266 log.Fatal(err) 1267 } 1268 1269 b := &bytes.Buffer{} 1270 data := map[string]interface{}{ 1271 "Arithmetic": map[string]Op{ 1272 "add": {"+", true, true, true, false, false, false}, 1273 "sub": {"-", false, true, true, false, false, false}, 1274 "mul": {"*", false, true, true, false, false, false}, 1275 "quo": {"/", false, true, true, false, false, false}, 1276 "rem": {"%", false, false, false, false, false, true}, 1277 "shl": {"<<", false, false, false, true, false, true}, 1278 "shr": {">>", false, false, false, true, false, true}, 1279 "and": {"&", false, false, false, false, false, true}, 1280 "or": {"|", false, false, false, false, false, true}, 1281 "xor": {"^", false, false, false, false, false, true}, 1282 "andNot": {"&^", false, false, false, false, false, true}, 1283 }, 1284 "IncDec": map[string]Op{ 1285 "inc": {Name: "+"}, 1286 "dec": {Name: "-"}, 1287 }, 1288 "Comparison": map[string]Op{ 1289 "equal": {Name: "==", Complex: true}, 1290 "greater": {Name: ">", Complex: false}, 1291 "greaterEqual": {Name: ">=", Complex: false}, 1292 "lower": {Name: "<", Complex: false}, 1293 "lowerEqual": {Name: "<=", Complex: false}, 1294 "notEqual": {Name: "!=", Complex: true}, 1295 }, 1296 "Unary": map[string]Op{ 1297 "not": {Name: "!", Float: false, Bool: true}, 1298 "neg": {Name: "-", Float: true, Bool: false}, 1299 "pos": {Name: "+", Float: true, Bool: false}, 1300 "bitNot": {Name: "^", Float: false, Bool: false, Int: true}, 1301 }, 1302 } 1303 if err = parse.Execute(b, data); err != nil { 1304 log.Fatal(err) 1305 } 1306 1307 // gofmt 1308 source, err := format.Source(b.Bytes()) 1309 if err != nil { 1310 log.Fatal(err) 1311 } 1312 1313 if err = os.WriteFile("op.go", source, 0o666); err != nil { 1314 log.Fatal(err) 1315 } 1316 }