ms.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. package modern
  2. import (
  3. "fmt"
  4. "fw/cp"
  5. "fw/cp/constant/enter"
  6. cpm "fw/cp/module"
  7. "fw/cp/node"
  8. "fw/cp/object"
  9. "fw/rt2"
  10. "fw/rt2/context"
  11. "fw/rt2/frame"
  12. rtm "fw/rt2/module"
  13. "fw/rt2/scope"
  14. "fw/utils"
  15. "reflect"
  16. "ypk/assert"
  17. "ypk/halt"
  18. )
  19. type level struct {
  20. k map[cp.ID]int
  21. v map[int]scope.Variable
  22. r map[int]scope.Ref
  23. l map[int]*level
  24. next int
  25. ready bool
  26. nested bool
  27. }
  28. type area struct {
  29. d context.Domain
  30. data []*level
  31. all scope.Allocator
  32. }
  33. type salloc struct {
  34. area *area
  35. }
  36. type ref struct {
  37. scope.Ref
  38. id cp.ID
  39. link object.Object
  40. sc scope.Manager
  41. }
  42. func (r *ref) String() string {
  43. var m string
  44. if r.sc != nil {
  45. m = rtm.DomainModule(r.sc.Domain()).Name
  46. }
  47. return fmt.Sprint(m, " ", r.link.Name(), "@", r.id)
  48. }
  49. func newRef(x object.Object) *ref {
  50. return &ref{link: x}
  51. }
  52. func newlvl() *level {
  53. return &level{next: 1,
  54. k: make(map[cp.ID]int), ready: true,
  55. v: make(map[int]scope.Variable),
  56. r: make(map[int]scope.Ref),
  57. l: make(map[int]*level)}
  58. }
  59. func (a *area) top() *level {
  60. if len(a.data) > 0 {
  61. return a.data[len(a.data)-1]
  62. }
  63. return nil
  64. }
  65. func (a *area) Provide(x interface{}) scope.ValueFor {
  66. return func(scope.Value) scope.Value {
  67. switch z := x.(type) {
  68. case node.ConstantNode:
  69. return newConst(z)
  70. case object.ProcedureObject:
  71. return newProc(z)
  72. default:
  73. halt.As(100, reflect.TypeOf(z))
  74. }
  75. panic(0)
  76. }
  77. }
  78. //var alloc func(*level, []object.Object, map[cp.ID]interface{})
  79. func (l *level) alloc(mod *cpm.Module, root node.Node, ol []object.Object, skip map[cp.ID]interface{}) {
  80. for _, o := range ol {
  81. imp := mod.ImportOf(o)
  82. utils.PrintScope(reflect.TypeOf(o), o.Adr())
  83. _, field := o.(object.FieldObject)
  84. if imp == "" && (skip[o.Adr()] == nil || (field && l.nested)) {
  85. utils.PrintScope("next", l.next)
  86. switch x := o.(type) {
  87. case object.VariableObject, object.FieldObject:
  88. switch t := o.Complex().(type) {
  89. case nil, object.BasicType, object.ArrayType, object.DynArrayType:
  90. l.v[l.next] = newData(x)
  91. l.k[x.Adr()] = l.next
  92. l.next++
  93. case object.RecordType:
  94. l.v[l.next] = newRec(x)
  95. nl := newlvl()
  96. nl.nested = true
  97. l.l[l.next] = nl
  98. l.k[x.Adr()] = l.next
  99. fl := make([]object.Object, 0)
  100. for rec := t; rec != nil; {
  101. for x := rec.Link(); x != nil; x = x.Link() {
  102. //fmt.Println(o.Name(), ".", x.Name(), x.Adr())
  103. fl = append(fl, x)
  104. }
  105. rec = rec.BaseType()
  106. }
  107. //fmt.Println("record")
  108. l.v[l.next].(*rec).l = nl
  109. nl.alloc(mod, root, fl, skip)
  110. l.next++
  111. case object.PointerType:
  112. l.v[l.next] = newPtr(x)
  113. l.k[x.Adr()] = l.next
  114. l.next++
  115. default:
  116. halt.As(20, reflect.TypeOf(t))
  117. }
  118. case object.TypeObject, object.ConstantObject, object.ProcedureObject, object.Module:
  119. //do nothing
  120. case object.ParameterObject:
  121. if root.(node.EnterNode).Enter() == enter.PROCEDURE {
  122. l.r[l.next] = newRef(x)
  123. l.k[x.Adr()] = l.next
  124. l.next++
  125. }
  126. default:
  127. halt.As(20, reflect.TypeOf(x))
  128. }
  129. }
  130. }
  131. }
  132. func (a *salloc) Allocate(n node.Node, final bool) {
  133. mod := rtm.DomainModule(a.area.d)
  134. utils.PrintScope("ALLOCATE FOR", mod.Name, n.Adr())
  135. tl := mod.Types[n]
  136. skip := make(map[cp.ID]interface{}) //для процедурных типов в общей куче могут валяться переменные, скипаем их
  137. for _, t := range tl {
  138. switch x := t.(type) {
  139. case object.BasicType:
  140. for link := x.Link(); link != nil; link = link.Link() {
  141. skip[link.Adr()] = link
  142. }
  143. case object.RecordType:
  144. for link := x.Link(); link != nil; link = link.Link() {
  145. skip[link.Adr()] = link
  146. }
  147. }
  148. }
  149. nl := newlvl()
  150. nl.ready = final
  151. a.area.data = append(a.area.data, nl)
  152. nl.alloc(mod, n, mod.Objects[n], skip)
  153. }
  154. func (a *salloc) Dispose(n node.Node) {
  155. x := a.area.data
  156. a.area.data = nil
  157. for i := 0; i < len(x)-1; i++ {
  158. a.area.data = append(a.area.data, x[i])
  159. }
  160. }
  161. func (a *salloc) Initialize(n node.Node, par scope.PARAM) (seq frame.Sequence, ret frame.WAIT) {
  162. utils.PrintScope("INITIALIZE")
  163. l := a.area.top()
  164. assert.For(l != nil && !l.ready, 20)
  165. val := par.Values
  166. f := par.Frame
  167. end := func(frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
  168. l.ready = true
  169. if par.Tail != nil {
  170. return par.Tail(f)
  171. } else {
  172. return frame.End()
  173. }
  174. }
  175. seq = end
  176. ret = frame.NOW
  177. var sm scope.Manager
  178. for next := par.Objects; next != nil; next = next.Link() {
  179. global := f.Domain().Discover(context.UNIVERSE).(context.Domain)
  180. mod := rtm.ModuleOfNode(f.Domain(), val)
  181. if mod != nil {
  182. //fmt.Println(mod.Name)
  183. global = global.Discover(mod.Name).(context.Domain)
  184. sm = global.Discover(context.SCOPE).(scope.Manager)
  185. } else { //для фиктивных узлов, которые созданы рантаймом, типа INC/DEC
  186. sm = a.area
  187. }
  188. switch o := next.(type) {
  189. case object.VariableObject:
  190. switch nv := val.(type) {
  191. case node.ConstantNode:
  192. v := newConst(nv)
  193. l.v[l.k[o.Adr()]].Set(v)
  194. case node.VariableNode:
  195. v := sm.Select(nv.Object().Adr())
  196. l.v[l.k[o.Adr()]].Set(v)
  197. case node.FieldNode:
  198. nf := rt2.New(nv)
  199. rt2.Push(nf, f)
  200. rt2.Assert(f, func(f frame.Frame) (bool, int) {
  201. return rt2.ValueOf(f)[nv.Adr()] != nil, 60
  202. })
  203. rt2.ReplaceDomain(nf, global)
  204. seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
  205. v := rt2.ValueOf(f)[nv.Adr()]
  206. l.v[l.k[o.Adr()]].Set(v)
  207. return end, frame.NOW
  208. }
  209. ret = frame.LATER
  210. default:
  211. halt.As(40, reflect.TypeOf(nv))
  212. }
  213. case object.ParameterObject:
  214. switch nv := val.(type) {
  215. case node.VariableNode:
  216. old := l.r[l.k[o.Adr()]].(*ref)
  217. l.r[l.k[o.Adr()]] = &ref{link: old.link, sc: sm, id: nv.Object().Adr()}
  218. case node.ConstantNode: //array :) заменяем ссылку на переменную
  219. old := l.r[l.k[o.Adr()]].(*ref)
  220. l.r[l.k[o.Adr()]] = nil
  221. data := newConst(nv)
  222. switch data.(type) {
  223. case STRING, SHORTSTRING:
  224. val := &dynarr{link: old.link}
  225. val.Set(data)
  226. l.v[l.k[o.Adr()]] = val
  227. default:
  228. halt.As(100, reflect.TypeOf(data))
  229. }
  230. case node.DerefNode:
  231. rt2.Push(rt2.New(nv), f)
  232. rt2.Assert(f, func(f frame.Frame) (bool, int) {
  233. return rt2.ValueOf(f)[nv.Adr()] != nil, 60
  234. })
  235. dn := next
  236. old := l.r[l.k[dn.Adr()]].(*ref)
  237. seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
  238. switch dn.(type) {
  239. case object.VariableObject, object.ParameterObject:
  240. l.r[l.k[dn.Adr()]] = nil
  241. data := rt2.ValueOf(f)[nv.Adr()]
  242. switch deref := data.(type) {
  243. case STRING, SHORTSTRING:
  244. val := &dynarr{link: old.link}
  245. val.Set(deref)
  246. l.v[l.k[dn.Adr()]] = val
  247. case *rec:
  248. l.v[l.k[dn.Adr()]] = deref
  249. default:
  250. halt.As(100, reflect.TypeOf(data))
  251. }
  252. default:
  253. panic(fmt.Sprintln("unknown value", reflect.TypeOf(next)))
  254. }
  255. return end, frame.NOW
  256. }
  257. ret = frame.LATER
  258. default:
  259. halt.As(40, reflect.TypeOf(nv))
  260. }
  261. default:
  262. halt.As(40, reflect.TypeOf(o))
  263. }
  264. val = val.Link()
  265. }
  266. return seq, ret
  267. }
  268. func (a *salloc) Join(m scope.Manager) { a.area = m.(*area) }
  269. func (a *area) Update(id cp.ID, fval scope.ValueFor) {
  270. assert.For(id != 0, 20)
  271. var upd func(x int, id cp.ID)
  272. var k int
  273. upd = func(x int, id cp.ID) {
  274. utils.PrintScope("UPDATE", id)
  275. for i := x - 1; i >= 0 && k == 0; i-- {
  276. l := a.data[i]
  277. if l.ready {
  278. k = l.k[id]
  279. if k != 0 {
  280. v := a.data[i].v[k]
  281. if v == nil { //ref?
  282. r := l.r[k]
  283. if r != nil {
  284. utils.PrintScope("ref")
  285. if r.(*ref).sc == a {
  286. upd(i, r.(*ref).id)
  287. } else {
  288. k = -1
  289. r.(*ref).sc.Update(r.(*ref).id, fval)
  290. }
  291. break
  292. }
  293. } else {
  294. v.Set(fval(a.data[i].v[k]))
  295. }
  296. }
  297. }
  298. }
  299. }
  300. k = 0
  301. upd(len(a.data), id)
  302. assert.For(k != 0, 60)
  303. }
  304. func (a *area) Select(id cp.ID, val ...scope.ValueOf) (ret scope.Value) {
  305. var sel func(x int, id cp.ID)
  306. sel = func(x int, id cp.ID) {
  307. utils.PrintScope("SELECT", id)
  308. for i := x - 1; i >= 0 && ret == nil; i-- {
  309. l := a.data[i]
  310. k := 0
  311. if l.ready {
  312. k = l.k[id]
  313. if k != 0 {
  314. ret = l.v[k]
  315. if ret == nil { //ref?
  316. r := l.r[k]
  317. if r != nil {
  318. if l.l[k] != nil { //rec
  319. panic(0)
  320. } else {
  321. utils.PrintScope("ref")
  322. if r.(*ref).sc == a {
  323. sel(i, r.(*ref).id)
  324. } else {
  325. ret = r.(*ref).sc.Select(r.(*ref).id)
  326. }
  327. }
  328. break
  329. }
  330. } else if len(val) > 0 {
  331. val[0](ret)
  332. }
  333. }
  334. }
  335. }
  336. }
  337. sel(len(a.data), id)
  338. assert.For(ret != nil, 60)
  339. return ret
  340. }
  341. func (a *area) Target(all ...scope.Allocator) scope.Allocator {
  342. if len(all) > 0 {
  343. a.all = all[0]
  344. }
  345. if a.all == nil {
  346. return &salloc{area: a}
  347. } else {
  348. a.all.Join(a)
  349. return a.all
  350. }
  351. }
  352. func (a *area) String() (ret string) {
  353. for _, l := range a.data {
  354. ret = fmt.Sprintln(ret, l)
  355. }
  356. return ret
  357. }
  358. func (l *level) String() (ret string) {
  359. for k, v := range l.k {
  360. ret = fmt.Sprint(ret, "@", k, v, l.v[v])
  361. if l.v[v] == nil {
  362. ret = fmt.Sprintln(ret, l.r[v])
  363. } else if l.l[v] != nil {
  364. ret = fmt.Sprintln(ret, "{")
  365. ret = fmt.Sprintln(ret, l.l[v], "}")
  366. } else {
  367. ret = fmt.Sprintln(ret)
  368. }
  369. }
  370. return ret
  371. }
  372. func (a *area) Init(d context.Domain) { a.d = d }
  373. func (a *area) Domain() context.Domain { return a.d }
  374. func (a *area) Handle(msg interface{}) {}
  375. func fn(mgr scope.Manager, name string) (ret object.Object) {
  376. utils.PrintScope("FIND", name)
  377. a, ok := mgr.(*area)
  378. assert.For(ok, 20)
  379. assert.For(name != "", 21)
  380. for i := len(a.data) - 1; i >= 0 && ret == nil; i-- {
  381. l := a.data[i]
  382. for _, v := range l.v {
  383. switch vv := v.(type) {
  384. case *data:
  385. utils.PrintScope(vv.link.Name())
  386. if vv.link.Name() == name {
  387. ret = vv.link
  388. }
  389. default:
  390. utils.PrintScope(reflect.TypeOf(vv))
  391. }
  392. }
  393. }
  394. return ret
  395. }
  396. func nn(role string) scope.Manager {
  397. if role == context.SCOPE {
  398. return &area{all: &salloc{}}
  399. } else if role == context.HEAP {
  400. return &area{all: &halloc{}}
  401. } else {
  402. panic(0)
  403. }
  404. }
  405. func init() {
  406. scope.New = nn
  407. scope.FindObjByName = fn
  408. }