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