stack.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. package data
  2. import (
  3. "fmt"
  4. "fw/cp"
  5. "fw/cp/constant"
  6. "fw/cp/node"
  7. "fw/cp/object"
  8. "fw/rt2"
  9. "fw/rt2/context"
  10. "fw/rt2/frame"
  11. rtm "fw/rt2/module"
  12. "fw/rt2/rules2/wrap/data/items"
  13. "fw/rt2/rules2/wrap/eval"
  14. "fw/rt2/scope"
  15. "fw/utils"
  16. "reflect"
  17. "runtime"
  18. "ypk/assert"
  19. "ypk/halt"
  20. )
  21. type area struct {
  22. d context.Domain
  23. all scope.Allocator
  24. il items.Data
  25. unsafe bool
  26. }
  27. type salloc struct {
  28. area *area
  29. }
  30. type halloc struct {
  31. area *area
  32. }
  33. type key struct {
  34. items.Key
  35. id cp.ID
  36. }
  37. func (k *key) String() string {
  38. return fmt.Sprint(k.id)
  39. }
  40. func (k *key) Hash() int {
  41. return int(k.id)
  42. }
  43. func (k *key) EqualTo(to items.Key) int {
  44. kk, ok := to.(*key)
  45. if ok && kk.id == k.id {
  46. return 0
  47. } else {
  48. return -1
  49. }
  50. }
  51. type item struct {
  52. items.Item
  53. k items.Key
  54. d interface{}
  55. }
  56. func (i *item) KeyOf(k ...items.Key) items.Key {
  57. if len(k) == 1 {
  58. i.k = k[0]
  59. }
  60. return i.k
  61. }
  62. func (i *item) Copy(from items.Item) { panic(0) }
  63. func (i *item) Data(d ...interface{}) interface{} {
  64. if len(d) == 1 {
  65. i.d = d[0]
  66. }
  67. return i.d
  68. }
  69. func (i *item) Value() scope.Value {
  70. return i.d.(scope.Value)
  71. }
  72. func (a *area) Select(this cp.ID, val scope.ValueOf) {
  73. utils.PrintScope("SELECT", this)
  74. d, ok := a.il.Get(&key{id: this}).(*item)
  75. assert.For(ok, 20, this)
  76. val(d.Value())
  77. }
  78. func (a *area) Exists(this cp.ID) bool {
  79. utils.PrintScope("SEARCH", this)
  80. return a.il.Exists(&key{id: this})
  81. }
  82. func push(dom context.Domain, il items.Data, _o object.Object) {
  83. switch o := _o.(type) {
  84. case object.VariableObject, object.FieldObject:
  85. var x interface{}
  86. switch t := o.Complex().(type) {
  87. case nil, object.BasicType:
  88. x = newData(o)
  89. case object.ArrayType, object.DynArrayType:
  90. x = newData(o)
  91. case object.RecordType:
  92. ml := dom.Global().Discover(context.MOD).(rtm.List)
  93. r := newRec(o)
  94. x = r
  95. fl := make([]object.Object, 0)
  96. for rec := t; rec != nil; {
  97. for x := rec.Link(); x != nil; x = x.Link() {
  98. switch x.(type) {
  99. case object.FieldObject:
  100. //fmt.Println(o.Name(), ".", x.Name(), x.Adr())
  101. fl = append(fl, x)
  102. case object.ParameterObject, object.ProcedureObject, object.VariableObject:
  103. //do nothing
  104. default:
  105. halt.As(100, reflect.TypeOf(x))
  106. }
  107. }
  108. if rec.BaseRec() == nil {
  109. x := ml.NewTypeCalc()
  110. x.ConnectTo(rec)
  111. _, frec := x.ForeignBase()
  112. //fmt.Println(frec)
  113. rec, _ = frec.(object.RecordType)
  114. } else {
  115. rec = rec.BaseRec()
  116. }
  117. }
  118. r.fi = items.New()
  119. r.fi.Begin()
  120. for _, f := range fl {
  121. push(dom, r.fi, f)
  122. }
  123. r.fi.End()
  124. case object.PointerType:
  125. x = newPtr(o)
  126. default:
  127. halt.As(100, reflect.TypeOf(t))
  128. }
  129. assert.For(x != nil, 40)
  130. //fmt.Println(_o.Name(), x)
  131. d := &item{}
  132. d.Data(x)
  133. il.Set(&key{id: o.Adr()}, d)
  134. case object.ParameterObject:
  135. il.Hold(&key{id: o.Adr()})
  136. default:
  137. halt.As(100, reflect.TypeOf(o))
  138. }
  139. }
  140. func fin(x interface{}) {
  141. switch p := x.(type) {
  142. case *ptrValue:
  143. defer func() {
  144. mod := rtm.ModuleOfType(p.scope.Domain(), p.link.Complex())
  145. ol := mod.Objects[mod.Enter]
  146. var fn object.ProcedureObject
  147. for _, _po := range ol {
  148. switch po := _po.(type) {
  149. case object.ProcedureObject:
  150. if po.Name() == "FINALIZE" && po.Link().Complex().Equals(p.link.Complex()) {
  151. fn = po
  152. break
  153. }
  154. }
  155. }
  156. if fn != nil {
  157. global := p.scope.Domain().Discover(context.UNIVERSE).(context.Domain)
  158. root := global.Discover(context.STACK).(frame.Stack)
  159. cn := node.New(constant.CALL, cp.Some())
  160. ol := mod.NodeByObject(fn)
  161. assert.For(len(ol) <= 1, 40)
  162. cn.SetLeft(ol[0])
  163. cc := node.New(constant.CONSTANT, cp.Some()).(node.ConstantNode)
  164. cc.SetData(p)
  165. cc.SetType(object.COMPLEX)
  166. cn.SetRight(cc)
  167. nf := rt2.New(cn)
  168. nf.Init(global.Discover(mod.Name).(context.Domain))
  169. root.Queue(nf)
  170. }
  171. p.scope.Target().(scope.HeapAllocator).Dispose(p.id)
  172. }()
  173. }
  174. }
  175. func (h *halloc) Allocate(o object.Object, t object.PointerType, par ...interface{}) scope.Value {
  176. utils.PrintScope("HEAP ALLOCATE")
  177. //mod := rtm.ModuleOfType(h.area.d, t)
  178. assert.For(t != nil, 20)
  179. assert.For(o != nil, 21)
  180. var res scope.Value
  181. var talloc func(t object.PointerType)
  182. talloc = func(t object.PointerType) {
  183. switch bt := t.Complex().(type) {
  184. case object.RecordType:
  185. fake := object.New(object.VARIABLE, cp.Some())
  186. fake.SetComplex(bt)
  187. fake.SetType(object.COMPLEX)
  188. fake.SetName("{" + o.Name() + "}")
  189. push(h.area.d, h.area.il, fake)
  190. res = &ptrValue{scope: h.area, id: fake.Adr(), link: o}
  191. case object.DynArrayType:
  192. assert.For(len(par) > 0, 20)
  193. fake := object.New(object.VARIABLE, cp.Some())
  194. fake.SetComplex(bt)
  195. fake.SetType(object.COMPLEX)
  196. fake.SetName("[]")
  197. push(h.area.d, h.area.il, fake)
  198. h.area.Select(fake.Adr(), func(v scope.Value) {
  199. arr, ok := v.(*dynarr)
  200. assert.For(ok, 60)
  201. arr.Set(par[0].(scope.Value))
  202. })
  203. res = &ptrValue{scope: h.area, id: fake.Adr(), link: o}
  204. default:
  205. halt.As(100, fmt.Sprintln("cannot allocate", reflect.TypeOf(bt)))
  206. }
  207. }
  208. talloc(t)
  209. assert.For(res != nil, 60)
  210. runtime.SetFinalizer(res, fin)
  211. return res
  212. }
  213. func (h *halloc) Dispose(i cp.ID) {
  214. h.area.Select(i, func(v scope.Value) {
  215. utils.PrintScope("dispose", v)
  216. h.area.il.Remove(&key{id: i})
  217. })
  218. }
  219. func (a *halloc) Join(m scope.Manager) { a.area = m.(*area) }
  220. func (a *salloc) Allocate(n node.Node, final bool) {
  221. mod := rtm.ModuleOfNode(a.area.d, n)
  222. utils.PrintScope("ALLOCATE FOR", mod.Name, n.Adr())
  223. tl := mod.Types[n]
  224. skip := make(map[cp.ID]interface{}) //для процедурных типов в общей куче могут валяться переменные, скипаем их
  225. for _, t := range tl {
  226. switch x := t.(type) {
  227. case object.BasicType:
  228. for link := x.Link(); link != nil; link = link.Link() {
  229. skip[link.Adr()] = link
  230. }
  231. case object.RecordType:
  232. for link := x.Link(); link != nil; link = link.Link() {
  233. skip[link.Adr()] = link
  234. }
  235. }
  236. }
  237. //все объекты скоупа
  238. ol := mod.Objects[n]
  239. //добавим либо переменные внутри процедуры либо если мы создаем скоуп для модуля то процедурные объекты добавим в скиплист
  240. switch o := n.Object().(type) {
  241. case object.ProcedureObject:
  242. for l := o.Link(); l != nil; l = l.Link() {
  243. ol = append(ol, l)
  244. }
  245. case nil: //do nothing
  246. default:
  247. halt.As(100, reflect.TypeOf(o))
  248. }
  249. for _, o := range ol {
  250. switch t := o.(type) {
  251. case object.ProcedureObject:
  252. for l := t.Link(); l != nil; l = l.Link() {
  253. skip[l.Adr()] = l
  254. }
  255. skip[o.Adr()] = o
  256. case object.TypeObject:
  257. skip[o.Adr()] = o
  258. case object.ConstantObject:
  259. skip[o.Adr()] = o
  260. case object.Module:
  261. skip[o.Adr()] = o
  262. }
  263. }
  264. a.area.il.Begin()
  265. a.area.unsafe = true
  266. for _, o := range ol {
  267. if skip[o.Adr()] == nil {
  268. utils.PrintScope(o.Adr(), o.Name())
  269. push(a.area.d, a.area.il, o)
  270. }
  271. }
  272. if final {
  273. a.area.il.End()
  274. a.area.unsafe = false
  275. }
  276. }
  277. func (a *salloc) Dispose(n node.Node) {
  278. utils.PrintScope("DISPOSE")
  279. a.area.il.Drop()
  280. }
  281. func (a *salloc) proper_init(root node.Node, _val node.Node, _par object.Object, tail eval.Do, in eval.IN) eval.Do {
  282. utils.PrintScope("INITIALIZE")
  283. const link = "initialize:par"
  284. end := func(in eval.IN) eval.OUT {
  285. a.area.il.End()
  286. a.area.unsafe = false
  287. return eval.Later(tail)
  288. }
  289. var next eval.Do
  290. do := func(val node.Node, par object.Object) (out eval.OUT) {
  291. utils.PrintScope(par.Adr(), par.Name(), ":=", reflect.TypeOf(val))
  292. out = eval.Now(next)
  293. switch par.(type) {
  294. case object.VariableObject:
  295. out = eval.GetExpression(in, link, val, func(in eval.IN) eval.OUT {
  296. it := a.area.il.Get(&key{id: par.Adr()}).(*item)
  297. v := it.Value().(scope.Variable)
  298. val := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  299. v.Set(val)
  300. return eval.Later(next)
  301. })
  302. case object.ParameterObject:
  303. switch val.(type) {
  304. case node.Designator:
  305. out = eval.GetDesignator(in, link, val, func(in eval.IN) eval.OUT {
  306. mt := rt2.RegOf(in.Frame)[context.META].(*eval.Meta)
  307. fa := mt.Scope.(*area).il
  308. a.area.il.Link(&key{id: par.Adr()}, items.ID{In: fa, This: &key{id: mt.Id}})
  309. return eval.Later(next)
  310. })
  311. case node.Expression: //array заменяем ссылку на переменную
  312. out = eval.GetExpression(in, link, val, func(in eval.IN) eval.OUT {
  313. d := &item{}
  314. data := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  315. switch data.(type) {
  316. case STRING, SHORTSTRING:
  317. val := &dynarr{link: par}
  318. val.Set(data)
  319. d.Data(val)
  320. default:
  321. halt.As(100, reflect.TypeOf(data))
  322. }
  323. a.area.il.Put(&key{id: par.Adr()}, d)
  324. return eval.Later(next)
  325. })
  326. default:
  327. halt.As(100, reflect.TypeOf(val))
  328. }
  329. default:
  330. halt.As(100, reflect.TypeOf(par))
  331. }
  332. return
  333. }
  334. val := _val
  335. par := _par
  336. next = func(eval.IN) eval.OUT {
  337. if val == nil {
  338. return eval.Later(end)
  339. } else {
  340. step := do(val, par)
  341. val = val.Link()
  342. par = par.Link()
  343. return step
  344. }
  345. }
  346. return next
  347. }
  348. func (a *salloc) Initialize(n node.Node, par scope.PARAM) (frame.Sequence, frame.WAIT) {
  349. var tail eval.Do
  350. if par.Tail != nil {
  351. tail = eval.Expose(par.Tail)
  352. } else {
  353. tail = eval.Tail(eval.STOP)
  354. }
  355. return eval.Propose(a.proper_init(n, par.Values, par.Objects, tail, eval.IN{Frame: par.Frame, Parent: par.Frame.Parent()})), frame.NOW
  356. }
  357. func (a *salloc) Join(m scope.Manager) { a.area = m.(*area) }
  358. func (a *area) Target(all ...scope.Allocator) scope.Allocator {
  359. if len(all) > 0 {
  360. a.all = all[0]
  361. }
  362. if a.all == nil {
  363. return &salloc{area: a}
  364. } else {
  365. a.all.Join(a)
  366. return a.all
  367. }
  368. }
  369. func (a *area) String() string { return "fixme" }
  370. func (a *area) Provide(x interface{}) scope.Value {
  371. switch z := x.(type) {
  372. case node.ConstantNode:
  373. return newConst(z)
  374. case object.ProcedureObject:
  375. return newProc(z)
  376. default:
  377. halt.As(100, reflect.TypeOf(z))
  378. }
  379. panic(0)
  380. }
  381. func (a *area) Init(d context.Domain) { a.d = d }
  382. func (a *area) Domain() context.Domain { return a.d }
  383. func (a *area) Handle(msg interface{}) {}
  384. func nn(role string) scope.Manager {
  385. switch role {
  386. case context.SCOPE, context.CALL:
  387. return &area{all: &salloc{}, il: items.New()}
  388. case context.HEAP:
  389. ret := &area{all: &halloc{}, il: items.New(), unsafe: true}
  390. ret.il.Begin()
  391. return ret
  392. default:
  393. panic(0)
  394. }
  395. }
  396. func fn(mgr scope.Manager, name string) (ret object.Object) {
  397. utils.PrintScope("FIND", name)
  398. a, ok := mgr.(*area)
  399. assert.For(ok, 20)
  400. assert.For(name != "", 21)
  401. a.il.ForEach(func(in items.Value) (ok bool) {
  402. var v scope.Value
  403. switch val := in.(type) {
  404. case *item:
  405. v = val.Value()
  406. }
  407. switch vv := v.(type) {
  408. case *data:
  409. utils.PrintScope(vv.link.Name())
  410. if vv.link.Name() == name {
  411. ret = vv.link
  412. ok = true
  413. }
  414. default:
  415. utils.PrintScope(reflect.TypeOf(vv))
  416. }
  417. return
  418. })
  419. return ret
  420. }
  421. func init() {
  422. scope.New = nn
  423. scope.FindObjByName = fn
  424. }