MCPcopy Create free account
hub / github.com/brimdata/super / semCallByName

Method semCallByName

compiler/semantic/expr.go:761–868  ·  view source on GitHub ↗
(call *ast.CallExpr, name string, args []sem.Expr, argTypes []super.Type, inType super.Type)

Source from the content-addressed store, hash-verified

759}
760
761func (t *translator) semCallByName(call *ast.CallExpr, name string, args []sem.Expr, argTypes []super.Type, inType super.Type) (sem.Expr, super.Type) {
762 if subquery, typ := t.maybeSubqueryCall(call, name, inType); subquery != nil {
763 return subquery, typ
764 }
765 // Check if the name resolves to a symbol in scope.
766 if entry := t.scope.lookupEntry(name); entry != nil {
767 switch ref := entry.ref.(type) {
768 case funcParamValue:
769 t.error(call, fmt.Errorf("function called via parameter %q is bound to a non-function", name))
770 return badExpr, t.checker.unknown
771 case *funcParamLambda:
772 // Called name is a parameter inside of a function. We only end up here
773 // when actual values have been bound to the parameter (i.e., we're compiling
774 // a lambda-variant function each time it is called to create each variant),
775 // so we call the resolver here to create a new instance of the function being
776 // called. In the case of recursion, all the lambdas that are further passed
777 // as args are known (in terms of their decl IDs), so the resolver can
778 // look this up in the variants of the decl and stop the recursion even if the body
779 // of the called entity is not completed yet. We won't know the type but we
780 // can't know the type without function type signatures so when we integrate
781 // type checking here, we will use unknown for this corner case.
782 if isBuiltin(ref.id) {
783 // Check argument count here for builtin functions.
784 if _, err := function.New(super.NewContext(), ref.id, len(args)); err != nil {
785 t.error(call, fmt.Errorf("function %q called via parameter %q: %w", ref.id, ref.param, err))
786 return badExpr, t.checker.unknown
787 }
788 return sem.NewCall(call, ref.id, args), t.checker.unknown //XXX type check call
789 }
790 return t.resolver.mustResolveCall(call, ref.id, args, argTypes)
791 case *opDecl:
792 t.error(call, fmt.Errorf("cannot call user operator %q in an expression (consider subquery syntax)", name))
793 return badExpr, t.checker.unknown
794 case *sem.FuncRef:
795 // FuncRefs are put in the symbol table when passing stuff to user ops, e.g.,
796 // a lambda as a parameter, a &func, or a builtin like &upper.
797 return t.resolver.mustResolveCall(ref, ref.ID, args, argTypes)
798 case *funcDecl:
799 return t.resolver.mustResolveCall(call, ref.id, args, argTypes)
800 case *constDecl, *queryDecl:
801 t.error(call, fmt.Errorf("%q is not a function", name))
802 return badExpr, t.checker.unknown
803 case thunk:
804 // We're calling a function that is a user-operator parameter.
805 // It must be bound to a function.
806 f, _ := t.resolveThunk(ref, inType)
807 funcRef, ok := f.(*sem.FuncRef)
808 if !ok {
809 t.error(call, fmt.Errorf("function called via parameter %q is not a function", name))
810 return badExpr, t.checker.unknown
811 }
812 return t.resolver.mustResolveCall(call, funcRef.ID, args, argTypes)
813
814 }
815 if _, ok := entry.ref.(sem.Expr); ok {
816 t.error(call, fmt.Errorf("%q is not a function", name))
817 return badExpr, t.checker.unknown
818 }

Callers 1

semCallMethod · 0.95

Calls 14

maybeSubqueryCallMethod · 0.95
resolveThunkMethod · 0.95
semMapCallMethod · 0.95
maybeEvalStringMethod · 0.95
NewFunction · 0.92
NewContextFunction · 0.92
NewCallFunction · 0.92
CheckArgCountFunction · 0.92
CompileRegexpFunction · 0.92
QuotedStringFunction · 0.92
isBuiltinFunction · 0.85
lookupEntryMethod · 0.80

Tested by

no test coverage detected