stack.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. package data
  2. import (
  3. "fmt"
  4. "fw/cp"
  5. "fw/cp/node"
  6. "fw/cp/object"
  7. "fw/rt2"
  8. "fw/rt2/context"
  9. "fw/rt2/frame"
  10. rtm "fw/rt2/module"
  11. "fw/rt2/rules2/wrap/data/items"
  12. "fw/rt2/rules2/wrap/eval"
  13. "fw/rt2/scope"
  14. "fw/utils"
  15. "reflect"
  16. "ypk/assert"
  17. "ypk/halt"
  18. )
  19. type area struct {
  20. d context.Domain
  21. all scope.Allocator
  22. il items.Data
  23. }
  24. type salloc struct {
  25. area *area
  26. }
  27. type key struct {
  28. items.Key
  29. id cp.ID
  30. }
  31. func (k *key) String() string {
  32. return fmt.Sprint(k.id)
  33. }
  34. func (k *key) EqualTo(to items.Key) int {
  35. kk, ok := to.(*key)
  36. if ok && kk.id == k.id {
  37. return 0
  38. } else {
  39. return -1
  40. }
  41. }
  42. type item struct {
  43. items.Item
  44. k items.Key
  45. d interface{}
  46. }
  47. func (i *item) KeyOf(k ...items.Key) items.Key {
  48. if len(k) == 1 {
  49. i.k = k[0]
  50. }
  51. return i.k
  52. }
  53. func (i *item) Copy(from items.Item) { panic(0) }
  54. func (i *item) Data(d ...interface{}) interface{} {
  55. if len(d) == 1 {
  56. i.d = d[0]
  57. }
  58. return i.d
  59. }
  60. func (i *item) Value() scope.Value {
  61. return i.d.(scope.Value)
  62. }
  63. func (a *area) Select(this cp.ID, val scope.ValueOf) {
  64. utils.PrintScope("SELECT", this)
  65. d, ok := a.il.Get(&key{id: this}).(*item)
  66. assert.For(ok, 20, this)
  67. val(d.Value())
  68. }
  69. func (a *area) Exists(this cp.ID) bool {
  70. utils.PrintScope("SEARCH", this)
  71. return a.il.Exists(&key{id: this})
  72. }
  73. func (a *salloc) push(_o object.Object) {
  74. switch o := _o.(type) {
  75. case object.VariableObject:
  76. switch t := o.Complex().(type) {
  77. case nil, object.BasicType:
  78. x := newData(o)
  79. d := &item{}
  80. d.Data(x)
  81. a.area.il.Set(&key{id: o.Adr()}, d)
  82. case object.ArrayType, object.DynArrayType:
  83. x := newData(o)
  84. d := &item{}
  85. d.Data(x)
  86. a.area.il.Set(&key{id: o.Adr()}, d)
  87. default:
  88. halt.As(100, reflect.TypeOf(t))
  89. }
  90. case object.ParameterObject:
  91. a.area.il.Hold(&key{id: o.Adr()})
  92. default:
  93. halt.As(100, reflect.TypeOf(o))
  94. }
  95. }
  96. func (a *salloc) Allocate(n node.Node, final bool) {
  97. mod := rtm.ModuleOfNode(a.area.d, n)
  98. utils.PrintScope("ALLOCATE FOR", mod.Name, n.Adr())
  99. tl := mod.Types[n]
  100. skip := make(map[cp.ID]interface{}) //для процедурных типов в общей куче могут валяться переменные, скипаем их
  101. for _, t := range tl {
  102. switch x := t.(type) {
  103. case object.BasicType:
  104. for link := x.Link(); link != nil; link = link.Link() {
  105. skip[link.Adr()] = link
  106. }
  107. case object.RecordType:
  108. for link := x.Link(); link != nil; link = link.Link() {
  109. skip[link.Adr()] = link
  110. }
  111. }
  112. }
  113. //все объекты скоупа
  114. ol := mod.Objects[n]
  115. //добавим либо переменные внутри процедуры либо если мы создаем скоуп для модуля то процедурные объекты добавим в скиплист
  116. switch o := n.Object().(type) {
  117. case object.ProcedureObject:
  118. for l := o.Link(); l != nil; l = l.Link() {
  119. ol = append(ol, l)
  120. }
  121. case nil: //do nothing
  122. default:
  123. halt.As(100, reflect.TypeOf(o))
  124. }
  125. for _, o := range ol {
  126. switch t := o.(type) {
  127. case object.ProcedureObject:
  128. for l := t.Link(); l != nil; l = l.Link() {
  129. skip[l.Adr()] = l
  130. }
  131. skip[o.Adr()] = o
  132. case object.ConstantObject:
  133. skip[o.Adr()] = o
  134. }
  135. }
  136. a.area.il.Begin()
  137. for _, o := range ol {
  138. if skip[o.Adr()] == nil {
  139. utils.PrintScope(o.Adr(), o.Name())
  140. a.push(o)
  141. }
  142. }
  143. if final {
  144. a.area.il.End()
  145. }
  146. }
  147. func (a *salloc) Dispose(n node.Node) {
  148. a.area.il.Drop()
  149. }
  150. func (a *salloc) proper_init(root node.Node, _val node.Node, _par object.Object, tail eval.Do, in eval.IN) eval.Do {
  151. utils.PrintScope("INITIALIZE")
  152. const link = "initialize:par"
  153. end := func(in eval.IN) eval.OUT {
  154. a.area.il.End()
  155. return eval.Later(tail)
  156. }
  157. var next eval.Do
  158. do := func(val node.Node, par object.Object) (out eval.OUT) {
  159. utils.PrintScope(par.Adr(), par.Name(), ":=", reflect.TypeOf(val))
  160. out = eval.Now(next)
  161. switch par.(type) {
  162. case object.VariableObject:
  163. out = eval.GetExpression(in, link, val, func(in eval.IN) eval.OUT {
  164. it := a.area.il.Get(&key{id: par.Adr()}, items.INIT).(*item)
  165. v := it.Value().(scope.Variable)
  166. val := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  167. v.Set(val)
  168. return eval.Later(next)
  169. })
  170. case object.ParameterObject:
  171. switch val.(type) {
  172. case node.Designator:
  173. out = eval.GetDesignator(in, link, val, func(in eval.IN) eval.OUT {
  174. mt := rt2.RegOf(in.Frame)[context.META].(*eval.Meta)
  175. fa := mt.Scope.(*area).il
  176. a.area.il.Link(&key{id: par.Adr()}, items.ID{In: fa, This: &key{id: mt.Id}})
  177. return eval.Later(next)
  178. })
  179. case node.Expression: //array заменяем ссылку на переменную
  180. out = eval.GetExpression(in, link, val, func(in eval.IN) eval.OUT {
  181. d := &item{}
  182. data := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  183. switch data.(type) {
  184. case STRING, SHORTSTRING:
  185. val := &dynarr{link: par}
  186. val.Set(data)
  187. d.Data(val)
  188. default:
  189. halt.As(100, reflect.TypeOf(data))
  190. }
  191. a.area.il.Put(&key{id: par.Adr()}, d)
  192. return eval.Later(next)
  193. })
  194. default:
  195. halt.As(100, reflect.TypeOf(val))
  196. }
  197. default:
  198. halt.As(100, reflect.TypeOf(par))
  199. }
  200. return
  201. }
  202. val := _val
  203. par := _par
  204. next = func(eval.IN) eval.OUT {
  205. if val == nil {
  206. return eval.Later(end)
  207. } else {
  208. step := do(val, par)
  209. val = val.Link()
  210. par = par.Link()
  211. return step
  212. }
  213. }
  214. return next
  215. }
  216. func (a *salloc) Initialize(n node.Node, par scope.PARAM) (frame.Sequence, frame.WAIT) {
  217. var tail eval.Do
  218. if par.Tail != nil {
  219. tail = eval.Expose(par.Tail)
  220. } else {
  221. tail = eval.Tail(eval.STOP)
  222. }
  223. return eval.Propose(a.proper_init(n, par.Values, par.Objects, tail, eval.IN{Frame: par.Frame, Parent: par.Frame.Parent()})), frame.NOW
  224. }
  225. func (a *salloc) Join(m scope.Manager) { a.area = m.(*area) }
  226. func (a *area) Target(all ...scope.Allocator) scope.Allocator {
  227. if len(all) > 0 {
  228. a.all = all[0]
  229. }
  230. if a.all == nil {
  231. return &salloc{area: a}
  232. } else {
  233. a.all.Join(a)
  234. return a.all
  235. }
  236. }
  237. func (a *area) String() string { return "fixme" }
  238. func (a *area) Provide(x interface{}) scope.Value {
  239. switch z := x.(type) {
  240. case node.ConstantNode:
  241. return newConst(z)
  242. case object.ProcedureObject:
  243. return newProc(z)
  244. default:
  245. halt.As(100, reflect.TypeOf(z))
  246. }
  247. panic(0)
  248. }
  249. func (a *area) Init(d context.Domain) { a.d = d }
  250. func (a *area) Domain() context.Domain { return a.d }
  251. func (a *area) Handle(msg interface{}) {}
  252. func nn(role string) scope.Manager {
  253. switch role {
  254. case context.SCOPE, context.CALL:
  255. return &area{all: &salloc{}, il: items.New()}
  256. case context.HEAP:
  257. return &area{all: nil}
  258. //return &area{all: &halloc{}}
  259. default:
  260. panic(0)
  261. }
  262. }
  263. func fn(mgr scope.Manager, name string) (ret object.Object) {
  264. utils.PrintScope("FIND", name)
  265. a, ok := mgr.(*area)
  266. assert.For(ok, 20)
  267. assert.For(name != "", 21)
  268. a.il.ForEach(func(in items.Value) (ok bool) {
  269. var v scope.Value
  270. switch val := in.(type) {
  271. case *item:
  272. v = val.Value()
  273. }
  274. switch vv := v.(type) {
  275. case *data:
  276. utils.PrintScope(vv.link.Name())
  277. if vv.link.Name() == name {
  278. ret = vv.link
  279. ok = true
  280. }
  281. default:
  282. utils.PrintScope(reflect.TypeOf(vv))
  283. }
  284. return
  285. })
  286. return ret
  287. }
  288. func init() {
  289. scope.New = nn
  290. scope.FindObjByName = fn
  291. }