subroutine do_scalar (func,form,dimr,result,noper,ioper,operand,error)
  use sic_dependencies_interfaces
  use sic_interfaces
  use gildas_def
  use sic_expressions
  use sic_types
  use gbl_message
  use gbl_format
  !---------------------------------------------------------------------
  ! @ no-interface (because of argument type mismatch)
  !  Buffer routine used to call a function whose address is known.
  ! Version for SCALAR functions
  ! Arguments:
  !       FUNC            Ext     Function to call                Input
  !       FORM            I       Precision of result             Input
  !       RESULT          I       Pointer to result               Input
  !       NOPER           I       Number of operands              Input
  !       IOPER           I       Pointers to operands            Input
  !---------------------------------------------------------------------
  external                                 :: func          !
  integer                                  :: form          !
  integer(kind=size_length)                :: dimr          ! Dimension of result (input)
  integer                                  :: result        !
  integer                                  :: noper         !
  integer                                  :: ioper(noper)  !
  type(sic_descriptor_t)                   :: operand(0:maxoper)  ! List of operands (input)
  logical,                   intent(inout) :: error         ! Logical error flag
  ! Global
  include 'gbl_memory.inc'
  ! Local
  character(len=*), parameter :: rname='EVALUATE'
  integer(kind=address_length) :: ipnt1,ipnt2,ipnt3,ipntr
  character(len=message_length) :: mess
  !
  if (noper.gt.3) then
    call sic_message(seve%e,rname,'Internal logic error')
    error = .true.
    return
  endif
  !
  ipnt1 = gag_pointer(operand(ioper(1))%addr,memory)
  ipntr = gag_pointer(operand(result)%addr,memory)
  !
  if (form.eq.fmt_r8) then
    ! Real*8 calls
    if (noper.eq.1) then
      call do_dble_loop1(func,dimr,memory(ipntr),  &
            operand(ioper(1))%size/2,memory(ipnt1),error)
    elseif (noper.eq.2) then
      ipnt2 = gag_pointer(operand(ioper(2))%addr,memory)
      call do_dble_loop2(func,dimr,memory(ipntr),  &
            operand(ioper(1))%size/2,memory(ipnt1),  &
            operand(ioper(2))%size/2,memory(ipnt2),error)
    elseif (noper.eq.3) then
      ipnt2 = gag_pointer(operand(ioper(2))%addr,memory)
      ipnt3 = gag_pointer(operand(ioper(3))%addr,memory)
      call do_dble_loop3(func,dimr,memory(ipntr),  &
            operand(ioper(1))%size/2,memory(ipnt1),  &
            operand(ioper(2))%size/2,memory(ipnt2),  &
            operand(ioper(3))%size/2,memory(ipnt3),  &
            error)
    endif
    !
  elseif (form.eq.fmt_r4) then
    ! Real*4 calls
    if (noper.eq.1) then
      call do_real_loop1(func,dimr,memory(ipntr),  &
              operand(ioper(1))%size,memory(ipnt1),error)
    elseif (noper.eq.2) then
      ipnt2 = gag_pointer(operand(ioper(2))%addr,memory)
      call do_real_loop2(func,dimr,memory(ipntr),  &
              operand(ioper(1))%size,memory(ipnt1),  &
              operand(ioper(2))%size,memory(ipnt2),error)
    elseif (noper.eq.3) then
      ipnt2 = gag_pointer(operand(ioper(2))%addr,memory)
      ipnt3 = gag_pointer(operand(ioper(3))%addr,memory)
      call do_real_loop3(func,dimr,memory(ipntr),  &
              operand(ioper(1))%size,memory(ipnt1),  &
              operand(ioper(2))%size,memory(ipnt2),  &
              operand(ioper(3))%size,memory(ipnt3),  &
              error)
    endif
    !
  elseif (form.eq.fmt_i8) then
    ! Integer*8 calls
    if (noper.eq.1) then
      call do_long_loop1(func,dimr,memory(ipntr),  &
            operand(ioper(1))%size/2,memory(ipnt1),error)
    elseif (noper.eq.2) then
      ipnt2 = gag_pointer(operand(ioper(2))%addr,memory)
      call do_long_loop2(func,dimr,memory(ipntr),  &
            operand(ioper(1))%size/2,memory(ipnt1),  &
            operand(ioper(2))%size/2,memory(ipnt2),error)
    elseif (noper.eq.3) then
      ipnt2 = gag_pointer(operand(ioper(2))%addr,memory)
      ipnt3 = gag_pointer(operand(ioper(3))%addr,memory)
      call do_long_loop3(func,dimr,memory(ipntr),  &
            operand(ioper(1))%size/2,memory(ipnt1),  &
            operand(ioper(2))%size/2,memory(ipnt2),  &
            operand(ioper(3))%size/2,memory(ipnt3),  &
            error)
    endif
    !
  else
    ! Unsupported precision
    write(mess,100) 'Invalid precision ',form
    call sic_message(seve%e,rname,mess)
    error = .true.
  endif
  return
  !
100 format (a,i3,a)
end subroutine do_scalar
!
subroutine do_vector (func,form,dimr,result,noper,ioper,operand,code,error)
  use sic_dependencies_interfaces
  use sic_interfaces
  use gildas_def
  use sic_expressions
  use sic_dictionaries
  use sic_types
  use gbl_message
  use gbl_format
  !---------------------------------------------------------------------
  ! @ no-interface (because of argument type mismatch)
  !  Buffer routine used to call a function whose address is known.
  ! Version for VECTOR function
  ! Arguments:
  !       FUNC            Ext     Function to call                Input
  !       FORM            I       Precision of result             Input
  !       RESULT          I       Pointer to result               Input
  !       NOPER           I       Number of operands              Input
  !       IOPER           I       Pointers to operands            Input
  !       CODE            I       Code of operation               Input
  !       ERROR           L       Logical error flag              Output
  ! Written       11-Feb-1987     T.Forveille
  !---------------------------------------------------------------------
  integer, external :: func                 !
  integer :: form                           !
  integer(kind=size_length) :: dimr         ! Dimension of result (input)
  integer :: result                         !
  integer :: noper                          !
  integer :: ioper(noper)                   !
  type(sic_descriptor_t) :: operand(0:maxoper)  ! List of operands (input)
  integer :: code                           !
  logical :: error                          !
  ! Global
  include 'gbl_memory.inc'
  ! Local
  character(len=*), parameter :: rname='EVALUATE'
  integer(kind=address_length) :: ipnt1,ipnt2,ipntr
  integer ::  i,isgood
  integer(kind=size_length) :: nelem(noper)
  integer(kind=address_length) :: nwords(noper)
  character(len=message_length) :: mess
  !
  ! A Python function can be called with no argument number check.
  if ((noper.gt.2).and.(code.ne.code_pyfunc)) then
    call sic_message(seve%e,rname,'Internal logic error')
    error = .true.
    return
  endif
  !
  ipnt1 = gag_pointer(operand(ioper(1))%addr,memory)
  ipntr = gag_pointer(operand(result)%addr,memory)
  !
  isgood = 0   ! Avoid initialization warning
  if (form.eq.fmt_r8) then
    ! Real*8 calls
    if (code.eq.code_pyfunc) then
      do i=1,noper
        nelem(i)  = operand(ioper(i))%size/2
        nwords(i) = gag_pointer(operand(ioper(i))%addr,memory)
      enddo
      isgood = func (noper,nelem,nwords,dimr,memory(ipntr))
    elseif (noper.eq.1) then
      isgood = func (dimr,memory(ipntr),  &
               operand(ioper(1))%size/2,memory(ipnt1),0,0)
    elseif (noper.eq.2) then
      ipnt2 = gag_pointer(operand(ioper(2))%addr,memory)
      isgood = func (dimr,memory(ipntr),              &
               operand(ioper(1))%size/2,memory(ipnt1),  &
               operand(ioper(2))%size/2,memory(ipnt2))
    endif
    !
  elseif (form.eq.fmt_r4) then
    ! Real*4 calls
    if (code.eq.code_pyfunc) then
      do i=1,noper
        nelem(i)  = operand(ioper(i))%size
        nwords(i) = gag_pointer(operand(ioper(i))%addr,memory)
      enddo
      isgood = func (noper,nelem,nwords,dimr,memory(ipntr))
    elseif (noper.eq.1) then
      isgood = func (dimr,memory(ipntr),  &
               operand(ioper(1))%size,memory(ipnt1),0,0)
    elseif (noper.eq.2) then
      ipnt2 = gag_pointer(operand(ioper(2))%addr,memory)
      isgood = func(dimr,memory(ipntr),             &
               operand(ioper(1))%size,memory(ipnt1),  &
               operand(ioper(2))%size,memory(ipnt2))
    endif
    !
  elseif (form.eq.fmt_i8) then
    ! Integer*8 calls
    if (code.eq.code_pyfunc) then
      do i=1,noper
        nelem(i)  = operand(ioper(i))%size/2
        nwords(i) = gag_pointer(operand(ioper(i))%addr,memory)
      enddo
      isgood = func (noper,nelem,nwords,dimr,memory(ipntr))
    elseif (noper.eq.1) then
      isgood = func (dimr,memory(ipntr),  &
               operand(ioper(1))%size/2,memory(ipnt1),0,0)
    elseif (noper.eq.2) then
      ipnt2 = gag_pointer(operand(ioper(2))%addr,memory)
      isgood = func (dimr,memory(ipntr),              &
               operand(ioper(1))%size/2,memory(ipnt1),  &
               operand(ioper(2))%size/2,memory(ipnt2))
    endif
    !
  else
    ! Unsupported precision
    write(mess,100) 'Invalid precision ',form
    call sic_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  error = isgood.ne.0
  !
100 format (a,i3,a)
end subroutine do_vector
