stmt.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. package eval
  2. import (
  3. "fw/cp"
  4. "fw/cp/constant"
  5. "fw/cp/constant/enter"
  6. "fw/cp/constant/operation"
  7. "fw/cp/constant/statement"
  8. "fw/cp/node"
  9. "fw/cp/object"
  10. "fw/cp/traps"
  11. "fw/rt2"
  12. "fw/rt2/context"
  13. "fw/rt2/frame"
  14. rtm "fw/rt2/module"
  15. "fw/rt2/scope"
  16. "fw/utils"
  17. "log"
  18. "math/big"
  19. "reflect"
  20. "ypk/assert"
  21. "ypk/halt"
  22. )
  23. func makeTrap(f frame.Frame, err traps.TRAP) (out OUT) {
  24. trap := node.New(constant.TRAP, cp.Some()).(node.TrapNode)
  25. code := node.New(constant.CONSTANT, cp.Some()).(node.ConstantNode)
  26. code.SetType(object.INTEGER)
  27. code.SetData(int32(err))
  28. trap.SetLeft(code)
  29. rt2.Push(rt2.New(trap), f)
  30. return Later(Tail(STOP))
  31. }
  32. func doEnter(in IN) OUT {
  33. e := in.IR.(node.EnterNode)
  34. var next Do
  35. tail := func(IN) (out OUT) {
  36. body := in.IR.Right()
  37. switch {
  38. case body == nil:
  39. return End()
  40. case body != nil && in.Parent != nil:
  41. rt2.Push(rt2.New(body), in.Frame)
  42. return Later(Tail(STOP))
  43. case body != nil && in.Parent == nil: //секция BEGIN
  44. rt2.Push(rt2.New(body), in.Frame)
  45. end := in.IR.Link()
  46. if end != nil { //секция CLOSE
  47. out.Do = func(in IN) OUT {
  48. in.Frame.Root().PushFor(rt2.New(end), in.Frame)
  49. return OUT{Do: Tail(STOP), Next: LATER}
  50. }
  51. } else {
  52. out.Do = Tail(STOP)
  53. }
  54. out.Next = BEGIN
  55. }
  56. return
  57. }
  58. var sm scope.Manager
  59. switch e.Enter() {
  60. case enter.MODULE:
  61. sm = rt2.ModScope(in.Frame)
  62. case enter.PROCEDURE:
  63. sm = rt2.CallScope(in.Frame)
  64. }
  65. if e.Object() != nil { //параметры процедуры
  66. par, ok := rt2.RegOf(in.Frame)[e.Object()].(node.Node)
  67. //fmt.Println(rt2.DataOf(f)[n.Object()])
  68. //fmt.Println(ok)
  69. if ok {
  70. sm.Target().(scope.ScopeAllocator).Allocate(e, false)
  71. next = func(in IN) OUT {
  72. seq, _ := sm.Target().(scope.ScopeAllocator).Initialize(e,
  73. scope.PARAM{Objects: e.Object().Link(),
  74. Values: par,
  75. Frame: in.Frame,
  76. Tail: Propose(tail)})
  77. return Later(Expose(seq))
  78. }
  79. } else {
  80. sm.Target().(scope.ScopeAllocator).Allocate(e, true)
  81. next = tail
  82. }
  83. } else {
  84. sm.Target().(scope.ScopeAllocator).Allocate(in.IR, true)
  85. next = tail
  86. }
  87. return Now(next)
  88. }
  89. func inc_dec_seq(in IN, code operation.Operation) OUT {
  90. n := in.IR
  91. a := node.New(constant.ASSIGN, cp.Some()).(node.AssignNode)
  92. a.SetStatement(statement.ASSIGN)
  93. a.SetLeft(n.Left())
  94. op := node.New(constant.DYADIC, cp.Some()).(node.OperationNode)
  95. op.SetOperation(code)
  96. op.SetLeft(n.Left())
  97. op.SetRight(n.Right())
  98. a.SetRight(op)
  99. rt2.Push(rt2.New(a), in.Frame)
  100. /*seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
  101. sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
  102. sc.Update(n.Left().Object().Adr(), scope.Simple(rt2.ValueOf(f)[op.Adr()]))
  103. return frame.End()
  104. }
  105. ret = frame.LATER */
  106. return Later(Tail(STOP))
  107. }
  108. func doAssign(in IN) (out OUT) {
  109. const (
  110. right = "assign:right"
  111. left = "assign:left"
  112. )
  113. a := in.IR.(node.AssignNode)
  114. switch a.Statement() {
  115. case statement.ASSIGN:
  116. out = GetExpression(in, right, a.Right(), func(in IN) OUT {
  117. id := KeyOf(in, right)
  118. val := rt2.ValueOf(in.Frame)[id]
  119. assert.For(val != nil, 40, id)
  120. return GetDesignator(in, left, a.Left(), func(in IN) OUT {
  121. id := KeyOf(in, left)
  122. v, ok := rt2.ValueOf(in.Frame)[id].(scope.Variable)
  123. assert.For(ok, 41, reflect.TypeOf(v))
  124. v.Set(val)
  125. return End()
  126. })
  127. })
  128. case statement.INC, statement.INCL:
  129. switch a.Left().(type) {
  130. case node.VariableNode, node.ParameterNode, node.FieldNode:
  131. out = inc_dec_seq(in, operation.PLUS)
  132. default:
  133. halt.As(100, "wrong left", reflect.TypeOf(a.Left()))
  134. }
  135. case statement.DEC, statement.EXCL:
  136. switch a.Left().(type) {
  137. case node.VariableNode, node.ParameterNode, node.FieldNode:
  138. out = inc_dec_seq(in, operation.MINUS)
  139. default:
  140. halt.As(100, "wrong left", reflect.TypeOf(a.Left()))
  141. }
  142. case statement.NEW:
  143. heap := in.Frame.Domain().Discover(context.HEAP).(scope.Manager).Target().(scope.HeapAllocator)
  144. if a.Right() != nil {
  145. out = GetExpression(in, right, a.Right(), func(in IN) OUT {
  146. size := rt2.ValueOf(in.Frame)[KeyOf(in, right)]
  147. rt2.RegOf(in.Frame)[nullSafeFlag] = true
  148. return GetDesignator(in, left, a.Left(), func(in IN) OUT {
  149. v := rt2.ValueOf(in.Frame)[KeyOf(in, left)].(scope.Variable)
  150. _, c := scope.Ops.TypeOf(v)
  151. fn := heap.Allocate("new", c.(object.PointerType), size)
  152. v.Set(fn)
  153. return End()
  154. })
  155. })
  156. } else {
  157. out = GetDesignator(in, left, a.Left(), func(IN) OUT {
  158. v := rt2.ValueOf(in.Frame)[KeyOf(in, left)].(scope.Variable)
  159. _, c := scope.Ops.TypeOf(v)
  160. fn := heap.Allocate("new", c.(object.PointerType))
  161. v.Set(fn)
  162. return End()
  163. })
  164. }
  165. default:
  166. halt.As(100, "unsupported assign statement", a.Statement())
  167. }
  168. return
  169. }
  170. const ifCode = 1700
  171. func doIf(in IN) OUT {
  172. const left = "if:left:if"
  173. i := in.IR.(node.IfNode)
  174. return GetExpression(in, left, i.Left(), func(in IN) OUT {
  175. val := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
  176. assert.For(val != nil, 20)
  177. rt2.ValueOf(in.Parent)[i.Adr()] = val
  178. rt2.RegOf(in.Parent)[in.Key] = i.Adr()
  179. return End()
  180. })
  181. }
  182. func doCondition(in IN) OUT {
  183. const left = "if:left"
  184. i := in.IR.(node.ConditionalNode)
  185. rt2.RegOf(in.Frame)[ifCode] = i.Left() // if
  186. var next Do
  187. next = func(in IN) OUT {
  188. last := rt2.RegOf(in.Frame)[ifCode].(node.Node)
  189. fi := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
  190. done := scope.GoTypeFrom(fi).(bool)
  191. rt2.RegOf(in.Frame)[ifCode] = nil
  192. rt2.ValueOf(in.Frame)[KeyOf(in, left)] = nil
  193. if done && last.Right() != nil {
  194. rt2.Push(rt2.New(last.Right()), in.Frame)
  195. return Later(Tail(STOP))
  196. } else if last.Right() == nil {
  197. return End()
  198. } else if last.Link() != nil { //elsif
  199. rt2.RegOf(in.Frame)[ifCode] = last.Link()
  200. return GetStrange(in, left, last.Link(), next)
  201. } else if i.Right() != nil { //else
  202. rt2.Push(rt2.New(i.Right()), in.Frame)
  203. return Later(Tail(STOP))
  204. } else if i.Right() == nil {
  205. return End()
  206. } else if i.Right() == last {
  207. return End()
  208. } else {
  209. halt.As(100, "wrong if then else")
  210. panic(100)
  211. }
  212. }
  213. return GetStrange(in, left, i.Left(), next)
  214. }
  215. func doWhile(in IN) OUT {
  216. const left = "while:left"
  217. w := in.IR.(node.WhileNode)
  218. var next Do
  219. next = func(IN) OUT {
  220. key := KeyOf(in, left)
  221. fi := rt2.ValueOf(in.Frame)[key]
  222. rt2.ValueOf(in.Frame)[key] = nil
  223. done := scope.GoTypeFrom(fi).(bool)
  224. if done && w.Right() != nil {
  225. rt2.Push(rt2.New(w.Right()), in.Frame)
  226. return Later(func(IN) OUT { return GetExpression(in, left, w.Left(), next) })
  227. } else if !done {
  228. return End()
  229. } else if w.Right() == nil {
  230. return End()
  231. } else {
  232. panic("unexpected while seq")
  233. }
  234. }
  235. return GetExpression(in, left, w.Left(), next)
  236. }
  237. const exitFlag = 1812
  238. func doExit(in IN) OUT {
  239. in.Frame.Root().ForEach(func(f frame.Frame) (ok bool) {
  240. n := rt2.NodeOf(f)
  241. _, ok = n.(node.LoopNode)
  242. if ok {
  243. rt2.RegOf(f)[exitFlag] = true
  244. }
  245. ok = !ok
  246. return ok
  247. })
  248. return End()
  249. }
  250. func doLoop(in IN) OUT {
  251. l := in.IR.(node.LoopNode)
  252. exit, ok := rt2.RegOf(in.Frame)[exitFlag].(bool)
  253. if ok && exit {
  254. return End()
  255. }
  256. if l.Left() != nil {
  257. rt2.Push(rt2.New(l.Left()), in.Frame)
  258. return Later(doLoop)
  259. } else if l.Left() == nil {
  260. return End()
  261. } else {
  262. panic("unexpected loop seq")
  263. }
  264. }
  265. func doRepeat(in IN) OUT {
  266. const right = "return:right"
  267. r := in.IR.(node.RepeatNode)
  268. rt2.ValueOf(in.Frame)[r.Right().Adr()] = scope.TypeFromGo(false)
  269. var next Do
  270. next = func(in IN) OUT {
  271. fi := rt2.ValueOf(in.Frame)[r.Right().Adr()]
  272. done := scope.GoTypeFrom(fi).(bool)
  273. if !done && r.Left() != nil {
  274. rt2.Push(rt2.New(r.Left()), in.Frame)
  275. return Later(func(IN) OUT { return GetExpression(in, right, r.Right(), next) })
  276. } else if done {
  277. return End()
  278. } else if r.Left() == nil {
  279. return End()
  280. } else {
  281. panic("unexpected repeat seq")
  282. }
  283. }
  284. return Now(next)
  285. }
  286. func doTrap(in IN) OUT {
  287. const left = "trap:left"
  288. return GetExpression(in, left, in.IR.Left(), func(IN) OUT {
  289. val := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
  290. log.Println("TRAP:", traps.This(scope.GoTypeFrom(val)))
  291. in.Frame.Root().ForEach(func(x frame.Frame) (do bool) {
  292. n := rt2.NodeOf(x)
  293. if n != nil {
  294. log.Println(reflect.TypeOf(n), n.Adr())
  295. } else {
  296. log.Println(reflect.TypeOf(x))
  297. }
  298. return true
  299. })
  300. return Now(Tail(WRONG))
  301. })
  302. }
  303. func doReturn(in IN) OUT {
  304. const left = "return:left"
  305. r := in.IR.(node.ReturnNode)
  306. return GetExpression(in, left, r.Left(), func(IN) OUT {
  307. val := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
  308. if val == nil {
  309. val, _ = rt2.RegOf(in.Frame)[context.RETURN].(scope.Value)
  310. }
  311. assert.For(val != nil, 40)
  312. in.Frame.Root().ForEach(func(f frame.Frame) bool {
  313. n := rt2.NodeOf(f)
  314. _, done := n.(node.EnterNode)
  315. if done {
  316. rt2.ValueOf(f)[r.Object().Adr()] = val
  317. rt2.RegOf(f)[context.RETURN] = val
  318. }
  319. return !done
  320. })
  321. return End()
  322. })
  323. }
  324. func doCall(in IN) (out OUT) {
  325. const (
  326. right = "call:right"
  327. )
  328. c := in.IR.(node.CallNode)
  329. call := func(proc node.Node, d context.Domain) {
  330. _, ok := proc.(node.EnterNode)
  331. assert.For(ok, 20, "try call", reflect.TypeOf(proc), proc.Adr(), proc.Object().Adr())
  332. nf := rt2.New(proc)
  333. rt2.Push(nf, in.Frame)
  334. if d != nil {
  335. rt2.ReplaceDomain(nf, d)
  336. }
  337. //передаем ссылку на цепочку значений параметров в данные фрейма входа в процедуру
  338. if (c.Right() != nil) && (proc.Object() != nil) {
  339. rt2.RegOf(nf)[proc.Object()] = c.Right()
  340. } else {
  341. //fmt.Println("no data for call")
  342. }
  343. out = Later(func(in IN) OUT {
  344. if in.Key != nil {
  345. val := rt2.ValueOf(in.Frame)[c.Left().Object().Adr(0, 0)]
  346. if val == nil {
  347. if rv, _ := rt2.RegOf(in.Frame)[context.RETURN].(scope.Value); rv != nil {
  348. val = rv
  349. }
  350. }
  351. if val != nil {
  352. id := cp.ID(cp.Some())
  353. rt2.ValueOf(in.Parent)[id] = val
  354. rt2.RegOf(in.Parent)[in.Key] = id
  355. } else {
  356. utils.PrintFrame("possibly no return", in.Key, rt2.RegOf(in.Frame), rt2.ValueOf(in.Frame), rt2.RegOf(in.Parent), rt2.ValueOf(in.Parent))
  357. }
  358. }
  359. return End()
  360. })
  361. }
  362. switch p := c.Left().(type) {
  363. case node.EnterNode:
  364. call(p, nil)
  365. case node.ProcedureNode:
  366. //m := rtm.DomainModule(in.Frame.Domain())
  367. ml := in.Frame.Domain().Global().Discover(context.MOD).(rtm.List)
  368. switch p.Object().Mode() {
  369. case object.LOCAL_PROC, object.EXTERNAL_PROC:
  370. if imp := p.Object().Imp(); imp == "" {
  371. m := rtm.ModuleOfObject(in.Frame.Domain(), p.Object())
  372. proc := m.NodeByObject(p.Object())
  373. assert.For(proc != nil, 40, m.Name, imp, p.Object().Imp(), p.Object().Adr(0, 0), p.Object().Name())
  374. call(proc[0], nil)
  375. } else {
  376. m := ml.Loaded(imp)
  377. pl := m.ObjectByName(m.Enter, c.Left().Object().Name())
  378. var proc object.ProcedureObject
  379. var nl []node.Node
  380. for _, n := range pl {
  381. if n.Mode() == p.Object().Mode() {
  382. proc = n.(object.ProcedureObject)
  383. }
  384. }
  385. nl = m.NodeByObject(proc)
  386. utils.PrintFrame("foreign call", len(nl), "proc refs", proc)
  387. call(nl[0], in.Frame.Domain().Global().Discover(imp).(context.Domain))
  388. }
  389. case object.TYPE_PROC:
  390. //sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
  391. out = GetExpression(in, right, c.Right(), func(IN) (out OUT) {
  392. var (
  393. proc []node.Node
  394. dm context.Domain
  395. )
  396. id := KeyOf(in, right)
  397. v := rt2.ValueOf(in.Frame)[id]
  398. t, ct := scope.Ops.TypeOf(v)
  399. if ct == nil {
  400. return makeTrap(in.Frame, traps.Default)
  401. }
  402. assert.For(ct != nil, 40, id, v, t)
  403. x := ml.NewTypeCalc()
  404. x.ConnectTo(ct)
  405. sup := p.Super()
  406. for _, ml := range x.MethodList() {
  407. for _, m := range ml {
  408. //fmt.Println(m.Obj.Name(), m.Obj.Adr())
  409. if m.Obj.Name() == p.Object().Name() {
  410. if !sup {
  411. proc = append(proc, m.Enter)
  412. break
  413. } else {
  414. sup = false //супервызов должен быть вторым методом с тем же именем
  415. }
  416. dm = in.Frame.Domain().Global().Discover(m.Mod.Name).(context.Domain)
  417. }
  418. }
  419. if len(proc) > 0 {
  420. break
  421. }
  422. }
  423. assert.For(len(proc) > 0, 40, p.Object().Name())
  424. call(proc[0], dm)
  425. out = Later(Tail(STOP))
  426. return
  427. })
  428. default:
  429. halt.As(100, "wrong proc mode ", p.Object().Mode(), p.Object().Adr(), p.Object().Name())
  430. }
  431. case node.VariableNode:
  432. m := rtm.DomainModule(in.Frame.Domain())
  433. sc := rt2.ScopeFor(in.Frame, p.Object().Adr())
  434. var obj interface{}
  435. sc.Select(p.Object().Adr(), func(in scope.Value) {
  436. obj = scope.GoTypeFrom(in)
  437. })
  438. if obj, ok := obj.(object.Object); ok {
  439. proc := m.NodeByObject(obj)
  440. call(proc[0], nil)
  441. } else {
  442. name := p.Object().Name()
  443. switch {
  444. case sys[name] != nil:
  445. return syscall(in)
  446. default:
  447. halt.As(100, "unknown sysproc variable", name)
  448. }
  449. }
  450. default:
  451. halt.As(100, reflect.TypeOf(p))
  452. }
  453. return
  454. }
  455. const isFlag = 1700
  456. func doWith(in IN) OUT {
  457. const left = "with:left"
  458. w := in.IR.(node.WithNode)
  459. f := in.Frame
  460. rt2.RegOf(f)[isFlag] = w.Left() //if
  461. var seq Do
  462. seq = func(in IN) OUT {
  463. last := rt2.RegOf(f)[isFlag].(node.Node)
  464. id := KeyOf(in, left)
  465. v := rt2.ValueOf(f)[id]
  466. assert.For(v != nil, 40)
  467. done := scope.GoTypeFrom(v).(bool)
  468. rt2.ValueOf(f)[id] = nil
  469. if done && last.Right() != nil {
  470. rt2.Push(rt2.New(last.Right()), f)
  471. return Later(Tail(STOP))
  472. } else if last.Right() == nil {
  473. return End()
  474. } else if last.Link() != nil { //elsif
  475. rt2.RegOf(f)[isFlag] = last.Link()
  476. return Later(func(IN) OUT { return GetStrange(in, left, last.Link(), seq) })
  477. } else if w.Right() != nil { //else
  478. rt2.Push(rt2.New(w.Right()), f)
  479. return Later(Tail(STOP))
  480. } else if w.Right() == nil {
  481. return End()
  482. } else if last == w.Right() {
  483. return End()
  484. } else {
  485. panic("conditional sequence wrong")
  486. }
  487. }
  488. return GetStrange(in, left, w.Left(), seq)
  489. }
  490. func int32Of(x interface{}) (a int32) {
  491. //fmt.Println(reflect.TypeOf(x))
  492. switch v := x.(type) {
  493. case *int32:
  494. z := *x.(*int32)
  495. a = z
  496. case int32:
  497. a = x.(int32)
  498. case *big.Int:
  499. a = int32(v.Int64())
  500. default:
  501. //panic(fmt.Sprintln("unsupported type", reflect.TypeOf(x)))
  502. }
  503. return a
  504. }
  505. func doCase(in IN) OUT {
  506. const left = "case:left"
  507. c := in.IR.(node.CaseNode)
  508. var e int
  509. do := func(in IN) (out OUT) {
  510. cond := c.Right().(node.ElseNode)
  511. //fmt.Println("case?", e, cond.Min(), cond.Max())
  512. if e < cond.Min() || e > cond.Max() { //case?
  513. if cond.Right() != nil {
  514. rt2.Push(rt2.New(cond.Right()), in.Frame)
  515. }
  516. out.Do = Tail(STOP)
  517. out.Next = LATER
  518. } else {
  519. for next := cond.Left(); next != nil && out.Do == nil; next = next.Link() {
  520. var ok bool
  521. // _c := next.Left()
  522. for _c := next.Left(); _c != nil && !ok; _c = _c.Link() {
  523. c := _c.(node.ConstantNode)
  524. //fmt.Println("const", c.Data(), c.Min(), c.Max())
  525. if (c.Min() != nil) && (c.Max() != nil) {
  526. //fmt.Println(e, *c.Max(), "..", *c.Min())
  527. ok = e >= *c.Min() && e <= *c.Max()
  528. } else {
  529. //fmt.Println(e, c.Data())
  530. ok = int32Of(c.Data()) == int32(e)
  531. }
  532. }
  533. //fmt.Println(ok)
  534. if ok {
  535. rt2.Push(rt2.New(next.Right()), in.Frame)
  536. out.Do = Tail(STOP)
  537. out.Next = LATER
  538. }
  539. }
  540. if out.Do == nil && cond.Right() != nil {
  541. rt2.Push(rt2.New(cond.Right()), in.Frame)
  542. out.Do = Tail(STOP)
  543. out.Next = LATER
  544. }
  545. }
  546. assert.For(out.Do != nil, 60)
  547. return out
  548. }
  549. return GetExpression(in, left, c.Left(), func(IN) (out OUT) {
  550. v := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
  551. _x := scope.GoTypeFrom(v)
  552. switch x := _x.(type) {
  553. case nil:
  554. panic("nil")
  555. case int32:
  556. e = int(x)
  557. //fmt.Println("case", e)
  558. out.Do = do
  559. out.Next = NOW
  560. return out
  561. default:
  562. halt.As(100, "unsupported case expr", reflect.TypeOf(_x))
  563. }
  564. panic(0)
  565. })
  566. }