inferring.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package typsys
  2. import "kumachan/standalone/ctn"
  3. func Match(x Type, y Type, s *InferringState) (bool, *InferringState) {
  4. if x == nil || y == nil {
  5. panic("something went wrong")
  6. }
  7. if s != nil {
  8. var X, to_inferring = x.(InferringType)
  9. var Y, from_inferring = y.(InferringType)
  10. var inferring string
  11. var certain Type
  12. var ok = false
  13. if to_inferring && IsCertain(y) {
  14. inferring = X.Id
  15. certain = y
  16. ok = true
  17. }
  18. if IsCertain(x) && from_inferring {
  19. inferring = Y.Id
  20. certain = x
  21. ok = true
  22. }
  23. if ok {
  24. var inferred, exists = s.getInferred(inferring)
  25. if exists {
  26. if Equal(certain, inferred) {
  27. return true, s
  28. } else {
  29. return false, nil
  30. }
  31. } else {
  32. return true, s.newStateSetInferred(inferring, certain)
  33. }
  34. }
  35. }
  36. switch X := x.(type) {
  37. case InferringType:
  38. if Y, ok := y.(InferringType); ok {
  39. return (X.Id == Y.Id), s
  40. }
  41. case ParameterType:
  42. if Y, ok := y.(ParameterType); ok {
  43. return (X.Name == Y.Name), s
  44. }
  45. case RefType:
  46. if Y, ok := y.(RefType); ok {
  47. if (X.Def == Y.Def) {
  48. if len(X.Args) == len(Y.Args) {
  49. var n = len(X.Args)
  50. var all_assignable = true
  51. for i := 0; i < n; i += 1 {
  52. var assignable, s1 = Match(X.Args[i], Y.Args[i], s)
  53. if assignable {
  54. s = s1
  55. } else {
  56. all_assignable = false
  57. break
  58. }
  59. }
  60. if all_assignable {
  61. return true, s
  62. }
  63. }
  64. }
  65. }
  66. }
  67. return false, nil
  68. }
  69. func MatchAll(x ([] Type), y ([] Type), s *InferringState) (bool, *InferringState) {
  70. if len(x) != len(y) {
  71. return false, nil
  72. }
  73. var L = len(x)
  74. for i := 0; i < L; i += 1 {
  75. var ok, s1 = Match(x[i], y[i], s)
  76. if ok {
  77. s = s1
  78. } else {
  79. return false, nil
  80. }
  81. }
  82. return true, s
  83. }
  84. func IsCertain(t Type) bool {
  85. switch T := t.(type) {
  86. case InferringType:
  87. return false
  88. case RefType:
  89. for _, arg := range T.Args {
  90. if !(IsCertain(arg)) {
  91. return false
  92. }
  93. }
  94. }
  95. return true
  96. }
  97. func ToInferring(t Type, params ([] string)) Type {
  98. return Transform(t, func(t Type) (Type, bool) {
  99. switch T := t.(type) {
  100. case InferringType:
  101. panic("invalid arguments")
  102. case ParameterType:
  103. for _, p := range params {
  104. if p == T.Name {
  105. var inferring = InferringType { p }
  106. return inferring, true
  107. }
  108. }
  109. }
  110. return nil, false
  111. })
  112. }
  113. func GetCertainOrInferred(t Type, s *InferringState) (CertainType, bool) {
  114. if t == nil {
  115. panic("invalid argument")
  116. }
  117. if IsCertain(t) {
  118. return CertainType { t }, true
  119. } else {
  120. if s != nil {
  121. return s.GetInferredType(t)
  122. } else {
  123. return CertainType {}, false
  124. }
  125. }
  126. }
  127. type InferringState struct {
  128. parameters [] string
  129. mapping ctn.Map[string,Type]
  130. }
  131. func Infer(parameters ([] string)) *InferringState {
  132. return &InferringState {
  133. parameters: parameters,
  134. mapping: ctn.MakeMap[string,Type](ctn.StringCompare),
  135. }
  136. }
  137. func (s *InferringState) getInferred(name string) (Type, bool) {
  138. if s == nil {
  139. panic("invalid operation")
  140. }
  141. var value, exists = s.mapping.Lookup(name)
  142. return value, exists
  143. }
  144. func (s *InferringState) newStateSetInferred(name string, value Type) *InferringState {
  145. if s == nil {
  146. panic("invalid operation")
  147. }
  148. return &InferringState {
  149. parameters: s.parameters,
  150. mapping: s.mapping.Inserted(name, value),
  151. }
  152. }
  153. func (s *InferringState) GetInferredType(t Type) (CertainType, bool) {
  154. if s == nil {
  155. panic("invalid operation")
  156. }
  157. var ok = true
  158. var inferred_t = Transform(t, func(t Type) (Type, bool) {
  159. if T, is_inferring := t.(InferringType); is_inferring {
  160. var value, exists = s.mapping.Lookup(T.Id)
  161. if exists {
  162. return value, true
  163. } else {
  164. ok = false
  165. return nil, false
  166. }
  167. } else {
  168. return nil, false
  169. }
  170. })
  171. if ok {
  172. return CertainType { inferred_t }, true
  173. } else {
  174. return CertainType {}, false
  175. }
  176. }
  177. func (s *InferringState) GetInferredParameterNamespace(name string) (string, bool) {
  178. if s == nil {
  179. panic("invalid operation")
  180. }
  181. var value, exists = s.mapping.Lookup(name)
  182. if exists {
  183. var ref_type, is_ref_type = value.(RefType)
  184. if is_ref_type {
  185. var ns = ref_type.Def.Namespace
  186. return ns, true
  187. } else {
  188. return "", false
  189. }
  190. } else {
  191. return "", false
  192. }
  193. }