call.go 7.9 KB

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