if.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package rules
  2. import (
  3. "fw/cp/node"
  4. "fw/rt2"
  5. "fw/rt2/frame"
  6. "fw/rt2/scope"
  7. "reflect"
  8. "ypk/halt"
  9. )
  10. func ifExpr(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
  11. n := rt2.NodeOf(f)
  12. switch l := n.Left().(type) {
  13. case node.OperationNode:
  14. rt2.Push(rt2.New(n.Left()), f)
  15. seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
  16. rt2.RegOf(f.Parent())[n] = rt2.RegOf(f)[n.Left()]
  17. rt2.ValueOf(f.Parent())[n.Adr()] = rt2.ValueOf(f)[n.Left().Adr()]
  18. return frame.End()
  19. }
  20. ret = frame.LATER
  21. case node.ConstantNode, node.VariableNode, node.ParameterNode, node.FieldNode:
  22. return This(expectExpr(f, l, func(...IN) OUT {
  23. rt2.ValueOf(f.Parent())[n.Adr()] = rt2.ValueOf(f)[l.Adr()]
  24. return End()
  25. }))
  26. default:
  27. halt.As(100, reflect.TypeOf(l))
  28. }
  29. return seq, ret
  30. }
  31. func ifSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
  32. n := rt2.NodeOf(f)
  33. rt2.RegOf(f)[0] = n.Left() //if
  34. rt2.Push(rt2.New(n.Left()), f)
  35. rt2.Assert(f, func(f frame.Frame) (bool, int) {
  36. return rt2.ValueOf(f)[n.Left().Adr()] != nil, 60
  37. })
  38. seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
  39. last := rt2.RegOf(f)[0].(node.Node)
  40. done := scope.GoTypeFrom(rt2.ValueOf(f)[last.Adr()]).(bool)
  41. rt2.RegOf(f)[last] = nil
  42. if done && last.Right() != nil {
  43. rt2.Push(rt2.New(last.Right()), f)
  44. return frame.Tail(frame.STOP), frame.LATER
  45. } else if last.Right() == nil {
  46. return frame.End()
  47. } else if last.Link() != nil { //elsif
  48. rt2.RegOf(f)[0] = last.Link()
  49. rt2.Push(rt2.New(last.Link()), f)
  50. rt2.Assert(f, func(f frame.Frame) (bool, int) {
  51. return rt2.ValueOf(f)[last.Link().Adr()] != nil, 61
  52. })
  53. return seq, frame.LATER
  54. } else if n.Right() != nil { //else
  55. rt2.Push(rt2.New(n.Right()), f)
  56. return frame.Tail(frame.STOP), frame.LATER
  57. } else if n.Right() == nil {
  58. return frame.End()
  59. } else if last == n.Right() {
  60. return frame.End()
  61. } else {
  62. panic("conditional sequence wrong")
  63. }
  64. }
  65. return seq, frame.LATER
  66. }