ref.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package checker
  2. import (
  3. "kumachan/loader"
  4. "kumachan/transformer/node"
  5. )
  6. func (impl UntypedRef) SemiExprVal() {}
  7. type UntypedRef struct {
  8. RefBody UntypedRefBody
  9. TypeArgs [] Type
  10. }
  11. type UntypedRefBody interface { UntypedRefBody() }
  12. func (impl UntypedRefToType) UntypedRefBody() {}
  13. type UntypedRefToType struct {
  14. TypeName loader.Symbol
  15. Type *GenericType
  16. }
  17. func (impl UntypedRefToFunctions) UntypedRefBody() {}
  18. type UntypedRefToFunctions struct {
  19. FuncName string
  20. Functions [] *GenericFunction
  21. }
  22. func (impl RefConstant) ExprVal() {}
  23. type RefConstant struct {
  24. Name loader.Symbol
  25. }
  26. func (impl RefFunction) ExprVal() {}
  27. type RefFunction struct {
  28. Name string
  29. Index uint
  30. }
  31. func (impl RefLocal) ExprVal() {}
  32. type RefLocal struct {
  33. Name string
  34. }
  35. func CheckRef(ref node.Ref, ctx ExprContext) (SemiExpr, *ExprError) {
  36. var info = ctx.GetExprInfo(ref.Node)
  37. var maybe_symbol = ctx.ModuleInfo.Module.SymbolFromRef(ref)
  38. var symbol, ok = maybe_symbol.(loader.Symbol)
  39. if !ok { return SemiExpr{}, &ExprError {
  40. Point: ctx.GetErrorPoint(ref.Module.Node),
  41. Concrete: E_ModuleNotFound { loader.Id2String(ref.Module) },
  42. } }
  43. var sym_concrete, exists = ctx.LookupSymbol(symbol)
  44. if !exists { return SemiExpr{}, &ExprError {
  45. Point: ctx.GetErrorPoint(ref.Id.Node),
  46. Concrete: E_TypeOrValueNotFound { symbol },
  47. } }
  48. var type_ctx = ctx.GetTypeContext()
  49. var type_args = make([]Type, len(ref.TypeArgs))
  50. for i, arg_node := range ref.TypeArgs {
  51. var t, err = TypeFrom(arg_node.Type, type_ctx)
  52. if err != nil { return SemiExpr{}, &ExprError {
  53. Point: err.Point,
  54. Concrete: E_TypeErrorInExpr { err },
  55. } }
  56. type_args[i] = t
  57. }
  58. switch s := sym_concrete.(type) {
  59. case SymLocalValue:
  60. return LiftTyped(Expr {
  61. Type: s.ValueType,
  62. Value: RefLocal { symbol.SymbolName },
  63. Info: info,
  64. }), nil
  65. case SymConst:
  66. return LiftTyped(Expr {
  67. Type: s.Const.DeclaredType,
  68. Value: RefConstant { symbol },
  69. Info: info,
  70. }), nil
  71. case SymTypeParam:
  72. return SemiExpr{}, &ExprError {
  73. Point: ctx.GetErrorPoint(ref.Id.Node),
  74. Concrete: E_TypeParamInExpr { symbol.SymbolName },
  75. }
  76. case SymType:
  77. return SemiExpr {
  78. Value: UntypedRef {
  79. RefBody: UntypedRefToType {
  80. TypeName: symbol,
  81. Type: s.Type,
  82. },
  83. TypeArgs: type_args,
  84. },
  85. Info: info,
  86. }, nil
  87. case SymFunctions:
  88. return SemiExpr {
  89. Value: UntypedRef {
  90. RefBody: UntypedRefToFunctions {
  91. FuncName: symbol.SymbolName,
  92. Functions: s.Functions,
  93. },
  94. TypeArgs: type_args,
  95. },
  96. Info: info,
  97. }, nil
  98. default:
  99. panic("impossible branch")
  100. }
  101. }
  102. func AssignRefTo(expected Type, ref UntypedRef, info ExprInfo, ctx ExprContext) (Expr, *ExprError) {
  103. switch r := ref.RefBody.(type) {
  104. case UntypedRefToType:
  105. return Expr{}, &ExprError {
  106. Point: info.ErrorPoint,
  107. Concrete: E_TypeUsedAsValue { r.TypeName },
  108. }
  109. case UntypedRefToFunctions:
  110. var name = r.FuncName
  111. var functions = r.Functions
  112. var type_args = ref.TypeArgs
  113. return OverloadedAssignTo (
  114. expected, functions, name, type_args, info, ctx,
  115. )
  116. default:
  117. panic("impossible branch")
  118. }
  119. }
  120. func CallUntypedRef (
  121. arg SemiExpr,
  122. ref UntypedRef,
  123. ref_info ExprInfo,
  124. call_info ExprInfo,
  125. ctx ExprContext,
  126. ) (SemiExpr, *ExprError) {
  127. switch ref_body := ref.RefBody.(type) {
  128. case UntypedRefToType:
  129. var g = ref_body.Type
  130. var g_name = ref_body.TypeName
  131. var type_args = ref.TypeArgs
  132. var expr, err = Box (
  133. arg, g, g_name, ref_info, type_args, call_info, ctx,
  134. )
  135. if err != nil { return SemiExpr{}, err }
  136. return LiftTyped(expr), nil
  137. case UntypedRefToFunctions:
  138. var functions = ref_body.Functions
  139. var name = ref_body.FuncName
  140. var type_args = ref.TypeArgs
  141. return OverloadedCall (
  142. functions, name, type_args, arg, ref_info, call_info, ctx,
  143. )
  144. default:
  145. panic("impossible branch")
  146. }
  147. }