123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package checker
- import (
- "kumachan/interpreter/lang/ast"
- "kumachan/interpreter/lang/common/source"
- "kumachan/interpreter/compiler/checker/typsys"
- "kumachan/interpreter/compiler/checker/checked"
- )
- type ExprChecker func (
- expected typsys.Type, s *typsys.InferringState, ctx ExprContext) (
- *checked.Expr, *typsys.InferringState, *source.Error,
- )
- func makeExprChecker(loc source.Location, k func(*checkContext)(checkResult)) ExprChecker {
- return func(expected typsys.Type, s *typsys.InferringState, ctx ExprContext) (*checked.Expr, *typsys.InferringState, *source.Error) {
- var cc = makeCheckContext(loc, expected, s, ctx)
- var result = k(cc)
- return result.expr, cc.inferring, result.err
- }
- }
- func makeExprCheckerWithLocalScope(loc source.Location, k func(*checkContextWithLocalScope)(checkResult)) ExprChecker {
- return func(expected typsys.Type, s *typsys.InferringState, ctx ExprContext) (*checked.Expr, *typsys.InferringState, *source.Error) {
- var cc = makeCheckContextWithLocalScope(loc, expected, s, ctx)
- var result = k(cc)
- return result.expr, cc.inferring, result.err
- }
- }
- func check(node ast.Expr) ExprChecker {
- return ExprChecker(func(expected typsys.Type, s *typsys.InferringState, ctx ExprContext) (*checked.Expr, *typsys.InferringState, *source.Error) {
- var L = len(node.Pipeline)
- if L == 0 {
- return checkTerm(node.Term)(expected, s, ctx)
- } else {
- var last_index = (L - 1)
- var rest_pipeline = node.Pipeline[:last_index]
- var last = node.Pipeline[last_index]
- var rest = ast.Expr {
- Node: node.Node,
- Term: node.Term,
- Pipeline: rest_pipeline,
- }
- var cast, is_cast = last.Pipe.(ast.PipeCast)
- if is_cast {
- var loc = last.Location
- return checkCast(rest, cast.Target, loc)(expected, s, ctx)
- } else {
- var rest_expr, _, err = check(rest)(nil, nil, ctx)
- if err != nil { return nil, nil, err }
- return checkPipe(rest_expr, last)(expected, s, ctx)
- }
- }
- })
- }
- func checkPipe(in *checked.Expr, pipe ast.VariousPipe) ExprChecker {
- var loc = pipe.Location
- switch P := pipe.Pipe.(type) {
- case ast.PipeCast:
- panic("branch should have been handled elsewhere")
- case ast.PipeFunc:
- return checkCallPipe(P.Callee, in, P.Argument, loc)
- case ast.PipeGet:
- return checkGet(in, P.Key, loc)
- case ast.PipeInterior:
- return checkInterior(in, P.Module, P.Item, loc)
- default:
- panic("impossible branch")
- }
- }
- func checkTerm(term ast.VariousTerm) ExprChecker {
- switch T := term.Term.(type) {
- case CheckedExprTerm:
- return checkCheckedExpr(T)
- case ConstructorCallTerm:
- return checkConstructorCall(T, term.Location)
- case ast.VariousCall:
- switch C := T.Call.(type) {
- case ast.CallPrefix:
- return checkCallPrefix(C.Callee, C.Argument, C.Location)
- case ast.CallInfix:
- return checkCallInfix(C.Operator, C.Left, C.Right, C.Location)
- case ast.CallCps:
- return checkCallCps(C.Callee, C.Input, C.Binding, C.Output, C.Node)
- default:
- panic("impossible branch")
- }
- case ast.TermBlank:
- return checkBlank(T)
- case ast.StringLiteral:
- return checkString(T)
- case ast.Formatter:
- return checkFormatter(T)
- case ast.CharLiteral:
- return checkChar(T)
- case ast.FloatLiteral:
- return checkFloat(T)
- case ast.IntegerLiteral:
- return checkInteger(T)
- case ast.InlineRef:
- return checkInlineRef(T)
- case ast.Tuple:
- return checkTuple(T)
- case ast.Record:
- return checkRecord(T)
- case ast.Lambda:
- return checkLambda(T, nil)
- case ast.Block:
- return checkBlock(T)
- case ast.Array:
- return checkList(T)
- case ast.If:
- return checkIf(T)
- case ast.Switch:
- return checkSwitch(T)
- case ast.Select:
- return checkSelect(T)
- case ast.PipelineLambda:
- return checkPipelineLambda(T)
- case ast.ConstructorLambda:
- return checkConstructorLambda(T)
- default:
- panic("impossible branch")
- }
- }
|