overload.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package checker
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. func OverloadedCall (
  7. functions [] *GenericFunction,
  8. name string,
  9. type_args [] Type,
  10. arg SemiExpr,
  11. f_info ExprInfo,
  12. call_info ExprInfo,
  13. ctx ExprContext,
  14. ) (SemiExpr, *ExprError) {
  15. if len(functions) == 0 { panic("something went wrong") }
  16. if len(functions) == 1 {
  17. var f = functions[0]
  18. var unbox_count uint
  19. var expr, err = GenericFunctionCall (
  20. f, name, 0, type_args, arg, f_info, call_info, ctx,
  21. &unbox_count,
  22. )
  23. if err != nil { return SemiExpr{}, err }
  24. return LiftTyped(expr), nil
  25. } else {
  26. var options = make([]AvailableCall, 0)
  27. var candidates = make([]string, 0)
  28. for i, f := range functions {
  29. var index = uint(i)
  30. var unbox_count uint
  31. var expr, err = GenericFunctionCall (
  32. f, name, index, type_args, arg, f_info, call_info, ctx,
  33. &unbox_count,
  34. )
  35. if err != nil {
  36. candidates = append(candidates, DescribeCandidate (
  37. name, f, ctx,
  38. ))
  39. } else {
  40. options = append(options, AvailableCall {
  41. Expr: expr,
  42. UnboxCount: unbox_count,
  43. })
  44. }
  45. }
  46. var available_count = len(options)
  47. if available_count == 0 {
  48. return SemiExpr{}, &ExprError {
  49. Point: call_info.ErrorPoint,
  50. Concrete: E_NoneOfFunctionsCallable {
  51. Candidates: candidates,
  52. },
  53. }
  54. } else if available_count == 1 {
  55. return LiftTyped(options[0].Expr), nil
  56. } else {
  57. var min_unbox = ^(uint(0))
  58. var min_quantity = 0
  59. var min = -1
  60. for i, opt := range options {
  61. if opt.UnboxCount < min_unbox {
  62. min_unbox = opt.UnboxCount
  63. min_quantity = 0
  64. min = i
  65. } else if opt.UnboxCount == min_unbox {
  66. min_quantity += 1
  67. }
  68. }
  69. if min == -1 { panic("something went wrong") }
  70. if min_quantity == 1 {
  71. return LiftTyped(options[min].Expr), nil
  72. } else {
  73. return SemiExpr {
  74. Value: UndecidedCall {
  75. Options: options,
  76. FuncName: name,
  77. },
  78. Info: call_info,
  79. }, nil
  80. }
  81. }
  82. }
  83. }
  84. func OverloadedAssignTo (
  85. expected Type,
  86. functions [] *GenericFunction,
  87. name string,
  88. type_args [] Type,
  89. info ExprInfo,
  90. ctx ExprContext,
  91. ) (Expr, *ExprError) {
  92. if len(functions) == 0 { panic("something went wrong") }
  93. if len(functions) == 1 {
  94. var f = functions[0]
  95. return GenericFunctionAssignTo (
  96. expected, name, 0, f, type_args, info, ctx,
  97. )
  98. } else {
  99. var candidates = make([]string, 0)
  100. for i, f := range functions {
  101. var index = uint(i)
  102. var expr, err = GenericFunctionAssignTo (
  103. expected, name, index, f, type_args, info, ctx,
  104. )
  105. if err != nil {
  106. candidates = append(candidates, DescribeCandidate (
  107. name, f, ctx,
  108. ))
  109. } else {
  110. return expr, nil
  111. }
  112. }
  113. if expected == nil {
  114. return Expr{}, &ExprError {
  115. Point: info.ErrorPoint,
  116. Concrete: E_ExplicitTypeRequired {},
  117. }
  118. } else {
  119. return Expr{}, &ExprError {
  120. Point: info.ErrorPoint,
  121. Concrete: E_NoneOfFunctionsAssignable {
  122. To: ctx.DescribeType(expected),
  123. Candidates: candidates,
  124. },
  125. }
  126. }
  127. }
  128. }
  129. func DescribeCandidate(name string, f *GenericFunction, ctx ExprContext) string {
  130. return fmt.Sprintf (
  131. "%s[%s]: %s",
  132. name,
  133. strings.Join(f.TypeParams, ","),
  134. DescribeTypeWithParams (
  135. AnonymousType { f.DeclaredType },
  136. f.TypeParams,
  137. ),
  138. )
  139. }