call.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. package rules
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "fw/cp"
  6. "fw/cp/constant"
  7. cpm "fw/cp/module"
  8. "fw/cp/node"
  9. "fw/cp/object"
  10. "fw/rt2"
  11. "fw/rt2/context"
  12. "fw/rt2/frame"
  13. rtm "fw/rt2/module"
  14. "fw/rt2/scope"
  15. "fw/utils"
  16. "reflect"
  17. "ypk/assert"
  18. "ypk/halt"
  19. )
  20. /**
  21. Для CallNode
  22. .Left() указывает на процедуру или на переменную процедурного типа
  23. .Left().Object() указывает на список внутренних объектов, в т.ч. переменных
  24. .Object() указывает первый элемент из списка входных параметров/переменных,
  25. то же что и.Left().Object().Link(), далее .Link() указывает на следующие за ним входные параметры
  26. .Right() указывает на узлы, которые передаются в параметры
  27. */
  28. var sys map[string]func(f frame.Frame, par node.Node) (frame.Sequence, frame.WAIT)
  29. type Msg struct {
  30. Type string
  31. Command string
  32. Data string
  33. }
  34. func callHandler(f frame.Frame, obj object.Object, data interface{}) {
  35. //n := rt2.Utils.NodeOf(f)
  36. //fmt.Println("call handler", obj)
  37. if obj == nil {
  38. return
  39. }
  40. m := rtm.DomainModule(f.Domain())
  41. cn := node.New(constant.CALL, int(cp.SomeAdr()))
  42. ol := m.NodeByObject(obj)
  43. assert.For(len(ol) <= 1, 40)
  44. cn.SetLeft(ol[0])
  45. cc := node.New(constant.CONSTANT, int(cp.SomeAdr())).(node.ConstantNode)
  46. cc.SetData(data)
  47. cc.SetType(object.SHORTSTRING)
  48. cn.SetRight(cc)
  49. rt2.Push(rt2.New(cn), f)
  50. }
  51. func process(f frame.Frame, par node.Node) (frame.Sequence, frame.WAIT) {
  52. assert.For(par != nil, 20)
  53. sm := f.Domain().Discover(context.SCOPE).(scope.Manager)
  54. do := func(val string) {
  55. if val != "" {
  56. msg := &Msg{}
  57. if err := json.Unmarshal([]byte(val), msg); err == nil {
  58. switch msg.Type {
  59. case "log":
  60. fmt.Print(msg.Data)
  61. callHandler(f, scope.FindObjByName(sm, "go_handler"), `{"type":"log"}`)
  62. case "core":
  63. switch msg.Command {
  64. case "load":
  65. //fmt.Println("try to load", msg.Data)
  66. glob := f.Domain().Discover(context.UNIVERSE).(context.Domain)
  67. modList := glob.Discover(context.MOD).(rtm.List)
  68. fl := glob.Discover(context.MT).(*flow)
  69. _, err := modList.Load(msg.Data, func(m *cpm.Module) {
  70. fl.grow(glob, m)
  71. })
  72. assert.For(err == nil, 60)
  73. default:
  74. halt.As(100, msg.Command)
  75. }
  76. default:
  77. panic(40)
  78. }
  79. } else {
  80. fmt.Println(val, "not a json")
  81. }
  82. }
  83. }
  84. var val string
  85. switch p := par.(type) {
  86. case node.ConstantNode:
  87. val = par.(node.ConstantNode).Data().(string)
  88. do(val)
  89. return frame.Tail(frame.STOP), frame.LATER
  90. case node.VariableNode, node.ParameterNode:
  91. val = scope.GoTypeFrom(sm.Select(p.Object().Adr())).(string)
  92. do(val)
  93. return frame.Tail(frame.STOP), frame.LATER
  94. case node.DerefNode:
  95. rt2.Push(rt2.New(p), f)
  96. return This(expectExpr(f, p, func(...IN) (out OUT) {
  97. v := rt2.ValueOf(f)[p.Adr()]
  98. assert.For(v != nil, 60)
  99. val = scope.GoTypeFrom(v).(string)
  100. do(val)
  101. out.do = Tail(STOP)
  102. out.next = LATER
  103. return out
  104. }))
  105. default:
  106. halt.As(100, "unsupported param", reflect.TypeOf(p))
  107. }
  108. panic(0)
  109. }
  110. func init() {
  111. sys = make(map[string]func(f frame.Frame, par node.Node) (frame.Sequence, frame.WAIT))
  112. sys["go_process"] = process
  113. }
  114. func syscall(f frame.Frame) (frame.Sequence, frame.WAIT) {
  115. n := rt2.NodeOf(f)
  116. name := n.Left().Object().Name()
  117. return sys[name](f, n.Right())
  118. }
  119. func callSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
  120. n := rt2.NodeOf(f)
  121. call := func(proc node.Node, d context.Domain) {
  122. nf := rt2.New(proc)
  123. rt2.Push(nf, f)
  124. if d != nil {
  125. rt2.ReplaceDomain(nf, d)
  126. }
  127. //передаем ссылку на цепочку значений параметров в данные фрейма входа в процедуру
  128. if (n.Right() != nil) && (proc.Object() != nil) {
  129. rt2.RegOf(nf)[proc.Object()] = n.Right()
  130. } else {
  131. //fmt.Println("no data for call")
  132. }
  133. seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
  134. // rt2.DataOf(f.Parent())[n] = rt2.DataOf(f)[n.Left().Object()]
  135. if f.Parent() != nil {
  136. rt2.ValueOf(f.Parent())[n.Adr()] = rt2.ValueOf(f)[n.Left().Object().Adr()]
  137. }
  138. return frame.End()
  139. }
  140. ret = frame.LATER
  141. }
  142. switch p := n.Left().(type) {
  143. case node.EnterNode:
  144. call(p, nil)
  145. case node.ProcedureNode:
  146. m := rtm.DomainModule(f.Domain())
  147. ml := f.Domain().Discover(context.UNIVERSE).(context.Domain).Discover(context.MOD).(rtm.List)
  148. if p.Super() {
  149. fmt.Println("supercall, stop for now")
  150. seq = Propose(Tail(STOP))
  151. ret = frame.NOW
  152. } else {
  153. if imp := m.ImportOf(n.Left().Object()); imp == "" || imp == m.Name {
  154. switch p.Object().Mode() {
  155. case object.LOCAL_PROC, object.EXTERNAL_PROC:
  156. proc := m.NodeByObject(n.Left().Object())
  157. assert.For(proc != nil, 40)
  158. call(proc[0], nil)
  159. case object.TYPE_PROC:
  160. var proc []node.Node
  161. //sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
  162. return This(expectExpr(f, n.Right(), func(...IN) (out OUT) {
  163. v := rt2.ValueOf(f)[n.Right().Adr()]
  164. var dm context.Domain
  165. var fn object.ProcedureObject
  166. _, c := scope.Ops.TypeOf(v)
  167. mod := rtm.ModuleOfType(f.Domain(), c)
  168. dm = f.Domain().Discover(context.UNIVERSE).(context.Domain).Discover(mod.Name).(context.Domain)
  169. ol := mod.Objects[mod.Enter]
  170. for _, _po := range ol {
  171. switch po := _po.(type) {
  172. case object.ProcedureObject:
  173. if po.Name() == p.Object().Name() && po.Link() != nil && po.Link().Complex() == c {
  174. fn = po
  175. }
  176. }
  177. }
  178. assert.For(fn != nil, 40)
  179. proc = mod.NodeByObject(fn)
  180. assert.For(proc != nil, 40)
  181. call(proc[0], dm)
  182. out.do = Tail(STOP)
  183. out.next = LATER
  184. return out
  185. }))
  186. default:
  187. halt.As(100, "wrong proc mode ", p.Object().Mode())
  188. }
  189. //fmt.Println(len(proc), len(n.Left().Object().Ref()))
  190. //fmt.Println("proc refs", proc)
  191. } else {
  192. m := ml.Loaded(imp)
  193. pl := m.ObjectByName(m.Enter, n.Left().Object().Name())
  194. var proc object.ProcedureObject
  195. var nl []node.Node
  196. for _, n := range pl {
  197. if n.Mode() == p.Object().Mode() {
  198. proc = n.(object.ProcedureObject)
  199. }
  200. }
  201. //utils.PrintFrame("proc refs", len(proc))
  202. switch proc.Mode() {
  203. case object.LOCAL_PROC, object.EXTERNAL_PROC:
  204. nl = m.NodeByObject(proc)
  205. utils.PrintFrame("foreign call", len(nl), "proc refs", proc)
  206. call(nl[0], f.Domain().Discover(context.UNIVERSE).(context.Domain).Discover(imp).(context.Domain))
  207. default:
  208. halt.As(100, "wrong proc mode ", p.Object().Mode())
  209. }
  210. }
  211. }
  212. case node.VariableNode:
  213. m := rtm.DomainModule(f.Domain())
  214. sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
  215. obj := scope.GoTypeFrom(sc.Select(n.Left().Object().Adr()))
  216. if obj, ok := obj.(object.Object); ok {
  217. proc := m.NodeByObject(obj)
  218. call(proc[0], nil)
  219. } else {
  220. name := n.Left().Object().Name()
  221. switch {
  222. case name == "go_process":
  223. return syscall(f)
  224. default:
  225. panic(fmt.Sprintln("unknown sysproc variable", name))
  226. }
  227. }
  228. default:
  229. halt.As(100, "unknown call left: ", reflect.TypeOf(p))
  230. }
  231. return seq, ret
  232. }