comparisons.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package glisp
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. )
  7. func signumFloat(f SexpFloat) int {
  8. if f > 0 {
  9. return 1
  10. }
  11. if f < 0 {
  12. return -1
  13. }
  14. return 0
  15. }
  16. func signumInt(i SexpInt) int {
  17. if i > 0 {
  18. return 1
  19. }
  20. if i < 0 {
  21. return -1
  22. }
  23. return 0
  24. }
  25. func compareFloat(f SexpFloat, expr Sexp) (int, error) {
  26. switch e := expr.(type) {
  27. case SexpInt:
  28. return signumFloat(f - SexpFloat(e)), nil
  29. case SexpFloat:
  30. return signumFloat(f - e), nil
  31. case SexpChar:
  32. return signumFloat(f - SexpFloat(e)), nil
  33. }
  34. errmsg := fmt.Sprintf("cannot compare %T to %T", f, expr)
  35. return 0, errors.New(errmsg)
  36. }
  37. func compareInt(i SexpInt, expr Sexp) (int, error) {
  38. switch e := expr.(type) {
  39. case SexpInt:
  40. return signumInt(i - e), nil
  41. case SexpFloat:
  42. return signumFloat(SexpFloat(i) - e), nil
  43. case SexpChar:
  44. return signumInt(i - SexpInt(e)), nil
  45. }
  46. errmsg := fmt.Sprintf("cannot compare %T to %T", i, expr)
  47. return 0, errors.New(errmsg)
  48. }
  49. func compareChar(c SexpChar, expr Sexp) (int, error) {
  50. switch e := expr.(type) {
  51. case SexpInt:
  52. return signumInt(SexpInt(c) - e), nil
  53. case SexpFloat:
  54. return signumFloat(SexpFloat(c) - e), nil
  55. case SexpChar:
  56. return signumInt(SexpInt(c - e)), nil
  57. }
  58. errmsg := fmt.Sprintf("cannot compare %T to %T", c, expr)
  59. return 0, errors.New(errmsg)
  60. }
  61. func compareString(s SexpStr, expr Sexp) (int, error) {
  62. switch e := expr.(type) {
  63. case SexpStr:
  64. return bytes.Compare([]byte(s), []byte(e)), nil
  65. }
  66. errmsg := fmt.Sprintf("cannot compare %T to %T", s, expr)
  67. return 0, errors.New(errmsg)
  68. }
  69. func compareSymbol(sym SexpSymbol, expr Sexp) (int, error) {
  70. switch e := expr.(type) {
  71. case SexpSymbol:
  72. return signumInt(SexpInt(sym.number - e.number)), nil
  73. }
  74. errmsg := fmt.Sprintf("cannot compare %T to %T", sym, expr)
  75. return 0, errors.New(errmsg)
  76. }
  77. func comparePair(a SexpPair, b Sexp) (int, error) {
  78. var bp SexpPair
  79. switch t := b.(type) {
  80. case SexpPair:
  81. bp = t
  82. default:
  83. errmsg := fmt.Sprintf("cannot compare %T to %T", a, b)
  84. return 0, errors.New(errmsg)
  85. }
  86. res, err := Compare(a.head, bp.head)
  87. if err != nil {
  88. return 0, err
  89. }
  90. if res != 0 {
  91. return res, nil
  92. }
  93. return Compare(a.tail, bp.tail)
  94. }
  95. func compareArray(a SexpArray, b Sexp) (int, error) {
  96. var ba SexpArray
  97. switch t := b.(type) {
  98. case SexpArray:
  99. ba = t
  100. default:
  101. errmsg := fmt.Sprintf("cannot compare %T to %T", a, b)
  102. return 0, errors.New(errmsg)
  103. }
  104. var length int
  105. if len(a) < len(ba) {
  106. length = len(a)
  107. } else {
  108. length = len(ba)
  109. }
  110. for i := 0; i < length; i++ {
  111. res, err := Compare(a[i], ba[i])
  112. if err != nil {
  113. return 0, err
  114. }
  115. if res != 0 {
  116. return res, nil
  117. }
  118. }
  119. return signumInt(SexpInt(len(a) - len(ba))), nil
  120. }
  121. func compareBool(a SexpBool, b Sexp) (int, error) {
  122. var bb SexpBool
  123. switch bt := b.(type) {
  124. case SexpBool:
  125. bb = bt
  126. default:
  127. errmsg := fmt.Sprintf("cannot compare %T to %T", a, b)
  128. return 0, errors.New(errmsg)
  129. }
  130. // true > false
  131. if a && bb {
  132. return 0, nil
  133. }
  134. if a {
  135. return 1, nil
  136. }
  137. if bb {
  138. return -1, nil
  139. }
  140. return 0, nil
  141. }
  142. func Compare(a Sexp, b Sexp) (int, error) {
  143. switch at := a.(type) {
  144. case SexpInt:
  145. return compareInt(at, b)
  146. case SexpChar:
  147. return compareChar(at, b)
  148. case SexpFloat:
  149. return compareFloat(at, b)
  150. case SexpBool:
  151. return compareBool(at, b)
  152. case SexpStr:
  153. return compareString(at, b)
  154. case SexpSymbol:
  155. return compareSymbol(at, b)
  156. case SexpPair:
  157. return comparePair(at, b)
  158. case SexpArray:
  159. return compareArray(at, b)
  160. case SexpSentinel:
  161. if at == SexpNull && b == SexpNull {
  162. return 0, nil
  163. } else {
  164. return -1, nil
  165. }
  166. }
  167. errmsg := fmt.Sprintf("cannot compare %T to %T", a, b)
  168. return 0, errors.New(errmsg)
  169. }