call.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package rules
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "fw/cp"
  6. "fw/cp/constant"
  7. "fw/cp/node"
  8. "fw/cp/object"
  9. "fw/rt2"
  10. "fw/rt2/context"
  11. "fw/rt2/frame"
  12. rt_mod "fw/rt2/module"
  13. "fw/rt2/scope"
  14. "fw/utils"
  15. "reflect"
  16. "ypk/assert"
  17. "ypk/halt"
  18. )
  19. /**
  20. Для CallNode
  21. .Left() указывает на процедуру или на переменную процедурного типа
  22. .Left().Object() указывает на список внутренних объектов, в т.ч. переменных
  23. .Object() указывает первый элемент из списка входных параметров/переменных,
  24. то же что и.Left().Object().Link(), далее .Link() указывает на следующие за ним входные параметры
  25. .Right() указывает на узлы, которые передаются в параметры
  26. */
  27. var sys map[string]func(f frame.Frame, par node.Node) (frame.Sequence, frame.WAIT)
  28. type Msg struct {
  29. Type string
  30. Data string
  31. }
  32. func callHandler(f frame.Frame, obj object.Object, data interface{}) {
  33. //n := rt2.Utils.NodeOf(f)
  34. //fmt.Println("call handler", obj)
  35. if obj == nil {
  36. return
  37. }
  38. m := rt_mod.DomainModule(f.Domain())
  39. cn := node.New(constant.CALL, int(cp.SomeAdr()))
  40. ol := m.NodeByObject(obj)
  41. assert.For(len(ol) <= 1, 40)
  42. cn.SetLeft(ol[0])
  43. cc := node.New(constant.CONSTANT, int(cp.SomeAdr())).(node.ConstantNode)
  44. cc.SetData(data)
  45. cc.SetType(object.SHORTSTRING)
  46. cn.SetRight(cc)
  47. rt2.Push(rt2.New(cn), f)
  48. }
  49. func process(f frame.Frame, par node.Node) (frame.Sequence, frame.WAIT) {
  50. assert.For(par != nil, 20)
  51. sm := f.Domain().Discover(context.SCOPE).(scope.Manager)
  52. do := func(val string) {
  53. if val != "" {
  54. msg := &Msg{}
  55. if err := json.Unmarshal([]byte(val), msg); err == nil {
  56. switch msg.Type {
  57. case "log":
  58. fmt.Println(msg.Data)
  59. callHandler(f, scope.FindObjByName(sm, "go_handler"), `{"type":"log"}`)
  60. default:
  61. panic(40)
  62. }
  63. } else {
  64. fmt.Println(val, "not a json")
  65. }
  66. }
  67. }
  68. var val string
  69. switch p := par.(type) {
  70. case node.ConstantNode:
  71. val = par.(node.ConstantNode).Data().(string)
  72. do(val)
  73. return frame.Tail(frame.STOP), frame.LATER
  74. case node.VariableNode, node.ParameterNode:
  75. val = scope.GoTypeFrom(sm.Select(p.Object().Adr())).(string)
  76. do(val)
  77. return frame.Tail(frame.STOP), frame.LATER
  78. case node.DerefNode:
  79. rt2.Push(rt2.New(p), f)
  80. return This(expectExpr(f, p, func(...IN) (out OUT) {
  81. v := rt2.ValueOf(f)[p.Adr()]
  82. assert.For(v != nil, 60)
  83. val = scope.GoTypeFrom(v).(string)
  84. do(val)
  85. out.do = Tail(STOP)
  86. out.next = LATER
  87. return out
  88. }))
  89. default:
  90. halt.As(100, "unsupported param", reflect.TypeOf(p))
  91. }
  92. panic(0)
  93. }
  94. func init() {
  95. sys = make(map[string]func(f frame.Frame, par node.Node) (frame.Sequence, frame.WAIT))
  96. sys["go_process"] = process
  97. }
  98. func syscall(f frame.Frame) (frame.Sequence, frame.WAIT) {
  99. n := rt2.NodeOf(f)
  100. name := n.Left().Object().Name()
  101. return sys[name](f, n.Right())
  102. }
  103. func callSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
  104. n := rt2.NodeOf(f)
  105. call := func(proc node.Node, d context.Domain) {
  106. nf := rt2.New(proc)
  107. rt2.Push(nf, f)
  108. if d != nil {
  109. rt2.ReplaceDomain(nf, d)
  110. }
  111. //передаем ссылку на цепочку значений параметров в данные фрейма входа в процедуру
  112. if (n.Right() != nil) && (proc.Object() != nil) {
  113. rt2.RegOf(nf)[proc.Object()] = n.Right()
  114. } else {
  115. //fmt.Println("no data for call")
  116. }
  117. seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
  118. // rt2.DataOf(f.Parent())[n] = rt2.DataOf(f)[n.Left().Object()]
  119. rt2.ValueOf(f.Parent())[n.Adr()] = rt2.ValueOf(f)[n.Left().Object().Adr()]
  120. return frame.End()
  121. }
  122. ret = frame.LATER
  123. }
  124. switch p := n.Left().(type) {
  125. case node.ProcedureNode:
  126. m := rt_mod.DomainModule(f.Domain())
  127. ml := f.Domain().Discover(context.UNIVERSE).(context.Domain).Discover(context.MOD).(rt_mod.List)
  128. if p.Super() {
  129. fmt.Println("supercall, stop for now")
  130. seq = Propose(Tail(STOP))
  131. ret = frame.NOW
  132. } else {
  133. if imp := m.ImportOf(n.Left().Object()); imp == "" {
  134. proc := m.NodeByObject(n.Left().Object())
  135. fmt.Println(len(proc), len(n.Left().Object().Ref()))
  136. call(proc[0], nil)
  137. } else {
  138. m := ml.Loaded(imp)
  139. proc := m.ObjectByName(m.Enter, n.Left().Object().Name())
  140. nl := m.NodeByObject(proc)
  141. utils.PrintFrame("foreign call", len(nl))
  142. call(nl[0], f.Domain().Discover(context.UNIVERSE).(context.Domain).Discover(imp).(context.Domain))
  143. }
  144. }
  145. case node.VariableNode:
  146. m := rt_mod.DomainModule(f.Domain())
  147. sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
  148. obj := scope.GoTypeFrom(sc.Select(n.Left().Object().Adr()))
  149. if obj, ok := obj.(object.Object); ok {
  150. proc := m.NodeByObject(obj)
  151. call(proc[0], nil)
  152. } else {
  153. name := n.Left().Object().Name()
  154. switch {
  155. case name == "go_process":
  156. return syscall(f)
  157. default:
  158. panic(fmt.Sprintln("unknown sysproc variable", name))
  159. }
  160. }
  161. default:
  162. panic("unknown call left")
  163. }
  164. return seq, ret
  165. }