eval.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. package expr
  2. import (
  3. "fmt"
  4. "math"
  5. "reflect"
  6. )
  7. type Env map[Var]interface{}
  8. type runtimePanic string
  9. func SafetyEvalBool(expr Expr, env Env) (value bool, err error) {
  10. defer func() {
  11. switch x := recover().(type) {
  12. case nil:
  13. // no panic
  14. case runtimePanic:
  15. value = false
  16. err = fmt.Errorf("%s", x)
  17. default:
  18. // unexpected panic: resume state of panic.
  19. panic(x)
  20. }
  21. }()
  22. if expr == nil {
  23. return false, nil
  24. }
  25. value = ConvertToBool(expr.Eval(env))
  26. return
  27. }
  28. func (v Var) Eval(env Env) reflect.Value {
  29. switch v {
  30. case "true":
  31. return reflect.ValueOf(true)
  32. case "false":
  33. return reflect.ValueOf(false)
  34. default:
  35. if i, ok := env[v]; ok {
  36. return reflect.ValueOf(i)
  37. }
  38. panic(runtimePanic(fmt.Sprintf("undefined variable: %s", v)))
  39. }
  40. }
  41. func (l literal) Eval(_ Env) reflect.Value {
  42. return reflect.ValueOf(l.value)
  43. }
  44. func (u unary) Eval(env Env) reflect.Value {
  45. switch u.op {
  46. case "+":
  47. return unaryPlus(u.x.Eval(env))
  48. case "-":
  49. return unaryMinus(u.x.Eval(env))
  50. case "!":
  51. return logicalNegation(u.x.Eval(env))
  52. case "~":
  53. return bitwiseComplement(u.x.Eval(env))
  54. }
  55. panic(runtimePanic(fmt.Sprintf("unsupported unary operator: %q", u.op)))
  56. }
  57. func (b binary) Eval(env Env) reflect.Value {
  58. switch b.op {
  59. case "+":
  60. return addition(b.x.Eval(env), b.y.Eval(env))
  61. case "-":
  62. return subtraction(b.x.Eval(env), b.y.Eval(env))
  63. case "*":
  64. return multiplication(b.x.Eval(env), b.y.Eval(env))
  65. case "/":
  66. return division(b.x.Eval(env), b.y.Eval(env))
  67. case "%":
  68. return modulus(b.x.Eval(env), b.y.Eval(env))
  69. case "&":
  70. return bitwiseAnd(b.x.Eval(env), b.y.Eval(env))
  71. case "&&":
  72. return logicalAnd(b.x.Eval(env), b.y.Eval(env))
  73. case "|":
  74. return bitwiseOr(b.x.Eval(env), b.y.Eval(env))
  75. case "||":
  76. return logicalOr(b.x.Eval(env), b.y.Eval(env))
  77. case "=", "==":
  78. return comparisonEqual(b.x.Eval(env), b.y.Eval(env))
  79. case ">":
  80. return comparisonGreater(b.x.Eval(env), b.y.Eval(env))
  81. case ">=":
  82. return comparisonGreaterOrEqual(b.x.Eval(env), b.y.Eval(env))
  83. case "<":
  84. return comparisonLess(b.x.Eval(env), b.y.Eval(env))
  85. case "<=":
  86. return comparisonLessOrEqual(b.x.Eval(env), b.y.Eval(env))
  87. case "!=":
  88. return comparisonNotEqual(b.x.Eval(env), b.y.Eval(env))
  89. }
  90. panic(runtimePanic(fmt.Sprintf("unsupported binary operator: %q", b.op)))
  91. }
  92. func (c call) Eval(env Env) reflect.Value {
  93. switch c.fn {
  94. case "pow":
  95. return reflect.ValueOf(math.Pow(ConvertToFloat(c.args[0].Eval(env)), ConvertToFloat(c.args[1].Eval(env))))
  96. case "sin":
  97. return reflect.ValueOf(math.Sin(ConvertToFloat(c.args[0].Eval(env))))
  98. case "sqrt":
  99. return reflect.ValueOf(math.Sqrt(ConvertToFloat(c.args[0].Eval(env))))
  100. }
  101. panic(runtimePanic(fmt.Sprintf("unsupported function call: %s", c.fn)))
  102. }
  103. func ConvertToBool(v reflect.Value) bool {
  104. switch v.Kind() {
  105. case reflect.Bool:
  106. return v.Bool()
  107. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  108. return v.Int() != 0
  109. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  110. return v.Uint() != 0
  111. case reflect.Float32, reflect.Float64:
  112. return v.Float() != 0
  113. default:
  114. panic(runtimePanic(fmt.Sprintf("cannot convert data type: %s to bool", v.Kind().String())))
  115. }
  116. }
  117. func ConvertToInt(v reflect.Value) int64 {
  118. switch v.Kind() {
  119. case reflect.Bool:
  120. if v.Bool() {
  121. return 1
  122. } else {
  123. return 0
  124. }
  125. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  126. return v.Int()
  127. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  128. return int64(v.Uint())
  129. case reflect.Float32, reflect.Float64:
  130. return int64(v.Float())
  131. default:
  132. panic(runtimePanic(fmt.Sprintf("cannot convert data type: %s to int", v.Kind().String())))
  133. }
  134. }
  135. func ConvertToUint(v reflect.Value) uint64 {
  136. switch v.Kind() {
  137. case reflect.Bool:
  138. if v.Bool() {
  139. return 1
  140. } else {
  141. return 0
  142. }
  143. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  144. return uint64(v.Int())
  145. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  146. return v.Uint()
  147. case reflect.Float32, reflect.Float64:
  148. return uint64(v.Float())
  149. default:
  150. panic(runtimePanic(fmt.Sprintf("cannot convert data type: %s to uint", v.Kind().String())))
  151. }
  152. }
  153. func ConvertToFloat(v reflect.Value) float64 {
  154. switch v.Kind() {
  155. case reflect.Bool:
  156. if v.Bool() {
  157. return 1
  158. } else {
  159. return 0
  160. }
  161. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  162. return float64(v.Int())
  163. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  164. return float64(v.Uint())
  165. case reflect.Float32, reflect.Float64:
  166. return v.Float()
  167. default:
  168. panic(runtimePanic(fmt.Sprintf("cannot convert data type: %s to float", v.Kind().String())))
  169. }
  170. }
  171. func unaryPlus(v reflect.Value) reflect.Value {
  172. return v
  173. }
  174. func unaryMinus(v reflect.Value) reflect.Value {
  175. switch v.Kind() {
  176. case reflect.Bool:
  177. return v
  178. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  179. return reflect.ValueOf(-v.Int())
  180. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  181. return reflect.ValueOf(-v.Uint())
  182. case reflect.Float32, reflect.Float64:
  183. return reflect.ValueOf(-v.Float())
  184. default:
  185. panic(runtimePanic(fmt.Sprintf("unary minus not support type: %s", v.Kind().String())))
  186. }
  187. }
  188. func logicalNegation(v reflect.Value) reflect.Value {
  189. return reflect.ValueOf(!ConvertToBool(v))
  190. }
  191. func bitwiseComplement(v reflect.Value) reflect.Value {
  192. switch v.Kind() {
  193. case reflect.Bool:
  194. return reflect.ValueOf(!v.Bool())
  195. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  196. return reflect.ValueOf(^v.Int())
  197. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  198. return reflect.ValueOf(^v.Uint())
  199. case reflect.Float32, reflect.Float64:
  200. panic(runtimePanic("cannot eval ~ for float"))
  201. default:
  202. panic(runtimePanic(fmt.Sprintf("bitwise complement not support type: %s", v.Kind().String())))
  203. }
  204. }
  205. func typeLevel(k reflect.Kind) int {
  206. switch k {
  207. case reflect.Float32, reflect.Float64:
  208. return 4
  209. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  210. return 3
  211. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  212. return 2
  213. case reflect.Bool:
  214. return 1
  215. default:
  216. return 0
  217. }
  218. }
  219. func typeAscend(a reflect.Kind, b reflect.Kind) reflect.Kind {
  220. if typeLevel(a) >= typeLevel(b) {
  221. return a
  222. } else {
  223. return b
  224. }
  225. }
  226. func addition(left reflect.Value, right reflect.Value) reflect.Value {
  227. k := typeAscend(left.Kind(), right.Kind())
  228. switch k {
  229. case reflect.Float32, reflect.Float64:
  230. r := ConvertToFloat(left) + ConvertToFloat(right)
  231. return reflect.ValueOf(r)
  232. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  233. r := ConvertToUint(left) + ConvertToUint(right)
  234. return reflect.ValueOf(r)
  235. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  236. r := ConvertToInt(left) + ConvertToInt(right)
  237. return reflect.ValueOf(r)
  238. case reflect.Bool:
  239. r := ConvertToInt(left) + ConvertToInt(right)
  240. return reflect.ValueOf(r != 0)
  241. default:
  242. panic(runtimePanic(fmt.Sprintf("type %s and %s not support addition", left.Kind().String(), right.Kind().String())))
  243. }
  244. }
  245. func subtraction(left reflect.Value, right reflect.Value) reflect.Value {
  246. k := typeAscend(left.Kind(), right.Kind())
  247. switch k {
  248. case reflect.Float32, reflect.Float64:
  249. r := ConvertToFloat(left) - ConvertToFloat(right)
  250. return reflect.ValueOf(r)
  251. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  252. r := ConvertToUint(left) - ConvertToUint(right)
  253. return reflect.ValueOf(r)
  254. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  255. r := ConvertToInt(left) - ConvertToInt(right)
  256. return reflect.ValueOf(r)
  257. case reflect.Bool:
  258. r := ConvertToInt(left) - ConvertToInt(right)
  259. return reflect.ValueOf(r != 0)
  260. default:
  261. panic(runtimePanic(fmt.Sprintf("type %s and %s not support subtraction", left.Kind().String(), right.Kind().String())))
  262. }
  263. }
  264. func multiplication(left reflect.Value, right reflect.Value) reflect.Value {
  265. k := typeAscend(left.Kind(), right.Kind())
  266. switch k {
  267. case reflect.Float32, reflect.Float64:
  268. r := ConvertToFloat(left) * ConvertToFloat(right)
  269. return reflect.ValueOf(r)
  270. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  271. r := ConvertToUint(left) * ConvertToUint(right)
  272. return reflect.ValueOf(r)
  273. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  274. r := ConvertToInt(left) * ConvertToInt(right)
  275. return reflect.ValueOf(r)
  276. case reflect.Bool:
  277. r := ConvertToInt(left) * ConvertToInt(right)
  278. return reflect.ValueOf(r != 0)
  279. default:
  280. panic(runtimePanic(fmt.Sprintf("type %s and %s not support multiplication", left.Kind().String(), right.Kind().String())))
  281. }
  282. }
  283. func division(left reflect.Value, right reflect.Value) reflect.Value {
  284. k := typeAscend(left.Kind(), right.Kind())
  285. switch k {
  286. case reflect.Float32, reflect.Float64:
  287. r := ConvertToFloat(left) / ConvertToFloat(right)
  288. return reflect.ValueOf(r)
  289. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  290. r := ConvertToUint(left) / ConvertToUint(right)
  291. return reflect.ValueOf(r)
  292. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  293. r := ConvertToInt(left) / ConvertToInt(right)
  294. return reflect.ValueOf(r)
  295. case reflect.Bool:
  296. r := ConvertToInt(left) / ConvertToInt(right)
  297. return reflect.ValueOf(r != 0)
  298. default:
  299. panic(runtimePanic(fmt.Sprintf("type %s and %s not support division", left.Kind().String(), right.Kind().String())))
  300. }
  301. }
  302. func modulus(left reflect.Value, right reflect.Value) reflect.Value {
  303. k := typeAscend(left.Kind(), right.Kind())
  304. switch k {
  305. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  306. r := ConvertToUint(left) % ConvertToUint(right)
  307. return reflect.ValueOf(r)
  308. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  309. r := ConvertToInt(left) % ConvertToInt(right)
  310. return reflect.ValueOf(r)
  311. case reflect.Bool:
  312. r := ConvertToInt(left) % ConvertToInt(right)
  313. return reflect.ValueOf(r != 0)
  314. default:
  315. panic(runtimePanic(fmt.Sprintf("type %s and %s not support division", left.Kind().String(), right.Kind().String())))
  316. }
  317. }
  318. func bitwiseAnd(left reflect.Value, right reflect.Value) reflect.Value {
  319. k := typeAscend(left.Kind(), right.Kind())
  320. switch k {
  321. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  322. r := ConvertToUint(left) & ConvertToUint(right)
  323. return reflect.ValueOf(r)
  324. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  325. r := ConvertToInt(left) & ConvertToInt(right)
  326. return reflect.ValueOf(r)
  327. case reflect.Bool:
  328. r := ConvertToBool(left) && ConvertToBool(right)
  329. return reflect.ValueOf(r)
  330. default:
  331. panic(runtimePanic(fmt.Sprintf("type %s and %s not support bitwise and", left.Kind().String(), right.Kind().String())))
  332. }
  333. }
  334. func bitwiseOr(left reflect.Value, right reflect.Value) reflect.Value {
  335. k := typeAscend(left.Kind(), right.Kind())
  336. switch k {
  337. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  338. r := ConvertToUint(left) | ConvertToUint(right)
  339. return reflect.ValueOf(r)
  340. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  341. r := ConvertToInt(left) | ConvertToInt(right)
  342. return reflect.ValueOf(r)
  343. case reflect.Bool:
  344. r := ConvertToBool(left) || ConvertToBool(right)
  345. return reflect.ValueOf(r)
  346. default:
  347. panic(runtimePanic(fmt.Sprintf("type %s and %s not support bitwise or", left.Kind().String(), right.Kind().String())))
  348. }
  349. }
  350. func logicalAnd(left reflect.Value, right reflect.Value) reflect.Value {
  351. r := ConvertToBool(left) && ConvertToBool(right)
  352. return reflect.ValueOf(r)
  353. }
  354. func logicalOr(left reflect.Value, right reflect.Value) reflect.Value {
  355. r := ConvertToBool(left) || ConvertToBool(right)
  356. return reflect.ValueOf(r)
  357. }
  358. func comparisonEqual(left reflect.Value, right reflect.Value) reflect.Value {
  359. k := typeAscend(left.Kind(), right.Kind())
  360. switch k {
  361. case reflect.Float32, reflect.Float64:
  362. r := ConvertToFloat(left) == ConvertToFloat(right)
  363. return reflect.ValueOf(r)
  364. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  365. r := ConvertToUint(left) == ConvertToUint(right)
  366. return reflect.ValueOf(r)
  367. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  368. r := ConvertToInt(left) == ConvertToInt(right)
  369. return reflect.ValueOf(r)
  370. case reflect.Bool:
  371. r := ConvertToInt(left) == ConvertToInt(right)
  372. return reflect.ValueOf(r)
  373. default:
  374. panic(runtimePanic(fmt.Sprintf("type %s and %s not support comparison equal", left.Kind().String(), right.Kind().String())))
  375. }
  376. }
  377. func comparisonNotEqual(left reflect.Value, right reflect.Value) reflect.Value {
  378. k := typeAscend(left.Kind(), right.Kind())
  379. switch k {
  380. case reflect.Float32, reflect.Float64:
  381. r := ConvertToFloat(left) != ConvertToFloat(right)
  382. return reflect.ValueOf(r)
  383. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  384. r := ConvertToUint(left) != ConvertToUint(right)
  385. return reflect.ValueOf(r)
  386. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  387. r := ConvertToInt(left) != ConvertToInt(right)
  388. return reflect.ValueOf(r)
  389. case reflect.Bool:
  390. r := ConvertToInt(left) != ConvertToInt(right)
  391. return reflect.ValueOf(r)
  392. default:
  393. panic(runtimePanic(fmt.Sprintf("type %s and %s not support comparison not equal", left.Kind().String(), right.Kind().String())))
  394. }
  395. }
  396. func comparisonGreater(left reflect.Value, right reflect.Value) reflect.Value {
  397. k := typeAscend(left.Kind(), right.Kind())
  398. switch k {
  399. case reflect.Float32, reflect.Float64:
  400. r := ConvertToFloat(left) > ConvertToFloat(right)
  401. return reflect.ValueOf(r)
  402. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  403. r := ConvertToUint(left) > ConvertToUint(right)
  404. return reflect.ValueOf(r)
  405. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  406. r := ConvertToInt(left) > ConvertToInt(right)
  407. return reflect.ValueOf(r)
  408. case reflect.Bool:
  409. r := ConvertToInt(left) > ConvertToInt(right)
  410. return reflect.ValueOf(r)
  411. default:
  412. panic(runtimePanic(fmt.Sprintf("type %s and %s not support comparison greater", left.Kind().String(), right.Kind().String())))
  413. }
  414. }
  415. func comparisonGreaterOrEqual(left reflect.Value, right reflect.Value) reflect.Value {
  416. k := typeAscend(left.Kind(), right.Kind())
  417. switch k {
  418. case reflect.Float32, reflect.Float64:
  419. r := ConvertToFloat(left) >= ConvertToFloat(right)
  420. return reflect.ValueOf(r)
  421. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  422. r := ConvertToUint(left) >= ConvertToUint(right)
  423. return reflect.ValueOf(r)
  424. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  425. r := ConvertToInt(left) >= ConvertToInt(right)
  426. return reflect.ValueOf(r)
  427. case reflect.Bool:
  428. r := ConvertToInt(left) >= ConvertToInt(right)
  429. return reflect.ValueOf(r)
  430. default:
  431. panic(runtimePanic(fmt.Sprintf("type %s and %s not support comparison greater or equal", left.Kind().String(), right.Kind().String())))
  432. }
  433. }
  434. func comparisonLess(left reflect.Value, right reflect.Value) reflect.Value {
  435. k := typeAscend(left.Kind(), right.Kind())
  436. switch k {
  437. case reflect.Float32, reflect.Float64:
  438. r := ConvertToFloat(left) < ConvertToFloat(right)
  439. return reflect.ValueOf(r)
  440. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  441. r := ConvertToUint(left) < ConvertToUint(right)
  442. return reflect.ValueOf(r)
  443. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  444. r := ConvertToInt(left) < ConvertToInt(right)
  445. return reflect.ValueOf(r)
  446. case reflect.Bool:
  447. r := ConvertToInt(left) < ConvertToInt(right)
  448. return reflect.ValueOf(r)
  449. default:
  450. panic(runtimePanic(fmt.Sprintf("type %s and %s not support comparison less", left.Kind().String(), right.Kind().String())))
  451. }
  452. }
  453. func comparisonLessOrEqual(left reflect.Value, right reflect.Value) reflect.Value {
  454. k := typeAscend(left.Kind(), right.Kind())
  455. switch k {
  456. case reflect.Float32, reflect.Float64:
  457. r := ConvertToFloat(left) <= ConvertToFloat(right)
  458. return reflect.ValueOf(r)
  459. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  460. r := ConvertToUint(left) <= ConvertToUint(right)
  461. return reflect.ValueOf(r)
  462. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  463. r := ConvertToInt(left) <= ConvertToInt(right)
  464. return reflect.ValueOf(r)
  465. case reflect.Bool:
  466. r := ConvertToInt(left) <= ConvertToInt(right)
  467. return reflect.ValueOf(r)
  468. default:
  469. panic(runtimePanic(fmt.Sprintf("type %s and %s not support comparison less or equal", left.Kind().String(), right.Kind().String())))
  470. }
  471. }