channels.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package zygo
  2. import (
  3. "errors"
  4. "fmt"
  5. )
  6. type SexpChannel struct {
  7. Val chan Sexp
  8. Typ *RegisteredType
  9. }
  10. func (ch *SexpChannel) SexpString(ps *PrintState) string {
  11. return "[chan]"
  12. }
  13. func (ch *SexpChannel) Type() *RegisteredType {
  14. return ch.Typ // TODO what should this be?
  15. }
  16. func MakeChanFunction(env *Zlisp, name string,
  17. args []Sexp) (Sexp, error) {
  18. if len(args) > 1 {
  19. return SexpNull, WrongNargs
  20. }
  21. size := 0
  22. if len(args) == 1 {
  23. switch t := args[0].(type) {
  24. case *SexpInt:
  25. size = int(t.Val)
  26. default:
  27. return SexpNull, errors.New(
  28. fmt.Sprintf("argument to %s must be int", name))
  29. }
  30. }
  31. return &SexpChannel{Val: make(chan Sexp, size)}, nil
  32. }
  33. func ChanTxFunction(env *Zlisp, name string,
  34. args []Sexp) (Sexp, error) {
  35. if len(args) < 1 {
  36. return SexpNull, WrongNargs
  37. }
  38. var channel chan Sexp
  39. switch t := args[0].(type) {
  40. case *SexpChannel:
  41. channel = chan Sexp(t.Val)
  42. default:
  43. return SexpNull, errors.New(
  44. fmt.Sprintf("argument 0 of %s must be channel", name))
  45. }
  46. if name == "send" {
  47. if len(args) != 2 {
  48. return SexpNull, WrongNargs
  49. }
  50. channel <- args[1]
  51. return SexpNull, nil
  52. }
  53. return <-channel, nil
  54. }
  55. func (env *Zlisp) ImportChannels() {
  56. env.AddFunction("makeChan", MakeChanFunction)
  57. env.AddFunction("send", ChanTxFunction)
  58. env.AddFunction("<!", ChanTxFunction)
  59. }