comparisons.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. package zygo
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "math"
  7. "reflect"
  8. )
  9. func IsNaNFunction(name string) ZlispUserFunction {
  10. return func(env *Zlisp, _ string, args []Sexp) (Sexp, error) {
  11. if len(args) != 1 {
  12. return SexpNull, WrongNargs
  13. }
  14. var err error
  15. a := args[0]
  16. if sel, isSel := a.(Selector); isSel {
  17. a, err = sel.RHS(env)
  18. if err != nil {
  19. return SexpNull, err
  20. }
  21. }
  22. switch at := a.(type) {
  23. case *SexpFloat:
  24. if math.IsNaN(at.Val) {
  25. return &SexpBool{Val: true}, nil
  26. }
  27. }
  28. return &SexpBool{Val: false}, nil
  29. }
  30. }
  31. func signumFloat(f float64) int {
  32. if f > 0 {
  33. return 1
  34. }
  35. if f < 0 {
  36. return -1
  37. }
  38. return 0
  39. }
  40. func signumInt(i int64) int {
  41. if i > 0 {
  42. return 1
  43. }
  44. if i < 0 {
  45. return -1
  46. }
  47. return 0
  48. }
  49. func compareFloat(f *SexpFloat, expr Sexp) (int, error) {
  50. switch e := expr.(type) {
  51. case *SexpInt:
  52. if math.IsNaN(f.Val) {
  53. return 2, nil
  54. }
  55. return signumFloat(f.Val - float64(e.Val)), nil
  56. case *SexpFloat:
  57. nanCount := 0
  58. if math.IsNaN(f.Val) {
  59. nanCount++
  60. }
  61. if math.IsNaN(e.Val) {
  62. nanCount++
  63. }
  64. if nanCount > 0 {
  65. return 1 + nanCount, nil
  66. }
  67. return signumFloat(f.Val - e.Val), nil
  68. case *SexpChar:
  69. if math.IsNaN(f.Val) {
  70. return 2, nil
  71. }
  72. return signumFloat(f.Val - float64(e.Val)), nil
  73. }
  74. errmsg := fmt.Sprintf("err 91: cannot compare %T to %T", f, expr)
  75. return 0, errors.New(errmsg)
  76. }
  77. func compareInt(i *SexpInt, expr Sexp) (int, error) {
  78. switch e := expr.(type) {
  79. case *SexpInt:
  80. return signumInt(i.Val - e.Val), nil
  81. case *SexpFloat:
  82. return signumFloat(float64(i.Val) - e.Val), nil
  83. case *SexpChar:
  84. return signumInt(i.Val - int64(e.Val)), nil
  85. case *SexpReflect:
  86. r := reflect.Value(e.Val)
  87. ifa := r.Interface()
  88. switch z := ifa.(type) {
  89. case *int64:
  90. return signumInt(i.Val - *z), nil
  91. }
  92. P("compareInt(): ifa = %v/%T", ifa, ifa)
  93. P("compareInt(): r.Elem() = %v/%T", r.Elem(), r.Elem())
  94. P("compareInt(): r.Elem().Interface() = %v/%T", r.Elem().Interface(), r.Elem().Interface())
  95. P("compareInt(): r.Elem().Type() = %v/%T", r.Elem().Type(), r.Elem().Type())
  96. P("compareInt(): r.Elem().Type().Name() = %v/%T", r.Elem().Type().Name(), r.Elem().Type().Name())
  97. }
  98. errmsg := fmt.Sprintf("err 92: cannot compare %T to %T", i, expr)
  99. return 0, errors.New(errmsg)
  100. }
  101. func compareChar(c *SexpChar, expr Sexp) (int, error) {
  102. switch e := expr.(type) {
  103. case *SexpInt:
  104. return signumInt(int64(c.Val) - e.Val), nil
  105. case *SexpFloat:
  106. return signumFloat(float64(c.Val) - e.Val), nil
  107. case *SexpChar:
  108. return signumInt(int64(c.Val) - int64(e.Val)), nil
  109. }
  110. errmsg := fmt.Sprintf("err 93: cannot compare %T to %T", c, expr)
  111. return 0, errors.New(errmsg)
  112. }
  113. func compareString(s *SexpStr, expr Sexp) (int, error) {
  114. switch e := expr.(type) {
  115. case *SexpStr:
  116. return bytes.Compare([]byte(s.S), []byte(e.S)), nil
  117. case *SexpReflect:
  118. r := reflect.Value(e.Val)
  119. ifa := r.Interface()
  120. switch z := ifa.(type) {
  121. case *string:
  122. return bytes.Compare([]byte(s.S), []byte(*z)), nil
  123. }
  124. }
  125. errmsg := fmt.Sprintf("err 94: cannot compare %T to %T", s, expr)
  126. return 0, errors.New(errmsg)
  127. }
  128. func (env *Zlisp) compareSymbol(sym *SexpSymbol, expr Sexp) (int, error) {
  129. switch e := expr.(type) {
  130. case *SexpSymbol:
  131. return signumInt(int64(sym.number - e.number)), nil
  132. }
  133. errmsg := fmt.Sprintf("err 95: cannot compare %T to %T", sym, expr)
  134. return 0, errors.New(errmsg)
  135. }
  136. func (env *Zlisp) comparePair(a *SexpPair, b Sexp) (int, error) {
  137. var bp *SexpPair
  138. switch t := b.(type) {
  139. case *SexpPair:
  140. bp = t
  141. default:
  142. errmsg := fmt.Sprintf("err 96: cannot compare %T to %T", a, b)
  143. return 0, errors.New(errmsg)
  144. }
  145. res, err := env.Compare(a.Head, bp.Head)
  146. if err != nil {
  147. return 0, err
  148. }
  149. if res != 0 {
  150. return res, nil
  151. }
  152. return env.Compare(a.Tail, bp.Tail)
  153. }
  154. func (env *Zlisp) compareArray(a *SexpArray, b Sexp) (int, error) {
  155. var ba *SexpArray
  156. switch t := b.(type) {
  157. case *SexpArray:
  158. ba = t
  159. default:
  160. errmsg := fmt.Sprintf("err 97: cannot compare %T to %T", a, b)
  161. return 0, errors.New(errmsg)
  162. }
  163. var length int
  164. if len(a.Val) < len(ba.Val) {
  165. length = len(a.Val)
  166. } else {
  167. length = len(ba.Val)
  168. }
  169. for i := 0; i < length; i++ {
  170. res, err := env.Compare(a.Val[i], ba.Val[i])
  171. if err != nil {
  172. return 0, err
  173. }
  174. if res != 0 {
  175. return res, nil
  176. }
  177. }
  178. return signumInt(int64(len(a.Val) - len(ba.Val))), nil
  179. }
  180. func compareBool(a *SexpBool, b Sexp) (int, error) {
  181. var bb *SexpBool
  182. switch bt := b.(type) {
  183. case *SexpBool:
  184. bb = bt
  185. default:
  186. errmsg := fmt.Sprintf("err 98: cannot compare %T to %T", a, b)
  187. return 0, errors.New(errmsg)
  188. }
  189. // true > false
  190. if a.Val && bb.Val {
  191. return 0, nil
  192. }
  193. if a.Val {
  194. return 1, nil
  195. }
  196. if bb.Val {
  197. return -1, nil
  198. }
  199. return 0, nil
  200. }
  201. func comparePointers(a *SexpPointer, bs Sexp) (int, error) {
  202. var b *SexpPointer
  203. switch bt := bs.(type) {
  204. case *SexpPointer:
  205. b = bt
  206. default:
  207. return 0, fmt.Errorf("err 99: cannot compare %T to %T", a, bs)
  208. }
  209. if a.Target == b.Target {
  210. return 0, nil
  211. }
  212. return 1, nil
  213. }
  214. func (env *Zlisp) Compare(a Sexp, b Sexp) (int, error) {
  215. var err error
  216. if sel, isSel := a.(Selector); isSel {
  217. a, err = sel.RHS(env)
  218. if err != nil {
  219. return 0, err
  220. }
  221. }
  222. if sel, isSel := b.(Selector); isSel {
  223. b, err = sel.RHS(env)
  224. if err != nil {
  225. return 0, err
  226. }
  227. }
  228. switch at := a.(type) {
  229. case *SexpInt:
  230. return compareInt(at, b)
  231. case *SexpUint64:
  232. return compareUint64(at, b)
  233. case *SexpChar:
  234. return compareChar(at, b)
  235. case *SexpFloat:
  236. return compareFloat(at, b)
  237. case *SexpBool:
  238. return compareBool(at, b)
  239. case *SexpStr:
  240. return compareString(at, b)
  241. case *SexpSymbol:
  242. return env.compareSymbol(at, b)
  243. case *SexpPair:
  244. return env.comparePair(at, b)
  245. case *SexpArray:
  246. return env.compareArray(at, b)
  247. case *SexpHash:
  248. return compareHash(at, b)
  249. case *RegisteredType:
  250. return compareRegisteredTypes(at, b)
  251. case *SexpPointer:
  252. return comparePointers(at, b)
  253. case *SexpSentinel:
  254. if at == SexpNull && b == SexpNull {
  255. return 0, nil
  256. } else {
  257. return -1, nil
  258. }
  259. case *SexpTime:
  260. switch bt := b.(type) {
  261. case *SexpTime:
  262. if bt.Tm.Unix() == at.Tm.Unix() {
  263. return 0, nil
  264. }
  265. return -1, nil
  266. }
  267. case *SexpReflect:
  268. r := reflect.Value(at.Val)
  269. ifa := r.Interface()
  270. //P("Compare(): ifa = %v/%t", ifa, ifa)
  271. //P("Compare(): r.Elem() = %v/%T", r.Elem(), r.Elem())
  272. switch z := ifa.(type) {
  273. case *int64:
  274. return compareInt(&SexpInt{Val: *z}, b)
  275. case *string:
  276. return compareString(&SexpStr{S: *z}, b)
  277. }
  278. }
  279. errmsg := fmt.Sprintf("err 100: cannot compare %T to %T", a, b)
  280. return 0, errors.New(errmsg)
  281. }
  282. // only compare uint64 to uint64
  283. func compareUint64(i *SexpUint64, expr Sexp) (int, error) {
  284. switch e := expr.(type) {
  285. case *SexpUint64:
  286. return signumUint64(i.Val - e.Val), nil
  287. }
  288. errmsg := fmt.Sprintf("err 101: cannot compare %T to %T", i, expr)
  289. return 0, errors.New(errmsg)
  290. }
  291. func signumUint64(i uint64) int {
  292. if i > 0 {
  293. return 1
  294. }
  295. if i < 0 {
  296. return -1
  297. }
  298. return 0
  299. }