stack.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  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. var tl []object.Object
  97. for rec := t; rec != nil; {
  98. //fmt.Println(rec.Qualident())
  99. if tl != nil {
  100. fl = append(fl, tl...)
  101. tl = nil
  102. }
  103. for x := rec.Link(); x != nil; x = x.Link() {
  104. switch x.(type) {
  105. case object.FieldObject:
  106. //fmt.Println(rec.Qualident(), o.Name(), ".", x.Name(), x.Adr())
  107. tl = append(tl, x)
  108. case object.ParameterObject, object.ProcedureObject, object.VariableObject:
  109. //do nothing
  110. default:
  111. halt.As(100, reflect.TypeOf(x))
  112. }
  113. }
  114. if rec.BaseRec() == nil {
  115. x := ml.NewTypeCalc()
  116. x.ConnectTo(rec)
  117. _, frec := x.ForeignBase()
  118. if frec != nil {
  119. //fmt.Println("fbase", frec.Qualident())
  120. tl = nil
  121. }
  122. rec, _ = frec.(object.RecordType)
  123. } else {
  124. rec = rec.BaseRec()
  125. if rec != nil {
  126. //fmt.Println("base", rec.Qualident())
  127. }
  128. }
  129. }
  130. if tl != nil {
  131. fl = append(fl, tl...)
  132. }
  133. r.fi = items.New()
  134. r.fi.Begin()
  135. for _, f := range fl {
  136. push(dom, r.fi, f)
  137. }
  138. r.fi.End()
  139. case object.PointerType:
  140. x = newPtr(o)
  141. default:
  142. halt.As(100, reflect.TypeOf(t))
  143. }
  144. assert.For(x != nil, 40)
  145. //fmt.Println(_o.Name(), x)
  146. d := &item{}
  147. d.Data(x)
  148. il.Set(&key{id: o.Adr()}, d)
  149. case object.ParameterObject:
  150. il.Hold(&key{id: o.Adr()})
  151. default:
  152. halt.As(100, reflect.TypeOf(o))
  153. }
  154. }
  155. func fin(x interface{}) {
  156. switch p := x.(type) {
  157. case *ptrValue:
  158. defer func() {
  159. mod := rtm.ModuleOfType(p.scope.Domain(), p.ct)
  160. ol := mod.Objects[mod.Enter]
  161. var fn object.ProcedureObject
  162. for _, _po := range ol {
  163. switch po := _po.(type) {
  164. case object.ProcedureObject:
  165. if po.Name() == "FINALIZE" && po.Link().Complex().Equals(p.ct) {
  166. fn = po
  167. break
  168. }
  169. }
  170. }
  171. if fn != nil {
  172. global := p.scope.Domain().Discover(context.UNIVERSE).(context.Domain)
  173. root := global.Discover(context.STACK).(frame.Stack)
  174. cn := node.New(constant.CALL, cp.Some())
  175. ol := mod.NodeByObject(fn)
  176. assert.For(len(ol) <= 1, 40)
  177. cn.SetLeft(ol[0])
  178. cc := node.New(constant.CONSTANT, cp.Some()).(node.ConstantNode)
  179. cc.SetData(p)
  180. cc.SetType(object.COMPLEX)
  181. cn.SetRight(cc)
  182. nf := rt2.New(cn)
  183. nf.Init(global.Discover(mod.Name).(context.Domain))
  184. root.Queue(nf)
  185. }
  186. p.scope.Target().(scope.HeapAllocator).Dispose(p.id)
  187. }()
  188. }
  189. }
  190. func (h *halloc) Allocate(name string, t object.PointerType, par ...interface{}) scope.Value {
  191. utils.PrintScope("HEAP ALLOCATE")
  192. //mod := rtm.ModuleOfType(h.area.d, t)
  193. assert.For(t != nil, 20)
  194. var res scope.Value
  195. var talloc func(t object.PointerType)
  196. talloc = func(t object.PointerType) {
  197. switch bt := t.Complex().(type) {
  198. case object.RecordType:
  199. fake := object.New(object.VARIABLE, cp.Some())
  200. fake.SetComplex(bt)
  201. fake.SetType(object.COMPLEX)
  202. fake.SetName("{" + "}")
  203. push(h.area.d, h.area.il, fake)
  204. res = &ptrValue{scope: h.area, id: fake.Adr(), ct: t}
  205. case object.DynArrayType:
  206. assert.For(len(par) > 0, 20)
  207. fake := object.New(object.VARIABLE, cp.Some())
  208. fake.SetComplex(bt)
  209. fake.SetType(object.COMPLEX)
  210. fake.SetName("[]")
  211. push(h.area.d, h.area.il, fake)
  212. h.area.Select(fake.Adr(), func(v scope.Value) {
  213. arr, ok := v.(*dynarr)
  214. assert.For(ok, 60)
  215. arr.Set(par[0].(scope.Value))
  216. })
  217. res = &ptrValue{scope: h.area, id: fake.Adr(), ct: t}
  218. default:
  219. halt.As(100, fmt.Sprintln("cannot allocate", reflect.TypeOf(bt)))
  220. }
  221. }
  222. talloc(t)
  223. assert.For(res != nil, 60)
  224. runtime.SetFinalizer(res, fin)
  225. return res
  226. }
  227. func (h *halloc) Dispose(i cp.ID) {
  228. h.area.Select(i, func(v scope.Value) {
  229. utils.PrintScope("dispose", v)
  230. h.area.il.Remove(&key{id: i})
  231. })
  232. }
  233. func (a *halloc) Join(m scope.Manager) { a.area = m.(*area) }
  234. func (a *salloc) Allocate(n node.Node, final bool) {
  235. mod := rtm.ModuleOfNode(a.area.d, n)
  236. utils.PrintScope("ALLOCATE FOR", mod.Name, n.Adr())
  237. tl := mod.Types[n]
  238. skip := make(map[cp.ID]interface{}) //для процедурных типов в общей куче могут валяться переменные, скипаем их
  239. for _, t := range tl {
  240. switch x := t.(type) {
  241. case object.BasicType:
  242. for link := x.Link(); link != nil; link = link.Link() {
  243. skip[link.Adr()] = link
  244. }
  245. case object.RecordType:
  246. for link := x.Link(); link != nil; link = link.Link() {
  247. skip[link.Adr()] = link
  248. }
  249. }
  250. }
  251. //все объекты скоупа
  252. ol := mod.Objects[n]
  253. //добавим либо переменные внутри процедуры либо если мы создаем скоуп для модуля то процедурные объекты добавим в скиплист
  254. switch o := n.Object().(type) {
  255. case object.ProcedureObject:
  256. for l := o.Link(); l != nil; l = l.Link() {
  257. ol = append(ol, l)
  258. }
  259. case nil: //do nothing
  260. default:
  261. halt.As(100, reflect.TypeOf(o))
  262. }
  263. for _, o := range ol {
  264. switch t := o.(type) {
  265. case object.ProcedureObject:
  266. for l := t.Link(); l != nil; l = l.Link() {
  267. skip[l.Adr()] = l
  268. }
  269. skip[o.Adr()] = o
  270. case object.TypeObject:
  271. skip[o.Adr()] = o
  272. case object.ConstantObject:
  273. skip[o.Adr()] = o
  274. case object.Module:
  275. skip[o.Adr()] = o
  276. }
  277. }
  278. a.area.il.Begin()
  279. a.area.unsafe = true
  280. for _, o := range ol {
  281. if skip[o.Adr()] == nil {
  282. utils.PrintScope(o.Adr(), o.Name())
  283. push(a.area.d, a.area.il, o)
  284. }
  285. }
  286. if final {
  287. a.area.il.End()
  288. a.area.unsafe = false
  289. }
  290. }
  291. func (a *salloc) Dispose(n node.Node) {
  292. utils.PrintScope("DISPOSE")
  293. a.area.il.Drop()
  294. }
  295. func (a *salloc) proper_init(root node.Node, _val node.Node, _par object.Object, tail eval.Do, in eval.IN) eval.Do {
  296. utils.PrintScope("INITIALIZE")
  297. const link = "initialize:par"
  298. end := func(in eval.IN) eval.OUT {
  299. a.area.il.End()
  300. a.area.unsafe = false
  301. return eval.Later(tail)
  302. }
  303. var next eval.Do
  304. do := func(val node.Node, par object.Object) (out eval.OUT) {
  305. utils.PrintScope(par.Adr(), par.Name(), ":=", reflect.TypeOf(val))
  306. out = eval.Now(next)
  307. switch par.(type) {
  308. case object.VariableObject:
  309. out = eval.GetExpression(in, link, val, func(in eval.IN) eval.OUT {
  310. it := a.area.il.Get(&key{id: par.Adr()}).(*item)
  311. v := it.Value().(scope.Variable)
  312. val := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  313. v.Set(val)
  314. return eval.Later(next)
  315. })
  316. case object.ParameterObject:
  317. switch val.(type) {
  318. case node.Designator:
  319. out = eval.GetDesignator(in, link, val, func(in eval.IN) eval.OUT {
  320. if mt, _ := rt2.RegOf(in.Frame)[context.META].(*eval.Meta); mt != nil && mt.Scope != nil {
  321. fa := mt.Scope.(*area).il
  322. a.area.il.Link(&key{id: par.Adr()}, items.ID{In: fa, This: &key{id: mt.Id}})
  323. } else { //поля, элементы массива, некоторые результаты разыменований
  324. d := &item{}
  325. v := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  326. d.Data(v)
  327. a.area.il.Put(&key{id: par.Adr()}, d)
  328. }
  329. return eval.Later(next)
  330. })
  331. case node.Expression: //array заменяем ссылку на переменную
  332. out = eval.GetExpression(in, link, val, func(in eval.IN) eval.OUT {
  333. d := &item{}
  334. data := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  335. switch data.(type) {
  336. case STRING, SHORTSTRING:
  337. val := &dynarr{comp: par.Complex()}
  338. val.Set(data)
  339. d.Data(val)
  340. default:
  341. halt.As(100, reflect.TypeOf(data))
  342. }
  343. a.area.il.Put(&key{id: par.Adr()}, d)
  344. return eval.Later(next)
  345. })
  346. default:
  347. halt.As(100, reflect.TypeOf(val))
  348. }
  349. default:
  350. halt.As(100, reflect.TypeOf(par))
  351. }
  352. return
  353. }
  354. val := _val
  355. par := _par
  356. next = func(eval.IN) eval.OUT {
  357. if val == nil {
  358. return eval.Later(end)
  359. } else {
  360. step := do(val, par)
  361. val = val.Link()
  362. par = par.Link()
  363. return step
  364. }
  365. }
  366. return next
  367. }
  368. func (a *salloc) Initialize(n node.Node, par scope.PARAM) (frame.Sequence, frame.WAIT) {
  369. var tail eval.Do
  370. if par.Tail != nil {
  371. tail = eval.Expose(par.Tail)
  372. } else {
  373. tail = eval.Tail(eval.STOP)
  374. }
  375. return eval.Propose(a.proper_init(n, par.Values, par.Objects, tail, eval.IN{Frame: par.Frame, Parent: par.Frame.Parent()})), frame.NOW
  376. }
  377. func (a *salloc) Join(m scope.Manager) { a.area = m.(*area) }
  378. func (a *area) Target(all ...scope.Allocator) scope.Allocator {
  379. if len(all) > 0 {
  380. a.all = all[0]
  381. }
  382. if a.all == nil {
  383. return &salloc{area: a}
  384. } else {
  385. a.all.Join(a)
  386. return a.all
  387. }
  388. }
  389. func (a *area) String() (ret string) {
  390. a.il.ForEach(func(in items.Value) bool {
  391. v, ok := in.(*item)
  392. if ok {
  393. ret = fmt.Sprintln(ret, v.Data())
  394. } else {
  395. ret = fmt.Sprintln(ret, "..")
  396. }
  397. return false
  398. })
  399. return
  400. }
  401. func (a *area) Provide(x interface{}) scope.Value {
  402. switch z := x.(type) {
  403. case node.ConstantNode:
  404. return newConst(z)
  405. case object.ProcedureObject:
  406. return newProc(z)
  407. default:
  408. halt.As(100, reflect.TypeOf(z))
  409. }
  410. panic(0)
  411. }
  412. func (a *area) Init(d context.Domain) { a.d = d }
  413. func (a *area) Domain() context.Domain { return a.d }
  414. func (a *area) Handle(msg interface{}) {}
  415. func nn(role string) scope.Manager {
  416. switch role {
  417. case context.SCOPE, context.CALL:
  418. return &area{all: &salloc{}, il: items.New()}
  419. case context.HEAP:
  420. ret := &area{all: &halloc{}, il: items.New(), unsafe: true}
  421. ret.il.Begin()
  422. return ret
  423. default:
  424. panic(0)
  425. }
  426. }
  427. func fn(mgr scope.Manager, name string) (ret object.Object) {
  428. utils.PrintScope("FIND", name)
  429. a, ok := mgr.(*area)
  430. assert.For(ok, 20)
  431. assert.For(name != "", 21)
  432. a.il.ForEach(func(in items.Value) (ok bool) {
  433. var v scope.Value
  434. switch val := in.(type) {
  435. case *item:
  436. v = val.Value()
  437. }
  438. switch vv := v.(type) {
  439. case *data:
  440. r := vv.val
  441. switch p := r.(type) {
  442. case *proc:
  443. utils.PrintScope(p.link.Name())
  444. if p.link.Name() == name {
  445. ret = p.link
  446. ok = true
  447. }
  448. }
  449. default:
  450. utils.PrintScope(reflect.TypeOf(vv))
  451. }
  452. return
  453. })
  454. return ret
  455. }
  456. func init() {
  457. scope.New = nn
  458. scope.FindObjByName = fn
  459. }