package ssa import ( "fmt" "git.urbach.dev/cli/q/src/types" ) // Call is an internal function call. type Call struct { Func *Function Arguments Liveness Source } // Equals returns true if the calls are equal. func (a *Call) Equals(v Value) bool { b, sameType := v.(*Call) if !sameType { return false } return a.Func.Equals(b.Func) && a.Arguments.Equals(b.Arguments) } // Inputs is the function pointer and the list of arguments. func (c *Call) Inputs() []Value { return append(c.Arguments, c.Func) } // IsPure returns false because a function call can have side effects. func (c *Call) IsPure() bool { return false } // String returns a human-readable representation of the call. func (c *Call) String() string { return fmt.Sprintf("%s(%s)", c.Func.String(), c.Arguments.String()) } // Type returns the return type of the function. func (c *Call) Type() types.Type { if len(c.Func.Typ.Output) == 0 { return types.Void } if len(c.Func.Typ.Output) == 1 { return c.Func.Typ.Output[0] } tuple := &types.Tuple{} for _, typ := range c.Func.Typ.Output { structure, isStruct := types.Unwrap(typ).(*types.Struct) if !isStruct { tuple.Types = append(tuple.Types, typ) continue } for _, field := range structure.Fields { tuple.Types = append(tuple.Types, field.Type) } } return tuple }