123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- package checker
- import (
- "kumachan/parser/scanner"
- "kumachan/transformer/node"
- )
- func (impl UndecidedCall) SemiExprVal() {}
- type UndecidedCall struct {
- Options [] AvailableCall
- FuncName string
- }
- type AvailableCall struct {
- Expr Expr
- UnboxCount uint
- }
- func (impl Call) ExprVal() {}
- type Call struct {
- Function Expr
- Argument Expr
- }
- func CheckCall(call node.Call, ctx ExprContext) (SemiExpr, *ExprError) {
- var arg_node, has_arg = call.Arg.(node.Call)
- if has_arg {
- var f, err1 = CheckTerm(call.Func, ctx)
- if err1 != nil { return SemiExpr{}, err1 }
- var arg, err2 = CheckCall(arg_node, ctx)
- if err2 != nil { return SemiExpr{}, err2 }
- var info = ctx.GetExprInfo(call.Node)
- return CheckSingleCall(f, arg, info, ctx)
- } else {
- return CheckTerm(call.Func, ctx)
- }
- }
- func CheckSingleCall(f SemiExpr, arg SemiExpr, info ExprInfo, ctx ExprContext) (SemiExpr, *ExprError) {
- switch f_concrete := f.Value.(type) {
- case TypedExpr:
- var t = f_concrete.Type
- switch T := t.(type) {
- case AnonymousType:
- switch r := T.Repr.(type) {
- case Func:
- var arg_typed, err = AssignTo(r.Input, arg, ctx)
- if err != nil { return SemiExpr{}, err }
- return LiftTyped(Expr {
- Type: r.Output,
- Value: Call {
- Function: Expr(f_concrete),
- Argument: arg_typed,
- },
- Info: f.Info,
- }), nil
- }
- }
- return SemiExpr{}, &ExprError {
- Point: f.Info.ErrorPoint,
- Concrete: E_ExprTypeNotCallable {
- Type: ctx.DescribeType(t),
- },
- }
- case UntypedLambda:
- return CallUntypedLambda(arg, f_concrete, f.Info, info, ctx)
- case UntypedRef:
- return CallUntypedRef(arg, f_concrete, f.Info, info, ctx)
- case SemiTypedMatch,
- SemiTypedBlock,
- UndecidedCall:
- return SemiExpr{}, &ExprError {
- Point: f.Info.ErrorPoint,
- Concrete: E_ExplicitTypeRequired {},
- }
- default:
- return SemiExpr{}, &ExprError {
- Point: f.Info.ErrorPoint,
- Concrete: E_ExprNotCallable {},
- }
- }
- }
- func CheckInfix(infix node.Infix, ctx ExprContext) (SemiExpr, *ExprError) {
- return CheckCall(DesugarInfix(infix), ctx)
- }
- func AssignCallTo(expected Type, call UndecidedCall, info ExprInfo, ctx ExprContext) (Expr, *ExprError) {
- var err = RequireExplicitType(expected, info)
- if err != nil { return Expr{}, err }
- var types_desc = make([]string, 0)
- for _, option := range call.Options {
- var expr, err = AssignTypedTo(expected, option.Expr, ctx, false)
- if err != nil {
- types_desc = append (
- types_desc,
- ctx.DescribeType(option.Expr.Type),
- )
- continue
- } else {
- return expr, nil
- }
- }
- return Expr{}, &ExprError {
- Point: info.ErrorPoint,
- Concrete: E_NoneOfTypesAssignable {
- From: types_desc,
- To: ctx.DescribeExpectedType(expected),
- },
- }
- }
- func DesugarExpr(expr node.Expr) node.Call {
- return DesugarPipeline(expr.Call, expr.Pipeline)
- }
- func DesugarPipeline(left node.Call, p node.MaybePipeline) node.Call {
- var pipeline, ok = p.(node.Pipeline)
- if !ok {
- return left
- }
- var f = pipeline.Func
- var maybe_right = pipeline.Arg
- var right, exists = maybe_right.(node.Call)
- var arg node.Tuple
- var current_node node.Node
- if exists {
- arg = node.Tuple {
- Node: pipeline.Operator.Node,
- Elements: []node.Expr {
- node.Expr {
- Node: left.Node,
- Call: left,
- Pipeline: nil,
- },
- node.Expr {
- Node: right.Node,
- Call: right,
- Pipeline: nil,
- },
- },
- }
- current_node = node.Node {
- Point: pipeline.Node.Point,
- Span: scanner.Span {
- Start: pipeline.Node.Span.Start,
- End: right.Span.End,
- },
- UID: 0,
- }
- } else {
- arg = node.Tuple {
- Node: left.Node,
- Elements: []node.Expr { {
- Node: left.Node,
- Call: left,
- Pipeline: nil,
- } },
- }
- current_node = node.Node {
- Point: pipeline.Node.Point,
- Span: scanner.Span {
- Start: pipeline.Node.Span.Start,
- End: pipeline.Func.Span.End,
- },
- UID: 0,
- }
- }
- var current = node.Call {
- Node: current_node,
- Func: f,
- Arg: node.Call {
- Node: arg.Node,
- Func: node.VariousTerm {
- Node: arg.Node,
- Term: arg,
- },
- Arg: nil,
- },
- }
- return DesugarPipeline(current, pipeline.Next)
- }
- func DesugarInfix(infix node.Infix) node.Call {
- return node.Call {
- Node: infix.Node,
- Func: infix.Operator,
- Arg: node.Call {
- Node: infix.Node,
- Func: node.VariousTerm {
- Node: infix.Node,
- Term: node.Tuple {
- Node: infix.Node,
- Elements: []node.Expr {
- node.Expr {
- Node: infix.Operand1.Node,
- Call: node.Call {
- Node: infix.Operand1.Node,
- Func: infix.Operand1,
- Arg: nil,
- },
- Pipeline: nil,
- },
- node.Expr {
- Node: infix.Operand2.Node,
- Call: node.Call {
- Node: infix.Operand2.Node,
- Func: infix.Operand2,
- Arg: nil,
- },
- Pipeline: nil,
- },
- },
- },
- },
- Arg: nil,
- },
- }
- }
|