ctx_type.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package checker
  2. import (
  3. "reflect"
  4. "kumachan/interpreter/lang/common/source"
  5. "kumachan/interpreter/compiler/checker/typsys"
  6. "kumachan/interpreter/compiler/checker/checked"
  7. )
  8. func (cc *checkContext) typeConsContext() TypeConsContext {
  9. return TypeConsContext {
  10. ModInfo: cc.exprContext.ModuleInfo,
  11. TypeReg: cc.exprContext.Registry.Types,
  12. ParamVec: cc.exprContext.ParameterList,
  13. }
  14. }
  15. func (cc *checkContext) getType(t nominalType) typsys.Type {
  16. return t(cc.exprContext.Types)
  17. }
  18. func (cc *checkContext) describeType(t typsys.Type) string {
  19. return typsys.DescribeType(t, cc.inferring)
  20. }
  21. func (cc *checkContext) describeTypeOf(expr *checked.Expr) string {
  22. return cc.describeType(expr.Type)
  23. }
  24. func (cc *checkContext) assignType(to typsys.Type, from typsys.Type) *source.Error {
  25. var a = typsys.MakeAssignContext(cc.exprContext.ModName, cc.inferring)
  26. var ok, s = typsys.Assign(to, from, a)
  27. if ok {
  28. cc.inferring = s
  29. return nil
  30. } else {
  31. return source.MakeError(cc.location, E_NotAssignable {
  32. From: cc.describeType(from),
  33. To: cc.describeType(to),
  34. })
  35. }
  36. }
  37. func (cc *checkContext) requireCertainOrInferredType(t typsys.Type) (typsys.Type, *source.Error) {
  38. var certain_t, ok = cc.getCertainType(t)
  39. if ok {
  40. return certain_t, nil
  41. } else {
  42. var inferred_t, ok = cc.getInferredType(t)
  43. if ok {
  44. return inferred_t, nil
  45. } else {
  46. return nil, source.MakeError(cc.location,
  47. E_ExplicitTypeRequired {})
  48. }
  49. }
  50. }
  51. func (cc *checkContext) getCertainType(t typsys.Type) (typsys.Type, bool) {
  52. if t == nil {
  53. return nil, false
  54. } else {
  55. if cc.inferring == nil {
  56. return t, true
  57. } else {
  58. return typsys.TypeOpGetCertainType(t, cc.inferring)
  59. }
  60. }
  61. }
  62. func (cc *checkContext) getInferredType(t typsys.Type) (typsys.Type, bool) {
  63. if t == nil {
  64. panic("something went wrong")
  65. } else {
  66. if cc.inferring == nil {
  67. panic("something went wrong")
  68. } else {
  69. return typsys.TypeOpGetInferredType(t, cc.inferring)
  70. }
  71. }
  72. }
  73. func (cc *checkContext) getExpectedCertainOrInferred(t typsys.Type) (typsys.Type, bool) {
  74. return typsys.TypeOpGetInferredExpectedType(t, cc.inferring)
  75. }
  76. func (cc *checkContext) getExpectedTuple(t typsys.Type) (typsys.Tuple, bool) {
  77. var get = func(t typsys.Type) (typsys.Tuple, bool) {
  78. return obtainIsoTuple(t, cc.exprContext.ModName)
  79. }
  80. var v, ok = cc.getExpectedTypeComponent(t, reflect.ValueOf(get))
  81. if ok {
  82. return v.(typsys.Tuple), true
  83. } else {
  84. return typsys.Tuple {}, false
  85. }
  86. }
  87. func (cc *checkContext) getExpectedRecord(t typsys.Type) (typsys.Record, bool) {
  88. var get = func(t typsys.Type) (typsys.Record, bool) {
  89. return obtainIsoRecord(t, cc.exprContext.ModName)
  90. }
  91. var v, ok = cc.getExpectedTypeComponent(t, reflect.ValueOf(get))
  92. if ok {
  93. return v.(typsys.Record), true
  94. } else {
  95. return typsys.Record {}, false
  96. }
  97. }
  98. func (cc *checkContext) getExpectedListItemType(t typsys.Type) (typsys.Type, bool) {
  99. var get func(typsys.Type) (typsys.Type, bool)
  100. get = func(t typsys.Type) (typsys.Type, bool) {
  101. var item_t, ok = coreList_(t)
  102. if ok {
  103. return item_t, true
  104. } else {
  105. var inner, box, is_box = typsys.Unbox(t, cc.exprContext.ModName)
  106. if is_box && box.BoxKind == typsys.Isomorphic {
  107. return get(inner)
  108. } else {
  109. return nil, false
  110. }
  111. }
  112. }
  113. var v, ok = cc.getExpectedTypeComponent(t, reflect.ValueOf(coreList_))
  114. if ok {
  115. return v.(typsys.Type), true
  116. } else {
  117. return nil, false
  118. }
  119. }
  120. func (cc *checkContext) getExpectedTypeComponent(t typsys.Type, get_ reflect.Value) (interface{}, bool) {
  121. var get = func(t typsys.Type) (interface{}, bool) {
  122. if t == nil {
  123. return nil, false
  124. }
  125. var ret = get_.Call([] reflect.Value { reflect.ValueOf(t) })
  126. var v, ok = ret[0].Interface(), ret[1].Interface()
  127. if ok.(bool) {
  128. return v, true
  129. } else {
  130. return nil, false
  131. }
  132. }
  133. var v, ok = get(t)
  134. if ok {
  135. return v, true
  136. } else {
  137. var t_, ok = typsys.TypeOpGetInferredExpectedType(t, cc.inferring)
  138. if ok {
  139. return get(t_)
  140. } else {
  141. return nil, false
  142. }
  143. }
  144. }
  145. func (cc *checkContext) getExpectedLambda(t typsys.Type, loc source.Location) (typsys.Lambda, *source.Error) {
  146. var get = func(t typsys.Type) (typsys.Lambda, bool) {
  147. return obtainIsoLambda(t, cc.exprContext.ModName)
  148. }
  149. var io, ok = get(t)
  150. if ok {
  151. var s = cc.inferring
  152. var in, ok = typsys.TypeOpGetInferredLambdaInputType(io.Input, s)
  153. if !(ok) { return typsys.Lambda {}, source.MakeError(loc,
  154. E_ExplicitTypeRequired {}) }
  155. var out = io.Output
  156. return typsys.Lambda {
  157. Input: in,
  158. Output: out,
  159. }, nil
  160. } else {
  161. var t_, ok = typsys.TypeOpGetInferredExpectedType(t, cc.inferring)
  162. if ok {
  163. var io, ok = get(t_)
  164. if ok {
  165. return io, nil
  166. }
  167. }
  168. if t == nil {
  169. return typsys.Lambda {}, source.MakeError(loc,
  170. E_ExplicitTypeRequired {})
  171. } else {
  172. return typsys.Lambda {}, source.MakeError(loc,
  173. E_LambdaAssignedToIncompatible {
  174. TypeName: typsys.DescribeType(t, cc.inferring),
  175. })
  176. }
  177. }
  178. }
  179. func (cc *checkContext) unboxInterface(expr *checked.Expr) (*typsys.Interface, *typsys.TypeDef, ([] typsys.Type), bool) {
  180. return cc.unboxInterfaceFromType(expr.Type)
  181. }
  182. func (cc *checkContext) unboxInterfaceFromType(t typsys.Type) (*typsys.Interface, *typsys.TypeDef, ([] typsys.Type), bool) {
  183. return unboxInterface(t, cc.exprContext.ModName)
  184. }
  185. func (cc *checkContext) unboxEnum(expr *checked.Expr) (*typsys.Enum, *typsys.TypeDef, ([] typsys.Type), bool) {
  186. return cc.unboxEnumFromType(expr.Type)
  187. }
  188. func (cc *checkContext) unboxEnumFromType(t typsys.Type) (*typsys.Enum, *typsys.TypeDef, ([] typsys.Type), bool) {
  189. return unboxEnum(t, cc.exprContext.ModName)
  190. }
  191. func (cc *checkContext) unboxRecord(expr *checked.Expr) (typsys.Record, bool) {
  192. return cc.unboxRecordFromType(expr.Type)
  193. }
  194. func (cc *checkContext) unboxRecordFromType(t typsys.Type) (typsys.Record, bool) {
  195. return unboxRecord(t, cc.exprContext.ModName)
  196. }
  197. func (cc *checkContext) unboxLambda(expr *checked.Expr) (typsys.Lambda, bool) {
  198. return cc.unboxLambdaFromType(expr.Type)
  199. }
  200. func (cc *checkContext) unboxLambdaFromType(t typsys.Type) (typsys.Lambda, bool) {
  201. return unboxLambda(t, cc.exprContext.ModName)
  202. }
  203. func (cc *checkContext) unboxInteriorReferableRecord(expr *checked.Expr) (typsys.Record, checked.InteriorRefOperand, typsys.Type, bool) {
  204. var record, ok = cc.unboxRecord(expr)
  205. if ok {
  206. var base_t = &typsys.NestedType { Content: record }
  207. return record, checked.RO_Record, base_t, true
  208. } else {
  209. var base_t, field_t, ok = coreProjRef_(expr.Type)
  210. if ok {
  211. var record, ok = cc.unboxRecordFromType(field_t)
  212. if ok {
  213. return record, checked.RO_ProjRef, base_t, true
  214. }
  215. }
  216. return typsys.Record {}, -1, nil, false
  217. }
  218. }
  219. func (cc *checkContext) unboxInteriorReferableEnum(expr *checked.Expr) (*typsys.Enum, ([] typsys.Type), checked.InteriorRefOperand, typsys.Type, bool) {
  220. var enum, enum_def, enum_args, ok = cc.unboxEnum(expr)
  221. if ok {
  222. var base_t = &typsys.NestedType { Content:
  223. typsys.Ref {
  224. Def: enum_def,
  225. Args: enum_args,
  226. } }
  227. return enum, enum_args, checked.RO_EnumOrInterface, base_t, true
  228. } else {
  229. { var base_t, field_t, ok = coreProjRef_(expr.Type)
  230. if ok {
  231. var enum, _, enum_args, ok = cc.unboxEnumFromType(field_t)
  232. if ok {
  233. return enum, enum_args, checked.RO_ProjRef, base_t, true
  234. }
  235. } }
  236. { var base_t, case_t, ok = coreCaseRef_(expr.Type)
  237. if ok {
  238. var enum, _, enum_args, ok = cc.unboxEnumFromType(case_t)
  239. if ok {
  240. return enum, enum_args, checked.RO_CaseRef, base_t, true
  241. }
  242. }}
  243. return nil, nil, -1, nil, false
  244. }
  245. }
  246. func (cc *checkContext) unboxInteriorReferableInterfaceDef(expr *checked.Expr) (*typsys.TypeDef, ([] typsys.Type), checked.InteriorRefOperand, typsys.Type, bool) {
  247. var _, def, t_args, ok = cc.unboxInterface(expr)
  248. if ok {
  249. var base_t = &typsys.NestedType { Content:
  250. typsys.Ref {
  251. Def: def,
  252. Args: t_args,
  253. } }
  254. return def, t_args, checked.RO_EnumOrInterface, base_t, true
  255. } else {
  256. { var base_t, field_t, ok = coreProjRef_(expr.Type)
  257. if ok {
  258. var _, def, t_args, ok = cc.unboxInterfaceFromType(field_t)
  259. if ok {
  260. return def, t_args, checked.RO_ProjRef, base_t, true
  261. }
  262. } }
  263. { var base_t, case_t, ok = coreCaseRef_(expr.Type)
  264. if ok {
  265. var _, def, t_args, ok = cc.unboxInterfaceFromType(case_t)
  266. if ok {
  267. return def, t_args, checked.RO_CaseRef, base_t, true
  268. }
  269. }}
  270. return nil, nil, -1, nil, false
  271. }
  272. }