expr.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package checker
  2. import (
  3. "kumachan/interpreter/lang/ast"
  4. "kumachan/interpreter/lang/common/source"
  5. "kumachan/interpreter/compiler/checker/typsys"
  6. "kumachan/interpreter/compiler/checker/checked"
  7. )
  8. type ExprChecker func (
  9. expected typsys.Type, s *typsys.InferringState, ctx ExprContext) (
  10. *checked.Expr, *typsys.InferringState, *source.Error,
  11. )
  12. func makeExprChecker(loc source.Location, k func(*checkContext)(checkResult)) ExprChecker {
  13. return func(expected typsys.Type, s *typsys.InferringState, ctx ExprContext) (*checked.Expr, *typsys.InferringState, *source.Error) {
  14. var cc = makeCheckContext(loc, expected, s, ctx)
  15. var result = k(cc)
  16. return result.expr, cc.inferring, result.err
  17. }
  18. }
  19. func makeExprCheckerWithLocalScope(loc source.Location, k func(*checkContextWithLocalScope)(checkResult)) ExprChecker {
  20. return func(expected typsys.Type, s *typsys.InferringState, ctx ExprContext) (*checked.Expr, *typsys.InferringState, *source.Error) {
  21. var cc = makeCheckContextWithLocalScope(loc, expected, s, ctx)
  22. var result = k(cc)
  23. return result.expr, cc.inferring, result.err
  24. }
  25. }
  26. func check(node ast.Expr) ExprChecker {
  27. return ExprChecker(func(expected typsys.Type, s *typsys.InferringState, ctx ExprContext) (*checked.Expr, *typsys.InferringState, *source.Error) {
  28. var L = len(node.Pipeline)
  29. if L == 0 {
  30. return checkTerm(node.Term)(expected, s, ctx)
  31. } else {
  32. var last_index = (L - 1)
  33. var rest_pipeline = node.Pipeline[:last_index]
  34. var last = node.Pipeline[last_index]
  35. var rest = ast.Expr {
  36. Node: node.Node,
  37. Term: node.Term,
  38. Pipeline: rest_pipeline,
  39. }
  40. var cast, is_cast = last.Pipe.(ast.PipeCast)
  41. if is_cast {
  42. var loc = last.Location
  43. return checkCast(rest, cast.Target, loc)(expected, s, ctx)
  44. } else {
  45. var rest_expr, _, err = check(rest)(nil, nil, ctx)
  46. if err != nil { return nil, nil, err }
  47. return checkPipe(rest_expr, last)(expected, s, ctx)
  48. }
  49. }
  50. })
  51. }
  52. func checkPipe(in *checked.Expr, pipe ast.VariousPipe) ExprChecker {
  53. var loc = pipe.Location
  54. switch P := pipe.Pipe.(type) {
  55. case ast.PipeCast:
  56. panic("branch should have been handled elsewhere")
  57. case ast.PipeFunc:
  58. return checkCallPipe(P.Callee, in, P.Argument, loc)
  59. case ast.PipeGet:
  60. return checkGet(in, P.Key, loc)
  61. case ast.PipeInterior:
  62. return checkInterior(in, P.Module, P.Item, loc)
  63. default:
  64. panic("impossible branch")
  65. }
  66. }
  67. func checkTerm(term ast.VariousTerm) ExprChecker {
  68. switch T := term.Term.(type) {
  69. case CheckedExprTerm:
  70. return checkCheckedExpr(T)
  71. case ConstructorCallTerm:
  72. return checkConstructorCall(T, term.Location)
  73. case ast.VariousCall:
  74. switch C := T.Call.(type) {
  75. case ast.CallPrefix:
  76. return checkCallPrefix(C.Callee, C.Argument, C.Location)
  77. case ast.CallInfix:
  78. return checkCallInfix(C.Operator, C.Left, C.Right, C.Location)
  79. case ast.CallCps:
  80. return checkCallCps(C.Callee, C.Input, C.Binding, C.Output, C.Node)
  81. default:
  82. panic("impossible branch")
  83. }
  84. case ast.TermBlank:
  85. return checkBlank(T)
  86. case ast.StringLiteral:
  87. return checkString(T)
  88. case ast.Formatter:
  89. return checkFormatter(T)
  90. case ast.CharLiteral:
  91. return checkChar(T)
  92. case ast.FloatLiteral:
  93. return checkFloat(T)
  94. case ast.IntegerLiteral:
  95. return checkInteger(T)
  96. case ast.InlineRef:
  97. return checkInlineRef(T)
  98. case ast.Tuple:
  99. return checkTuple(T)
  100. case ast.Record:
  101. return checkRecord(T)
  102. case ast.Lambda:
  103. return checkLambda(T, nil)
  104. case ast.Block:
  105. return checkBlock(T)
  106. case ast.Array:
  107. return checkList(T)
  108. case ast.If:
  109. return checkIf(T)
  110. case ast.Switch:
  111. return checkSwitch(T)
  112. case ast.Select:
  113. return checkSelect(T)
  114. case ast.PipelineLambda:
  115. return checkPipelineLambda(T)
  116. case ast.ConstructorLambda:
  117. return checkConstructorLambda(T)
  118. default:
  119. panic("impossible branch")
  120. }
  121. }