box.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package checker
  2. import (
  3. "kumachan/loader"
  4. )
  5. func Box (
  6. to_be_boxed SemiExpr,
  7. g_type *GenericType,
  8. g_type_name loader.Symbol,
  9. g_type_info ExprInfo,
  10. given_args [] Type,
  11. info ExprInfo,
  12. ctx ExprContext,
  13. ) (Expr, *ExprError) {
  14. var wrapped, ok = g_type.Value.(Boxed)
  15. if !ok { return Expr{}, &ExprError {
  16. Point: g_type_info.ErrorPoint,
  17. Concrete: E_BoxNonBoxedType { g_type_name.String() },
  18. } }
  19. var current_mod = ctx.GetModuleName()
  20. var type_mod = g_type_name.ModuleName
  21. if current_mod != type_mod {
  22. if wrapped.Protected {
  23. return Expr{}, &ExprError {
  24. Point: g_type_info.ErrorPoint,
  25. Concrete: E_BoxProtectedType { g_type_name.String() },
  26. }
  27. }
  28. if wrapped.Opaque {
  29. return Expr{}, &ExprError {
  30. Point: g_type_info.ErrorPoint,
  31. Concrete: E_BoxOpaqueType { g_type_name.String() },
  32. }
  33. }
  34. }
  35. var given_count = uint(len(given_args))
  36. var g_type_arity = uint(len(g_type.Params))
  37. if given_count == g_type_arity {
  38. var inner_type = FillTypeArgs(wrapped.InnerType, given_args)
  39. var expr, err = AssignTo(inner_type, to_be_boxed, ctx)
  40. if err != nil { return Expr{}, err }
  41. var outer_type = NamedType {
  42. Name: g_type_name,
  43. Args: given_args,
  44. }
  45. return Expr {
  46. Type: outer_type,
  47. Value: expr.Value,
  48. Info: info,
  49. }, nil
  50. } else if given_count == 0 {
  51. var inf_ctx = ctx.WithTypeArgsInferringEnabled(g_type.Params)
  52. var marked_inner_type = MarkParamsAsBeingInferred(wrapped.InnerType)
  53. var expr, err = AssignTo(marked_inner_type, to_be_boxed, inf_ctx)
  54. if err != nil { return Expr{}, err }
  55. if uint(len(inf_ctx.Inferred)) != g_type_arity {
  56. return Expr{}, &ExprError {
  57. Point: g_type_info.ErrorPoint,
  58. Concrete: E_ExplicitTypeParamsRequired {},
  59. }
  60. }
  61. var inferred_args = make([]Type, g_type_arity)
  62. for i, t := range inf_ctx.Inferred {
  63. inferred_args[i] = t
  64. }
  65. var inferred_type = NamedType {
  66. Name: g_type_name,
  67. Args: inferred_args,
  68. }
  69. var inner_type = FillTypeArgs(wrapped.InnerType, inferred_args)
  70. if !(AreTypesEqualInSameCtx(inner_type, expr.Type)) {
  71. panic("something went wrong")
  72. }
  73. return Expr {
  74. Type: inferred_type,
  75. Value: expr.Value,
  76. Info: info,
  77. }, nil
  78. } else {
  79. return Expr{}, &ExprError {
  80. Point: g_type_info.ErrorPoint,
  81. Concrete: E_TypeErrorInExpr { &TypeError {
  82. Point: g_type_info.ErrorPoint,
  83. Concrete: E_WrongParameterQuantity {
  84. TypeName: g_type_name,
  85. Required: g_type_arity,
  86. Given: given_count,
  87. },
  88. } },
  89. }
  90. }
  91. }