Beispiel #1
0
func (self *Gen) genCall(code *ir.Code, call *ast.CallExpr) *obj {
	f := self.genExpr(code, call.Func) // evaluate the function first
	if f == nil {
		return nil
	}

	ft, isFunc := f.t.(*types.Func)
	if !isFunc {
		self.errorf(call.Token, "calling on a non-function")
		return nil
	}

	if len(call.Args) != len(ft.Args) {
		self.errorf(call.Token, "wrong number of arguments")
		return nil
	}

	var args []*obj
	for i, arg := range call.Args {
		o := self.genExpr(code, arg)
		if o == nil {
			return nil
		}
		if !types.Equals(o.t, ft.Args[i]) {
			self.errorf(call.Token, "wrong argument type")
			return nil
		}
		args = append(args, o)
	}

	// TODO: push the ret first
	ret := voidObj

	for _, o := range args {
		code.Push(o.o) // now we can push the stuff for call
	}

	code.Call(f.o)

	var pops []ir.Obj
	for _, o := range args {
		pops = append(pops, o.o)
	}
	code.Pop(pops...)

	return ret
}