closure.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package main
  2. type ApplyFn func(s *Scope, args []Any) Any
  3. type Function interface {
  4. Apply(*Scope, []Any) Any
  5. }
  6. type Macro interface {
  7. Function
  8. macro() bool
  9. }
  10. type closure struct {
  11. s *Scope
  12. vars, body []Any
  13. }
  14. func (c *closure) Apply(s *Scope, args []Any) Any {
  15. args = c.s.EvalAll(args)
  16. c.s = NewScope(c.s)
  17. for i := 0; i < len(c.vars); i++ {
  18. v := c.vars[i]
  19. if v != Symbol("&") {
  20. c.s.env[v.(Symbol)] = args[i]
  21. } else {
  22. c.s.env[c.vars[i+1].(Symbol)] = args[i:]
  23. break
  24. }
  25. }
  26. evaled := c.s.EvalAll(c.body)
  27. return evaled[len(evaled)-1]
  28. }
  29. func (c *closure) String() string {
  30. return "#<closure>"
  31. }
  32. type macro closure
  33. func (m *macro) Apply(s *Scope, args []Any) Any {
  34. m.s = NewScope(s)
  35. for i := 0; i < len(m.vars); i++ {
  36. v := m.vars[i]
  37. if v != Symbol("&") {
  38. m.s.env[v.(Symbol)] = args[i]
  39. } else {
  40. m.s.env[m.vars[i+1].(Symbol)] = args[i:]
  41. break
  42. }
  43. }
  44. m.s.EvalAll(m.body[:len(m.body)-1])
  45. return m.s.Eval(m.body[len(m.body)-1])
  46. }
  47. // Just a placeholder method that makes
  48. // sure the macro's interface is unique
  49. func (m *macro) macro() bool {
  50. return true
  51. }
  52. func (m *macro) String() string {
  53. return "#<macro>"
  54. }