builtins.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. package main
  2. import (
  3. "fmt"
  4. )
  5. var Builtins = map[Symbol]ApplyFn{
  6. "quote": quote,
  7. "quasiquote": quasiquote,
  8. "lambda": lambda,
  9. "macro": newMacro,
  10. "macrox": macroExpand,
  11. "define": define,
  12. "if": iff,
  13. "set!": set,
  14. "let": let,
  15. // wrapped funcs
  16. "==": equality,
  17. "+": addition,
  18. "-": subtraction,
  19. "*": multiplication,
  20. "car": car,
  21. "cdr": cdr,
  22. "eval": eval,
  23. "true?": True,
  24. "assert": assert,
  25. "begin": begin,
  26. "println": println,
  27. }
  28. // The "u" stands for unwrapped
  29. var (
  30. eval = wrap(wrap(uEval))
  31. equality = wrap(uEquality)
  32. addition = wrap(uAddition)
  33. subtraction = wrap(uSubtraction)
  34. multiplication = wrap(uMultiplication)
  35. car = wrap(uCar)
  36. cdr = wrap(uCdr)
  37. True = wrap(uTrue)
  38. assert = wrap(uAssert)
  39. begin = wrap(uBegin)
  40. println = wrap(uPrintln)
  41. )
  42. func wrap(fn ApplyFn) ApplyFn {
  43. return func(s *Scope, args []Any) Any {
  44. args = s.EvalAll(args)
  45. return fn(s, args)
  46. }
  47. }
  48. func quote(s *Scope, args []Any) Any {
  49. return args[0]
  50. }
  51. func quasiquote(s *Scope, args []Any) Any {
  52. switch arg := args[0].(type) {
  53. case []Any:
  54. return resolveUnquoteSplices(s, resolveUnquotes(s, arg).([]Any))
  55. }
  56. return args[0]
  57. }
  58. func resolveUnquotes(s *Scope, sexp []Any) Any {
  59. if len(sexp) < 1 {
  60. return sexp
  61. }
  62. if sexp[0] == Symbol("unquote") {
  63. return s.Eval(sexp[1])
  64. } else if sexp[0] == Symbol("quasiquote") {
  65. return sexp
  66. }
  67. newSexp := make([]Any, len(sexp))
  68. for i, val := range sexp {
  69. switch val := val.(type) {
  70. case []Any:
  71. newSexp[i] = resolveUnquotes(s, val)
  72. default:
  73. newSexp[i] = val
  74. }
  75. }
  76. return newSexp
  77. }
  78. func resolveUnquoteSplices(s *Scope, sexp []Any) Any {
  79. if len(sexp) < 1 {
  80. return sexp
  81. }
  82. if sexp[0] == Symbol("unquote-splice") {
  83. return s.Eval(sexp[1])
  84. } else if sexp[0] == Symbol("quasiquote") {
  85. return sexp
  86. }
  87. for i := 0; i < len(sexp); i++ {
  88. val := sexp[i]
  89. switch val := val.(type) {
  90. case []Any:
  91. if len(val) > 1 && val[0] == Symbol("unquote-splice") {
  92. sexp = append(sexp[:i], append(resolveUnquoteSplices(s, val).([]Any), sexp[i+1:]...)...)
  93. } else {
  94. sexp[i] = resolveUnquoteSplices(s, val)
  95. }
  96. }
  97. }
  98. return sexp
  99. }
  100. func lambda(s *Scope, args []Any) Any {
  101. return &closure{s, args[0].([]Any), args[1:]}
  102. }
  103. func newMacro(s *Scope, args []Any) Any {
  104. return &macro{nil, args[0].([]Any), args[1:]}
  105. }
  106. func macroExpand(s *Scope, args []Any) Any {
  107. args = args[0].([]Any)
  108. return internalMacroExpand(s, args)
  109. }
  110. func internalMacroExpand(s *Scope, args []Any) Any {
  111. m := args[0]
  112. // The macro is guaranteed to be defined
  113. // since we s.Eval its Symbol beforehand
  114. m, _ = s.Lookup(m.(Symbol))
  115. return m.(Macro).Apply(s, args[1:])
  116. }
  117. func define(s *Scope, args []Any) Any {
  118. err := s.Add(args[0].(Symbol), s.Eval(args[1]))
  119. if err != nil {
  120. panic(err)
  121. }
  122. return nil
  123. }
  124. func iff(s *Scope, args []Any) Any {
  125. if True(s, []Any{args[0]}) == true {
  126. return s.Eval(args[1])
  127. } else {
  128. if len(args) > 2 {
  129. return s.Eval(args[2])
  130. } else {
  131. return nil
  132. }
  133. }
  134. }
  135. func set(s *Scope, args []Any) Any {
  136. s.Override(args[0].(Symbol), s.Eval(args[1]))
  137. return nil
  138. }
  139. func let(s *Scope, args []Any) Any {
  140. for _, v := range args[0].([]Any) {
  141. set(s, v.([]Any))
  142. }
  143. res := s.EvalAll(args[1:])
  144. return res[len(res)-1]
  145. }
  146. // Wrapped functions
  147. // -----------------
  148. func uEval(s *Scope, args []Any) Any {
  149. return args[len(args)-1]
  150. }
  151. func uEquality(s *Scope, args []Any) Any {
  152. for i := 1; i < len(args); i++ {
  153. if args[i-1] != args[i] {
  154. return false
  155. }
  156. }
  157. return true
  158. }
  159. func uAddition(s *Scope, args []Any) Any {
  160. var c int64 = 0
  161. for _, val := range args {
  162. c += val.(int64)
  163. }
  164. return c
  165. }
  166. func uSubtraction(s *Scope, args []Any) Any {
  167. var c int64 = args[0].(int64)
  168. for i := 1; i < len(args); i++ {
  169. c -= args[i].(int64)
  170. }
  171. return c
  172. }
  173. func uMultiplication(s *Scope, args []Any) Any {
  174. var c int64 = args[0].(int64)
  175. for i := 1; i < len(args); i++ {
  176. c *= args[i].(int64)
  177. }
  178. return c
  179. }
  180. func uCar(s *Scope, args []Any) Any {
  181. return args[0]
  182. }
  183. func uCdr(s *Scope, args []Any) Any {
  184. return args[1:]
  185. }
  186. func uTrue(s *Scope, args []Any) Any {
  187. for _, val := range args {
  188. if val == nil || val == false {
  189. return false
  190. }
  191. }
  192. return true
  193. }
  194. func uAssert(s *Scope, args []Any) Any {
  195. for _, val := range args {
  196. if True(s, []Any{val}) != true {
  197. panic("assertion failed")
  198. }
  199. }
  200. return nil
  201. }
  202. func uBegin(s *Scope, args []Any) Any {
  203. return args[len(args)-1]
  204. }
  205. func uPrintln(s *Scope, args []Any) Any {
  206. for _, val := range args {
  207. fmt.Println(val)
  208. }
  209. return nil
  210. }