object.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. package selsl
  2. import "fmt"
  3. type Slots map[string]Object
  4. func (s Slots) Set(name string, inst Object) Slots {
  5. s[name] = inst
  6. return s
  7. }
  8. func (s Slots) Get(name string) Object {
  9. res, ok := s[name]
  10. if !ok {
  11. return Nil
  12. }
  13. return res
  14. }
  15. /*
  16. func (s Slots) Clone() Slots {
  17. clone := Slots{}
  18. for k, v := range s {
  19. clone[k] = v.Clone()
  20. }
  21. return clone
  22. }
  23. */
  24. // Constants for special object slot names
  25. const (
  26. ParentSlot = "*parent"
  27. SelfSlot = "*self"
  28. MeSlot = "*me"
  29. ArgsSlot = "*args"
  30. )
  31. // IsReturner is a marker interface for types that cause
  32. // a return.
  33. type IsReturner interface{ IsReturn() }
  34. // Breaker is a marker interface for a type that cases
  35. // a break in flow.
  36. type IsBreaker interface{ IsBreak() }
  37. // A Thrower is a marker interface for a type that causes
  38. // a throw.
  39. type IsThrower interface{ IsThrow() }
  40. // Type is the type of an object. It is simply a string.
  41. type Type string
  42. // A message can be send to an object. It is also an object.
  43. type Message struct {
  44. Name string
  45. Args []Object
  46. Env Object
  47. Actor
  48. }
  49. func (m Message) String() string {
  50. return "message: " + m.Name
  51. }
  52. func (Message) Type() Type {
  53. return Type("message")
  54. }
  55. func (m Message) Value(env Object) Object {
  56. return m
  57. }
  58. func (m Message) Send(Message) Object {
  59. return m
  60. }
  61. // Object is the interface for all objects in SELSL.
  62. type Object interface {
  63. // String stringifies the value of the object.
  64. String() string
  65. // Type returns the name of the type in lower case.
  66. Type() Type
  67. // Value evaluates the object in a context.
  68. Value(env Object) Object
  69. // Send sends a message to the object.
  70. Send(msg Message) Object
  71. }
  72. type NilObject struct{}
  73. func (NilObject) String() string {
  74. return "nil"
  75. }
  76. func (NilObject) Value(env Object) Object {
  77. return nil
  78. }
  79. func (NilObject) Type() Type {
  80. return Type("nil")
  81. }
  82. func (NilObject) Send(Message) Object {
  83. return Nil
  84. }
  85. var Nil Object = NilObject{}
  86. func ParentOf(val Object) Object {
  87. return val.Send(Message{Name: ParentSlot})
  88. }
  89. /*
  90. type Environment struct {
  91. Instance
  92. }
  93. func NewEnvironment(parent, me, to Object, args ...Object) *Environment {
  94. name := "_env"
  95. if parent != nil {
  96. name = parent.Name() + "_env"
  97. }
  98. res := &Environment{Instance{name: name, slots: Slots{}}}
  99. res.Set(ParentSlot, parent)
  100. res.Set(SelfSlot, to)
  101. res.Set(ArgsSlot, List(args))
  102. res.Set(MeSlot, me)
  103. return res
  104. }
  105. func SendInEnv(to Object, message string, env Object) Object {
  106. lookup := to
  107. value := lookup.Slots().Get(message)
  108. for value == Nil {
  109. lookup = ParentOf(lookup)
  110. if lookup == Nil || lookup == nil {
  111. panic("Object does not support message " + message)
  112. }
  113. value = lookup.Slots().Get(message)
  114. }
  115. return value.Value(env)
  116. }
  117. func Send(to Object, message string, me, here Object, args ...Object) Object {
  118. env := NewEnvironment(here, me, to, args...)
  119. return SendInEnv(to, message, env)
  120. }
  121. */
  122. // Instance is a concrete implementation of Object
  123. // which can be embedded into Go structs to help them
  124. // become Objects themselves.
  125. type Instance struct {
  126. // the type of the instance, used in Type()
  127. kind Type
  128. // Slots, used to store members
  129. slots Slots
  130. }
  131. // String stringifies the value of the instance.
  132. func (i Instance) String() string {
  133. res := string(i.kind) + " { "
  134. for k, v := range i.slots {
  135. res += "\n" + k + ":" + v.String()
  136. }
  137. res += " } "
  138. return res
  139. }
  140. func (i Instance) Type() Type {
  141. return Type(i.kind)
  142. }
  143. func (i Instance) Value(env Object) Object {
  144. return i
  145. }
  146. func (i Instance) Send(message Message) Object {
  147. value := i.slots.Get(message.Name)
  148. if value == nil || value == Nil {
  149. // XXX should return an error in stead.
  150. return Nil
  151. }
  152. return value.Value(message.Env)
  153. }
  154. func (i *Instance) Set(name string, inst Object) *Instance {
  155. i.slots.Set(name, inst)
  156. return i
  157. }
  158. func NewInstance(kind string) *Instance {
  159. return &Instance{kind: Type(kind), slots: Slots{}}
  160. }
  161. // A primitive is a function implemented in Go that
  162. // on evaluation as an Object calls that function
  163. // with the given environment
  164. type Primitive func(env Object) Object
  165. func (p Primitive) Type() Type {
  166. return Type("primitive")
  167. }
  168. func (p Primitive) Send(m Message) Object {
  169. return p.Value(m)
  170. }
  171. func (p Primitive) Value(env Object) Object {
  172. return p(env)
  173. }
  174. func Self(o Object) Object {
  175. return o.Send(Message{Name: SelfSlot})
  176. }
  177. func Me(o Object) Object {
  178. return o.Send(Message{Name: MeSlot})
  179. }
  180. func Args(o Object) List {
  181. list := o.Send(Message{Name: ArgsSlot})
  182. if list == Nil {
  183. return List{}
  184. }
  185. return list.(List)
  186. }
  187. func Unary(unary func(target Object) Object) Primitive {
  188. return func(env Object) Object {
  189. return unary(Self(env))
  190. }
  191. }
  192. func Nullary(nullary func() Object) Primitive {
  193. return func(env Object) Object {
  194. return nullary()
  195. }
  196. }
  197. type String string
  198. func (s String) String() string {
  199. return string(s)
  200. }
  201. func (s String) Type() Type {
  202. return Type("string")
  203. }
  204. func (p String) Send(m Message) Object {
  205. // XXX implement string methods here
  206. return Nil
  207. }
  208. func (s String) Value(env Object) Object {
  209. return s
  210. }
  211. type List []Object
  212. func (l List) Type() Type {
  213. return Type("list")
  214. }
  215. func (l List) String() string {
  216. res := fmt.Sprintf("list: ")
  217. sep := ""
  218. for _, o := range l {
  219. res = fmt.Sprintf("%s %s %s", res, sep, o.String())
  220. sep = "and"
  221. }
  222. res += ";"
  223. return res
  224. }
  225. func (l List) Send(m Message) Object {
  226. // XXX implement list methods here
  227. return Nil
  228. }
  229. func (l List) Value(env Object) Object {
  230. return l
  231. }
  232. type Error struct {
  233. *Instance
  234. Error error
  235. }
  236. func (e Error) String() string {
  237. return fmt.Sprintf("error `%s`", e.Error)
  238. }
  239. func (e Error) Value(env Object) Object {
  240. return e
  241. }
  242. func NewErrorBasic(err error) Error {
  243. return Error{Instance: NewInstance("error"), Error: err}
  244. }
  245. func NewError(err string) Error {
  246. return NewErrorBasic(fmt.Errorf("%s", err))
  247. }
  248. type Int struct {
  249. *Instance
  250. Int int64
  251. }
  252. func NewInt(i int64) Int {
  253. return Int{Instance: NewInstance("int"), Int: i}
  254. }
  255. func (i Int) String() string {
  256. return fmt.Sprintf("%d", i.Int)
  257. }
  258. func (i Int) Value(env Object) Object {
  259. return i
  260. }
  261. type Statement struct {
  262. *Instance
  263. Command Object
  264. Param List
  265. }
  266. func (s Statement) String() string {
  267. return fmt.Sprintf("%s %s.", s.Command.String(), s.Param.String())
  268. }
  269. /*
  270. func (s Statement) Value(env Object) Object {
  271. cenv := env
  272. cenv.Slots().Set(ArgsSlot, s.Param)
  273. return SendInEnv(env, s.Command.Name(), cenv)
  274. }*/
  275. var _ Object = Error{}
  276. var _ Object = String("")
  277. var _ Object = Int{}
  278. var _ Object = List{}