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