expressions.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package glisp
  2. import (
  3. "reflect"
  4. "strconv"
  5. "strings"
  6. )
  7. type Sexp interface {
  8. SexpString() string
  9. }
  10. type SexpSentinel int
  11. const (
  12. SexpNull SexpSentinel = iota
  13. SexpEnd
  14. SexpMarker
  15. )
  16. func (sent SexpSentinel) SexpString() string {
  17. if sent == SexpNull {
  18. return "()"
  19. }
  20. if sent == SexpEnd {
  21. return "End"
  22. }
  23. if sent == SexpMarker {
  24. return "Marker"
  25. }
  26. return ""
  27. }
  28. type SexpPair struct {
  29. head Sexp
  30. tail Sexp
  31. }
  32. func Cons(a Sexp, b Sexp) SexpPair {
  33. return SexpPair{a, b}
  34. }
  35. func (pair SexpPair) Head() Sexp {
  36. return pair.head
  37. }
  38. func (pair SexpPair) Tail() Sexp {
  39. return pair.tail
  40. }
  41. func (pair SexpPair) SexpString() string {
  42. str := "("
  43. for {
  44. switch pair.tail.(type) {
  45. case SexpPair:
  46. str += pair.head.SexpString() + " "
  47. pair = pair.tail.(SexpPair)
  48. continue
  49. }
  50. break
  51. }
  52. str += pair.head.SexpString()
  53. if pair.tail == SexpNull {
  54. str += ")"
  55. } else {
  56. str += " . " + pair.tail.SexpString() + ")"
  57. }
  58. return str
  59. }
  60. type SexpArray []Sexp
  61. type SexpHash struct {
  62. TypeName *string
  63. Map map[int][]SexpPair
  64. KeyOrder *[]Sexp // must user pointers here, else hset! will fail to update.
  65. GoStruct *interface{}
  66. NumKeys *int
  67. }
  68. type SexpInt int
  69. type SexpBool bool
  70. type SexpFloat float64
  71. type SexpChar rune
  72. type SexpStr string
  73. var SexpIntSize = reflect.TypeOf(SexpInt(0)).Bits()
  74. var SexpFloatSize = reflect.TypeOf(SexpFloat(0.0)).Bits()
  75. func (arr SexpArray) SexpString() string {
  76. if len(arr) == 0 {
  77. return "[]"
  78. }
  79. str := "[" + arr[0].SexpString()
  80. for _, sexp := range arr[1:] {
  81. str += " " + sexp.SexpString()
  82. }
  83. str += "]"
  84. return str
  85. }
  86. func (hash SexpHash) SexpString() string {
  87. str := "{"
  88. for _, arr := range hash.Map {
  89. for _, pair := range arr {
  90. str += pair.head.SexpString() + " "
  91. str += pair.tail.SexpString() + " "
  92. }
  93. }
  94. if len(str) > 1 {
  95. return str[:len(str)-1] + "}"
  96. }
  97. return str + "}"
  98. }
  99. func (b SexpBool) SexpString() string {
  100. if b {
  101. return "true"
  102. }
  103. return "false"
  104. }
  105. func (i SexpInt) SexpString() string {
  106. return strconv.Itoa(int(i))
  107. }
  108. func (f SexpFloat) SexpString() string {
  109. return strconv.FormatFloat(float64(f), 'g', 5, SexpFloatSize)
  110. }
  111. func (c SexpChar) SexpString() string {
  112. return "#" + strings.Trim(strconv.QuoteRune(rune(c)), "'")
  113. }
  114. func (s SexpStr) SexpString() string {
  115. return strconv.Quote(string(s))
  116. }
  117. type SexpSymbol struct {
  118. name string
  119. number int
  120. }
  121. func (sym SexpSymbol) SexpString() string {
  122. return sym.name
  123. }
  124. func (sym SexpSymbol) Name() string {
  125. return sym.name
  126. }
  127. func (sym SexpSymbol) Number() int {
  128. return sym.number
  129. }
  130. type SexpFunction struct {
  131. name string
  132. user bool
  133. nargs int
  134. varargs bool
  135. fun GlispFunction
  136. userfun GlispUserFunction
  137. closeScope *Stack
  138. }
  139. func (sf SexpFunction) SexpString() string {
  140. return "fn [" + sf.name + "]"
  141. }
  142. func IsTruthy(expr Sexp) bool {
  143. switch e := expr.(type) {
  144. case SexpBool:
  145. return bool(e)
  146. case SexpInt:
  147. return e != 0
  148. case SexpChar:
  149. return e != 0
  150. case SexpSentinel:
  151. return e != SexpNull
  152. }
  153. return true
  154. }
  155. type SexpStackmark struct {
  156. sym SexpSymbol
  157. }
  158. func (mark SexpStackmark) SexpString() string {
  159. return "stackmark " + mark.sym.name
  160. }