func GenerateAbstractCall(target Callable, types *TypeLookup) *CallStm {
	c := &CallStm{
		Modifiers: &Modifiers{Bindings: new(BindStms)},
		Id:        target.GetId(),
		DecId:     target.GetId(),
		Bindings: &BindStms{
			List: make([]*BindStm, 0, len(target.GetInParams().List)),
			Table: make(map[string]*BindStm,
				len(target.GetInParams().List)),
		},
	}
	for _, arg := range target.GetInParams().List {
		typ := types.Get(arg.Tname)
		v := abstractExpForType(typ, &arg.Node, types)
		b := BindStm{
			Id:    arg.GetId(),
			Exp:   v,
			Tname: arg.GetTname(),
		}
		c.Bindings.List = append(c.Bindings.List, &b)
		c.Bindings.Table[b.Id] = &b
	}
	return c
}
GenerateAbstractCall creates a CallStm calling the given Callable with
arbitrary simulated inputs appropriate for static analysis of call graphs.

Because some arguments may be mapped over or used to disable sub-pipelines,
rather than just giving null as inputs the arguments given to each pipeline
input parameter are as follows:

- boolean inputs get false.
- Untyped maps, strings, numeric types and file types get null.
- Arrays get a single element.
- Typed maps get a single element with a key named "null".
package syntax
func GenerateCall(target Callable, args map[string]Exp) *CallStm {
	c := &CallStm{
		Modifiers: &Modifiers{Bindings: new(BindStms)},
		Id:        target.GetId(),
		DecId:     target.GetId(),
		Bindings: &BindStms{
			List: make([]*BindStm, 0, len(target.GetInParams().List)),
			Table: make(map[string]*BindStm,
				len(target.GetInParams().List)),
		},
	}
	for _, arg := range target.GetInParams().List {
		v := args[arg.GetId()]
		if v == nil {
			v = new(NullExp)
		}
		b := BindStm{
			Id:    arg.GetId(),
			Exp:   v,
			Tname: arg.GetTname(),
		}
		c.Bindings.List = append(c.Bindings.List, &b)
		c.Bindings.Table[b.Id] = &b
	}
	return c
}