product.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. package checker
  2. import (
  3. "kumachan/loader"
  4. "kumachan/transformer/node"
  5. )
  6. func (impl SemiTypedTuple) SemiExprVal() {}
  7. type SemiTypedTuple struct {
  8. Values [] SemiExpr
  9. }
  10. func (impl SemiTypedBundle) SemiExprVal() {}
  11. type SemiTypedBundle struct {
  12. Index map[string] uint
  13. Values [] SemiExpr
  14. KeyNodes [] node.Node
  15. }
  16. func (impl Product) ExprVal() {}
  17. type Product struct {
  18. Values [] Expr
  19. }
  20. func (impl Get) ExprVal() {}
  21. type Get struct {
  22. Product Expr
  23. Index uint
  24. }
  25. func (impl Set) ExprVal() {}
  26. type Set struct {
  27. Product Expr
  28. Index uint
  29. NewValue Expr
  30. }
  31. func CheckTuple(tuple node.Tuple, ctx ExprContext) (SemiExpr, *ExprError) {
  32. var info = ctx.GetExprInfo(tuple.Node)
  33. var L = len(tuple.Elements)
  34. if L == 0 {
  35. return LiftTyped(Expr {
  36. Type: AnonymousType { Unit {} },
  37. Value: UnitValue {},
  38. Info: info,
  39. }), nil
  40. } else if L == 1 {
  41. var expr, err = Check(tuple.Elements[0], ctx)
  42. if err != nil { return SemiExpr{}, err }
  43. return expr, nil
  44. } else {
  45. var el_exprs = make([]SemiExpr, L)
  46. var el_types = make([]Type, L)
  47. for i, el := range tuple.Elements {
  48. var expr, err = Check(el, ctx)
  49. if err != nil { return SemiExpr{}, err }
  50. el_exprs[i] = expr
  51. switch typed := expr.Value.(type) {
  52. case TypedExpr:
  53. el_types[i] = typed.Type
  54. }
  55. }
  56. return SemiExpr {
  57. Value: SemiTypedTuple { el_exprs },
  58. Info: info,
  59. }, nil
  60. }
  61. }
  62. func CheckBundle(bundle node.Bundle, ctx ExprContext) (SemiExpr, *ExprError) {
  63. var info = ctx.GetExprInfo(bundle.Node)
  64. switch update := bundle.Update.(type) {
  65. case node.Update:
  66. var base_semi, err = Check(update.Base, ctx)
  67. if err != nil { return SemiExpr{}, err }
  68. switch b := base_semi.Value.(type) {
  69. case TypedExpr:
  70. if IsBundleLiteral(Expr(b)) { return SemiExpr{}, &ExprError {
  71. Point: ctx.GetErrorPoint(update.Base.Node),
  72. Concrete: E_SetToLiteralBundle {},
  73. } }
  74. var L = len(bundle.Values)
  75. if !(L >= 1) { panic("something went wrong") }
  76. var base = Expr(b)
  77. switch target := UnboxBundle(base.Type, ctx).(type) {
  78. case Bundle:
  79. var occurred_names = make(map[string] bool)
  80. var current_base = base
  81. for _, field := range bundle.Values {
  82. var name = loader.Id2String(field.Key)
  83. var target_field, exists = target.Fields[name]
  84. if !exists {
  85. return SemiExpr{}, &ExprError {
  86. Point: ctx.GetErrorPoint(field.Key.Node),
  87. Concrete: E_FieldDoesNotExist {
  88. Field: name,
  89. Target: ctx.DescribeType(base.Type),
  90. },
  91. }
  92. }
  93. var _, duplicate = occurred_names[name]
  94. if duplicate {
  95. return SemiExpr{}, &ExprError {
  96. Point: ctx.GetErrorPoint(field.Key.Node),
  97. Concrete: E_ExprDuplicateField { name },
  98. }
  99. }
  100. occurred_names[name] = true
  101. var value_node = DesugarOmittedFieldValue(field)
  102. var value_semi, err1 = Check(value_node, ctx)
  103. if err1 != nil { return SemiExpr{}, err1 }
  104. var value, err2 = AssignTo(target_field.Type, value_semi, ctx)
  105. if err2 != nil { return SemiExpr{}, err2 }
  106. current_base = Expr {
  107. Type: current_base.Type,
  108. Value: Set {
  109. Product: current_base,
  110. Index: target_field.Index,
  111. NewValue: value,
  112. },
  113. Info: current_base.Info,
  114. }
  115. }
  116. var final = current_base
  117. return SemiExpr {
  118. Value: TypedExpr(final),
  119. Info: info,
  120. }, nil
  121. case BR_BundleButOpaque:
  122. return SemiExpr{}, &ExprError {
  123. Point: base.Info.ErrorPoint,
  124. Concrete: E_SetToOpaqueBundle {},
  125. }
  126. case BR_NonBundle:
  127. return SemiExpr{}, &ExprError {
  128. Point: base.Info.ErrorPoint,
  129. Concrete: E_SetToNonBundle {},
  130. }
  131. default:
  132. panic("impossible branch")
  133. }
  134. case SemiTypedBundle:
  135. return SemiExpr{}, &ExprError {
  136. Point: ctx.GetErrorPoint(update.Base.Node),
  137. Concrete: E_SetToLiteralBundle {},
  138. }
  139. default:
  140. return SemiExpr{}, &ExprError {
  141. Point: ctx.GetErrorPoint(update.Base.Node),
  142. Concrete: E_SetToNonBundle {},
  143. }
  144. }
  145. default:
  146. var L = len(bundle.Values)
  147. if L == 0 {
  148. return LiftTyped(Expr {
  149. Type: AnonymousType { Unit {} },
  150. Value: UnitValue {},
  151. Info: info,
  152. }), nil
  153. } else {
  154. var f_exprs = make([]SemiExpr, L)
  155. var f_index_map = make(map[string]uint, L)
  156. var f_key_nodes = make([]node.Node, L)
  157. for i, field := range bundle.Values {
  158. var name = loader.Id2String(field.Key)
  159. var _, exists = f_index_map[name]
  160. if exists { return SemiExpr{}, &ExprError {
  161. Point: ctx.GetErrorPoint(field.Key.Node),
  162. Concrete: E_ExprDuplicateField { name },
  163. } }
  164. var value = DesugarOmittedFieldValue(field)
  165. var expr, err = Check(value, ctx)
  166. if err != nil { return SemiExpr{}, err }
  167. f_exprs[i] = expr
  168. f_index_map[name] = uint(i)
  169. f_key_nodes[i] = field.Key.Node
  170. }
  171. return SemiExpr {
  172. Value: SemiTypedBundle {
  173. Index: f_index_map,
  174. Values: f_exprs,
  175. KeyNodes: f_key_nodes,
  176. },
  177. Info: info,
  178. }, nil
  179. }
  180. }
  181. }
  182. func CheckGet(get node.Get, ctx ExprContext) (SemiExpr, *ExprError) {
  183. var base_semi, err = Check(get.Base, ctx)
  184. if err != nil { return SemiExpr{}, err }
  185. switch b := base_semi.Value.(type) {
  186. case TypedExpr:
  187. if IsBundleLiteral(Expr(b)) { return SemiExpr{}, &ExprError {
  188. Point: ctx.GetErrorPoint(get.Base.Node),
  189. Concrete: E_GetFromLiteralBundle {},
  190. } }
  191. var L = len(get.Path)
  192. if !(L >= 1) { panic("something went wrong") }
  193. var base = Expr(b)
  194. for _, member := range get.Path {
  195. switch bundle := UnboxBundle(base.Type, ctx).(type) {
  196. case Bundle:
  197. var key = loader.Id2String(member.Name)
  198. var field, exists = bundle.Fields[key]
  199. if !exists { return SemiExpr{}, &ExprError {
  200. Point: ctx.GetErrorPoint(member.Node),
  201. Concrete: E_FieldDoesNotExist {
  202. Field: key,
  203. Target: ctx.DescribeType(AnonymousType{bundle}),
  204. },
  205. } }
  206. var expr = Expr {
  207. Type: field.Type,
  208. Value: Get {
  209. Product: Expr(base),
  210. Index: field.Index,
  211. },
  212. Info: ctx.GetExprInfo(member.Node),
  213. }
  214. base = expr
  215. case BR_BundleButOpaque:
  216. return SemiExpr{}, &ExprError {
  217. Point: base.Info.ErrorPoint,
  218. Concrete: E_GetFromOpaqueBundle {},
  219. }
  220. case BR_NonBundle:
  221. return SemiExpr{}, &ExprError {
  222. Point: base.Info.ErrorPoint,
  223. Concrete: E_GetFromNonBundle {},
  224. }
  225. default:
  226. panic("impossible branch")
  227. }
  228. }
  229. var final = base
  230. return LiftTyped(final), nil
  231. case SemiTypedBundle:
  232. return SemiExpr{}, &ExprError {
  233. Point: ctx.GetErrorPoint(get.Base.Node),
  234. Concrete: E_GetFromLiteralBundle {},
  235. }
  236. default:
  237. return SemiExpr{}, &ExprError {
  238. Point: ctx.GetErrorPoint(get.Base.Node),
  239. Concrete: E_GetFromNonBundle {},
  240. }
  241. }
  242. }
  243. func AssignTupleTo(expected Type, tuple SemiTypedTuple, info ExprInfo, ctx ExprContext) (Expr, *ExprError) {
  244. var non_nil_expected Type
  245. if expected == nil {
  246. non_nil_expected = AnonymousType {
  247. Tuple {
  248. // Fill with nil
  249. Elements: make([]Type, len(tuple.Values)),
  250. },
  251. }
  252. } else {
  253. non_nil_expected = expected
  254. }
  255. switch E := non_nil_expected.(type) {
  256. case AnonymousType:
  257. switch tuple_t := E.Repr.(type) {
  258. case Tuple:
  259. var required = len(tuple_t.Elements)
  260. var given = len(tuple.Values)
  261. if given != required {
  262. return Expr{}, &ExprError {
  263. Point: info.ErrorPoint,
  264. Concrete: E_TupleSizeNotMatching {
  265. Required: required,
  266. Given: given,
  267. GivenType: ctx.DescribeType(AnonymousType { tuple_t }),
  268. },
  269. }
  270. }
  271. var typed_exprs = make([]Expr, given)
  272. for i, el := range tuple.Values {
  273. var el_expected = tuple_t.Elements[i]
  274. var typed, err = AssignTo(el_expected, el, ctx)
  275. if err != nil { return Expr{}, err }
  276. typed_exprs[i] = typed
  277. }
  278. return Expr {
  279. Type: expected,
  280. Info: info,
  281. Value: Product { typed_exprs },
  282. }, nil
  283. }
  284. }
  285. return Expr{}, &ExprError {
  286. Point: info.ErrorPoint,
  287. Concrete: E_TupleAssignedToNonTupleType {},
  288. }
  289. }
  290. func AssignBundleTo(expected Type, bundle SemiTypedBundle, info ExprInfo, ctx ExprContext) (Expr, *ExprError) {
  291. var err = RequireExplicitType(expected, info)
  292. if err != nil { return Expr{}, err }
  293. switch E := expected.(type) {
  294. case AnonymousType:
  295. switch bundle_t := E.Repr.(type) {
  296. case Bundle:
  297. var values = make([]Expr, len(bundle_t.Fields))
  298. for field_name, field := range bundle_t.Fields {
  299. var given_index, exists = bundle.Index[field_name]
  300. if !exists {
  301. return Expr{}, &ExprError {
  302. Point: info.ErrorPoint,
  303. Concrete: E_MissingField {
  304. Field: field_name,
  305. Type: ctx.DescribeType(field.Type),
  306. },
  307. }
  308. }
  309. var given_value = bundle.Values[given_index]
  310. var value, err = AssignTo(field.Type, given_value, ctx)
  311. if err != nil { return Expr{}, err }
  312. values[field.Index] = value
  313. }
  314. for given_field_name, index := range bundle.Index {
  315. var _, exists = bundle_t.Fields[given_field_name]
  316. if !exists {
  317. var key_node = bundle.KeyNodes[index]
  318. return Expr{}, &ExprError {
  319. Point: ctx.GetErrorPoint(key_node),
  320. Concrete: E_SurplusField { given_field_name },
  321. }
  322. }
  323. }
  324. return Expr {
  325. Type: expected,
  326. Info: info,
  327. Value: Product { values },
  328. }, nil
  329. }
  330. }
  331. return Expr{}, &ExprError {
  332. Point: info.ErrorPoint,
  333. Concrete: E_BundleAssignedToNonBundleType {},
  334. }
  335. }
  336. func IsBundleLiteral(expr Expr) bool {
  337. switch expr.Value.(type) {
  338. case Product:
  339. switch t := expr.Type.(type) {
  340. case AnonymousType:
  341. switch t.Repr.(type) {
  342. case Bundle:
  343. return true
  344. }
  345. }
  346. }
  347. return false
  348. }
  349. func DesugarOmittedFieldValue(field node.FieldValue) node.Expr {
  350. switch val_expr := field.Value.(type) {
  351. case node.Expr:
  352. return val_expr
  353. default:
  354. return node.Expr {
  355. Node: field.Node,
  356. Call: node.Call {
  357. Node: field.Node,
  358. Func: node.VariousTerm {
  359. Node: field.Node,
  360. Term: node.Ref {
  361. Node: field.Node,
  362. Module: node.Identifier {
  363. Node: field.Node,
  364. Name: []rune(""),
  365. },
  366. Specific: false,
  367. Id: field.Key,
  368. TypeArgs: make([]node.VariousType, 0),
  369. },
  370. },
  371. },
  372. }
  373. }
  374. }