math.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. "math/rand"
  6. )
  7. func opAdd(val1, val2 value) *_number {
  8. return &_number{num: toNumber(val1) + toNumber(val2)}
  9. }
  10. func opSub(val1, val2 value) *_number {
  11. return &_number{num: toNumber(val1) - toNumber(val2)}
  12. }
  13. func opMul(val1, val2 value) *_number {
  14. return &_number{num: toNumber(val1) * toNumber(val2)}
  15. }
  16. func opDiv(val1, val2 value) *_number {
  17. if num1, num2 := toNumber(val1), toNumber(val2); num2 != 0 {
  18. return &_number{num: num1 / num2}
  19. }
  20. panic(fmt.Errorf("div: %s (%s / %s)", errDivisionByZero, val1.String(), val2.String()))
  21. }
  22. func opMod(val1, val2 value) *_number {
  23. if num1, num2 := toNumber(val1), toNumber(val2); num2 != 0 {
  24. return &_number{num: math.Mod(num1, num2)}
  25. }
  26. panic(fmt.Errorf("mod: %s (%s %% %s)", errDivisionByZero, val1.String(), val2.String()))
  27. }
  28. func opEq(val1, val2 value) *_bool {
  29. if isNumber(val1) && isNumber(val2) {
  30. return &_bool{b: toNumber(val1) == toNumber(val2)}
  31. }
  32. if isBool(val1) && isBool(val2) {
  33. return &_bool{b: toBool(val1) == toBool(val2)}
  34. }
  35. if isWord(val1) && isWord(val2) {
  36. return &_bool{b: escapeWord(toWord(val1)) == escapeWord(toWord(val2))}
  37. }
  38. panic(fmt.Errorf("eq: %s (%s == %s)", errIllegalOperandType, val1.String(), val2.String()))
  39. }
  40. func opGt(val1, val2 value) *_bool {
  41. if isNumber(val1) && isNumber(val2) {
  42. return &_bool{b: toNumber(val1) > toNumber(val2)}
  43. }
  44. if isBool(val1) && isBool(val2) {
  45. return &_bool{b: toBool(val1) && !toBool(val2)}
  46. }
  47. if isWord(val1) && isWord(val2) {
  48. return &_bool{b: escapeWord(toWord(val1)) > escapeWord(toWord(val2))}
  49. }
  50. panic(fmt.Errorf("gt: %s (%s > %s)", errIllegalOperandType, val1.String(), val2.String()))
  51. }
  52. func opLt(val1, val2 value) *_bool {
  53. if isNumber(val1) && isNumber(val2) {
  54. return &_bool{b: toNumber(val1) < toNumber(val2)}
  55. }
  56. if isBool(val1) && isBool(val2) {
  57. return &_bool{b: !toBool(val1) && toBool(val2)}
  58. }
  59. if isWord(val1) && isWord(val2) {
  60. return &_bool{b: escapeWord(toWord(val1)) < escapeWord(toWord(val2))}
  61. }
  62. panic(fmt.Errorf("lt: %s (%s < %s)", errIllegalOperandType, val1.String(), val2.String()))
  63. }
  64. func opAnd(val1, val2 value) *_bool {
  65. return &_bool{b: toBool(val1) && toBool(val2)}
  66. }
  67. func opOr(val1, val2 value) *_bool {
  68. return &_bool{b: toBool(val1) || toBool(val2)}
  69. }
  70. func opNot(val1 value) *_bool {
  71. return &_bool{b: !toBool(val1)}
  72. }
  73. func opRandom(val1 value) *_number {
  74. return &_number{num: toNumber(val1) * rand.Float64()}
  75. }
  76. func opInt(val1 value) *_number {
  77. return &_number{num: math.Floor(toNumber(val1))}
  78. }
  79. func opSqrt(val1 value) *_number {
  80. if num1 := toNumber(val1); num1 >= 0 {
  81. return &_number{num: math.Sqrt(num1)}
  82. }
  83. panic(fmt.Errorf("sqrt: %s (%s)", errNegativeSquareRoot, val1.String()))
  84. }