stack.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  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.ct)
  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.ct) {
  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(name string, 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. var res scope.Value
  180. var talloc func(t object.PointerType)
  181. talloc = func(t object.PointerType) {
  182. switch bt := t.Complex().(type) {
  183. case object.RecordType:
  184. fake := object.New(object.VARIABLE, cp.Some())
  185. fake.SetComplex(bt)
  186. fake.SetType(object.COMPLEX)
  187. fake.SetName("{" + "}")
  188. push(h.area.d, h.area.il, fake)
  189. res = &ptrValue{scope: h.area, id: fake.Adr(), ct: t}
  190. case object.DynArrayType:
  191. assert.For(len(par) > 0, 20)
  192. fake := object.New(object.VARIABLE, cp.Some())
  193. fake.SetComplex(bt)
  194. fake.SetType(object.COMPLEX)
  195. fake.SetName("[]")
  196. push(h.area.d, h.area.il, fake)
  197. h.area.Select(fake.Adr(), func(v scope.Value) {
  198. arr, ok := v.(*dynarr)
  199. assert.For(ok, 60)
  200. arr.Set(par[0].(scope.Value))
  201. })
  202. res = &ptrValue{scope: h.area, id: fake.Adr(), ct: t}
  203. default:
  204. halt.As(100, fmt.Sprintln("cannot allocate", reflect.TypeOf(bt)))
  205. }
  206. }
  207. talloc(t)
  208. assert.For(res != nil, 60)
  209. runtime.SetFinalizer(res, fin)
  210. return res
  211. }
  212. func (h *halloc) Dispose(i cp.ID) {
  213. h.area.Select(i, func(v scope.Value) {
  214. utils.PrintScope("dispose", v)
  215. h.area.il.Remove(&key{id: i})
  216. })
  217. }
  218. func (a *halloc) Join(m scope.Manager) { a.area = m.(*area) }
  219. func (a *salloc) Allocate(n node.Node, final bool) {
  220. mod := rtm.ModuleOfNode(a.area.d, n)
  221. utils.PrintScope("ALLOCATE FOR", mod.Name, n.Adr())
  222. tl := mod.Types[n]
  223. skip := make(map[cp.ID]interface{}) //для процедурных типов в общей куче могут валяться переменные, скипаем их
  224. for _, t := range tl {
  225. switch x := t.(type) {
  226. case object.BasicType:
  227. for link := x.Link(); link != nil; link = link.Link() {
  228. skip[link.Adr()] = link
  229. }
  230. case object.RecordType:
  231. for link := x.Link(); link != nil; link = link.Link() {
  232. skip[link.Adr()] = link
  233. }
  234. }
  235. }
  236. //все объекты скоупа
  237. ol := mod.Objects[n]
  238. //добавим либо переменные внутри процедуры либо если мы создаем скоуп для модуля то процедурные объекты добавим в скиплист
  239. switch o := n.Object().(type) {
  240. case object.ProcedureObject:
  241. for l := o.Link(); l != nil; l = l.Link() {
  242. ol = append(ol, l)
  243. }
  244. case nil: //do nothing
  245. default:
  246. halt.As(100, reflect.TypeOf(o))
  247. }
  248. for _, o := range ol {
  249. switch t := o.(type) {
  250. case object.ProcedureObject:
  251. for l := t.Link(); l != nil; l = l.Link() {
  252. skip[l.Adr()] = l
  253. }
  254. skip[o.Adr()] = o
  255. case object.TypeObject:
  256. skip[o.Adr()] = o
  257. case object.ConstantObject:
  258. skip[o.Adr()] = o
  259. case object.Module:
  260. skip[o.Adr()] = o
  261. }
  262. }
  263. a.area.il.Begin()
  264. a.area.unsafe = true
  265. for _, o := range ol {
  266. if skip[o.Adr()] == nil {
  267. utils.PrintScope(o.Adr(), o.Name())
  268. push(a.area.d, a.area.il, o)
  269. }
  270. }
  271. if final {
  272. a.area.il.End()
  273. a.area.unsafe = false
  274. }
  275. }
  276. func (a *salloc) Dispose(n node.Node) {
  277. utils.PrintScope("DISPOSE")
  278. a.area.il.Drop()
  279. }
  280. func (a *salloc) proper_init(root node.Node, _val node.Node, _par object.Object, tail eval.Do, in eval.IN) eval.Do {
  281. utils.PrintScope("INITIALIZE")
  282. const link = "initialize:par"
  283. end := func(in eval.IN) eval.OUT {
  284. a.area.il.End()
  285. a.area.unsafe = false
  286. return eval.Later(tail)
  287. }
  288. var next eval.Do
  289. do := func(val node.Node, par object.Object) (out eval.OUT) {
  290. utils.PrintScope(par.Adr(), par.Name(), ":=", reflect.TypeOf(val))
  291. out = eval.Now(next)
  292. switch par.(type) {
  293. case object.VariableObject:
  294. out = eval.GetExpression(in, link, val, func(in eval.IN) eval.OUT {
  295. it := a.area.il.Get(&key{id: par.Adr()}).(*item)
  296. v := it.Value().(scope.Variable)
  297. val := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  298. v.Set(val)
  299. return eval.Later(next)
  300. })
  301. case object.ParameterObject:
  302. switch val.(type) {
  303. case node.Designator:
  304. out = eval.GetDesignator(in, link, val, func(in eval.IN) eval.OUT {
  305. if mt, _ := rt2.RegOf(in.Frame)[context.META].(*eval.Meta); mt != nil && mt.Scope != nil {
  306. fa := mt.Scope.(*area).il
  307. a.area.il.Link(&key{id: par.Adr()}, items.ID{In: fa, This: &key{id: mt.Id}})
  308. } else { //поля, элементы массива, некоторые результаты разыменований
  309. d := &item{}
  310. v := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  311. d.Data(v)
  312. a.area.il.Put(&key{id: par.Adr()}, d)
  313. }
  314. return eval.Later(next)
  315. })
  316. case node.Expression: //array заменяем ссылку на переменную
  317. out = eval.GetExpression(in, link, val, func(in eval.IN) eval.OUT {
  318. d := &item{}
  319. data := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
  320. switch data.(type) {
  321. case STRING, SHORTSTRING:
  322. val := &dynarr{comp: par.Complex()}
  323. val.Set(data)
  324. d.Data(val)
  325. default:
  326. halt.As(100, reflect.TypeOf(data))
  327. }
  328. a.area.il.Put(&key{id: par.Adr()}, d)
  329. return eval.Later(next)
  330. })
  331. default:
  332. halt.As(100, reflect.TypeOf(val))
  333. }
  334. default:
  335. halt.As(100, reflect.TypeOf(par))
  336. }
  337. return
  338. }
  339. val := _val
  340. par := _par
  341. next = func(eval.IN) eval.OUT {
  342. if val == nil {
  343. return eval.Later(end)
  344. } else {
  345. step := do(val, par)
  346. val = val.Link()
  347. par = par.Link()
  348. return step
  349. }
  350. }
  351. return next
  352. }
  353. func (a *salloc) Initialize(n node.Node, par scope.PARAM) (frame.Sequence, frame.WAIT) {
  354. var tail eval.Do
  355. if par.Tail != nil {
  356. tail = eval.Expose(par.Tail)
  357. } else {
  358. tail = eval.Tail(eval.STOP)
  359. }
  360. return eval.Propose(a.proper_init(n, par.Values, par.Objects, tail, eval.IN{Frame: par.Frame, Parent: par.Frame.Parent()})), frame.NOW
  361. }
  362. func (a *salloc) Join(m scope.Manager) { a.area = m.(*area) }
  363. func (a *area) Target(all ...scope.Allocator) scope.Allocator {
  364. if len(all) > 0 {
  365. a.all = all[0]
  366. }
  367. if a.all == nil {
  368. return &salloc{area: a}
  369. } else {
  370. a.all.Join(a)
  371. return a.all
  372. }
  373. }
  374. func (a *area) String() (ret string) {
  375. a.il.ForEach(func(in items.Value) bool {
  376. v, ok := in.(*item)
  377. if ok {
  378. ret = fmt.Sprintln(ret, v.Data())
  379. } else {
  380. ret = fmt.Sprintln(ret, "..")
  381. }
  382. return false
  383. })
  384. return
  385. }
  386. func (a *area) Provide(x interface{}) scope.Value {
  387. switch z := x.(type) {
  388. case node.ConstantNode:
  389. return newConst(z)
  390. case object.ProcedureObject:
  391. return newProc(z)
  392. default:
  393. halt.As(100, reflect.TypeOf(z))
  394. }
  395. panic(0)
  396. }
  397. func (a *area) Init(d context.Domain) { a.d = d }
  398. func (a *area) Domain() context.Domain { return a.d }
  399. func (a *area) Handle(msg interface{}) {}
  400. func nn(role string) scope.Manager {
  401. switch role {
  402. case context.SCOPE, context.CALL:
  403. return &area{all: &salloc{}, il: items.New()}
  404. case context.HEAP:
  405. ret := &area{all: &halloc{}, il: items.New(), unsafe: true}
  406. ret.il.Begin()
  407. return ret
  408. default:
  409. panic(0)
  410. }
  411. }
  412. func fn(mgr scope.Manager, name string) (ret object.Object) {
  413. utils.PrintScope("FIND", name)
  414. a, ok := mgr.(*area)
  415. assert.For(ok, 20)
  416. assert.For(name != "", 21)
  417. a.il.ForEach(func(in items.Value) (ok bool) {
  418. var v scope.Value
  419. switch val := in.(type) {
  420. case *item:
  421. v = val.Value()
  422. }
  423. switch vv := v.(type) {
  424. case *data:
  425. r := vv.val
  426. switch p := r.(type) {
  427. case *proc:
  428. utils.PrintScope(p.link.Name())
  429. if p.link.Name() == name {
  430. ret = p.link
  431. ok = true
  432. }
  433. }
  434. default:
  435. utils.PrintScope(reflect.TypeOf(vv))
  436. }
  437. return
  438. })
  439. return ret
  440. }
  441. func init() {
  442. scope.New = nn
  443. scope.FindObjByName = fn
  444. }