# Automatically generated by /build/sagemath/src/sage-8.6/src/sage_setup/autogen/interpreters/generator.py.  Do not edit!
from sage.rings.complex_double cimport ComplexDoubleElement
import sage.rings.complex_double
cdef object CDF = sage.rings.complex_double.CDF

cdef extern from "solaris_fixes.h":
    pass

cdef extern from "complex.h":
    cdef double creal(double_complex)
    cdef double cimag(double_complex)
    cdef double_complex _Complex_I

cdef inline double_complex CDE_to_dz(zz):
    cdef ComplexDoubleElement z = <ComplexDoubleElement>(zz if isinstance(zz, ComplexDoubleElement) else CDF(zz))
    return z._complex.dat[0] + _Complex_I * z._complex.dat[1]

cdef inline ComplexDoubleElement dz_to_CDE(double_complex dz):
    cdef ComplexDoubleElement z = <ComplexDoubleElement>ComplexDoubleElement.__new__(ComplexDoubleElement)
    z._complex.dat[0] = creal(dz)
    z._complex.dat[1] = cimag(dz)
    return z

cdef public bint cdf_py_call_helper(object fn,
                                    int n_args,
                                    double_complex* args, double_complex* retval) except 0:
    py_args = []
    cdef int i
    for i from 0 <= i < n_args:
        py_args.append(dz_to_CDE(args[i]))
    py_result = fn(*py_args)
    cdef ComplexDoubleElement result
    if isinstance(py_result, ComplexDoubleElement):
        result = <ComplexDoubleElement>py_result
    else:
        result = CDF(py_result)
    retval[0] = CDE_to_dz(result)
    return 1



from cpython.ref cimport PyObject
cdef extern from "Python.h":
    void Py_DECREF(PyObject *o)
    void Py_INCREF(PyObject *o)
    void Py_CLEAR(PyObject *o)

    object PyList_New(Py_ssize_t len)
    ctypedef struct PyListObject:
        PyObject **ob_item

    ctypedef struct PyTupleObject:
        PyObject **ob_item

from cysignals.memory cimport check_allocarray, sig_free

from sage.ext.fast_callable cimport Wrapper

cdef extern from "sage/ext/interpreters/interp_cdf.c":
    double_complex interp_cdf(double_complex* args,
        double_complex* constants,
        PyObject** py_constants,
        double_complex* stack,
        int* code) except? -1094648119105371

cdef class Wrapper_cdf(Wrapper):
    # attributes are declared in corresponding .pxd file

    def __init__(self, args):
        Wrapper.__init__(self, args, metadata)
        cdef int i
        cdef int count
        count = args['args']
        self._n_args = count
        self._args = <double_complex*>check_allocarray(self._n_args, sizeof(double_complex))
        val = args['constants']
        self._n_constants = len(val)
        self._constants = <double_complex*>check_allocarray(self._n_constants, sizeof(double_complex))
        for i in range(len(val)):
            self._constants[i] = CDE_to_dz(val[i])
        val = args['py_constants']
        self._n_py_constants = len(val)
        self._list_py_constants = PyList_New(self._n_py_constants)
        self._py_constants = (<PyListObject *>self._list_py_constants).ob_item
        for i in range(len(val)):
            self._py_constants[i] = <PyObject *>val[i]; Py_INCREF(self._py_constants[i])
        count = args['stack']
        self._n_stack = count
        self._stack = <double_complex*>check_allocarray(self._n_stack, sizeof(double_complex))
        val = args['code']
        self._n_code = len(val)
        self._code = <int*>check_allocarray(self._n_code, sizeof(int))
        for i in range(len(val)):
            self._code[i] = val[i]

    def __dealloc__(self):
        cdef int i
        if self._args:
            sig_free(self._args)
        if self._constants:
            sig_free(self._constants)
        if self._stack:
            sig_free(self._stack)
        if self._code:
            sig_free(self._code)

    def __call__(self, *args):
        if self._n_args != len(args): raise ValueError
        cdef double_complex* c_args = self._args
        cdef int i
        for i from 0 <= i < len(args):
            self._args[i] = CDE_to_dz(args[i])
        return dz_to_CDE(interp_cdf(c_args
            , self._constants
            , self._py_constants
            , self._stack
            , self._code
            ))

    cdef bint call_c(self,
                     double_complex* args,
                     double_complex* result) except 0:
        result[0] = interp_cdf(args
            , self._constants
            , self._py_constants
            , self._stack
            , self._code
            )

        return 1

from sage.ext.fast_callable import CompilerInstrSpec, InterpreterMetadata
metadata = InterpreterMetadata(by_opname={
  'load_arg':
  (CompilerInstrSpec(0, 1, ['args']), 0),
  'load_const':
  (CompilerInstrSpec(0, 1, ['constants']), 1),
  'return':
  (CompilerInstrSpec(1, 0, []), 2),
  'py_call':
  (CompilerInstrSpec(0, 1, ['py_constants', 'n_inputs']), 3),
  'add':
  (CompilerInstrSpec(2, 1, []), 4),
  'sub':
  (CompilerInstrSpec(2, 1, []), 5),
  'mul':
  (CompilerInstrSpec(2, 1, []), 6),
  'div':
  (CompilerInstrSpec(2, 1, []), 7),
  'truediv':
  (CompilerInstrSpec(2, 1, []), 8),
  'pow':
  (CompilerInstrSpec(2, 1, []), 9),
  'ipow':
  (CompilerInstrSpec(1, 1, ['code']), 10),
  'neg':
  (CompilerInstrSpec(1, 1, []), 11),
  'invert':
  (CompilerInstrSpec(1, 1, []), 12),
  'abs':
  (CompilerInstrSpec(1, 1, []), 13),
  'sqrt':
  (CompilerInstrSpec(1, 1, []), 14),
  'sin':
  (CompilerInstrSpec(1, 1, []), 15),
  'cos':
  (CompilerInstrSpec(1, 1, []), 16),
  'tan':
  (CompilerInstrSpec(1, 1, []), 17),
  'asin':
  (CompilerInstrSpec(1, 1, []), 18),
  'acos':
  (CompilerInstrSpec(1, 1, []), 19),
  'atan':
  (CompilerInstrSpec(1, 1, []), 20),
  'sinh':
  (CompilerInstrSpec(1, 1, []), 21),
  'cosh':
  (CompilerInstrSpec(1, 1, []), 22),
  'tanh':
  (CompilerInstrSpec(1, 1, []), 23),
  'asinh':
  (CompilerInstrSpec(1, 1, []), 24),
  'acosh':
  (CompilerInstrSpec(1, 1, []), 25),
  'atanh':
  (CompilerInstrSpec(1, 1, []), 26),
  'exp':
  (CompilerInstrSpec(1, 1, []), 27),
  'log':
  (CompilerInstrSpec(1, 1, []), 28),
 },
 by_opcode=[
  ('load_arg',
   CompilerInstrSpec(0, 1, ['args'])),
  ('load_const',
   CompilerInstrSpec(0, 1, ['constants'])),
  ('return',
   CompilerInstrSpec(1, 0, [])),
  ('py_call',
   CompilerInstrSpec(0, 1, ['py_constants', 'n_inputs'])),
  ('add',
   CompilerInstrSpec(2, 1, [])),
  ('sub',
   CompilerInstrSpec(2, 1, [])),
  ('mul',
   CompilerInstrSpec(2, 1, [])),
  ('div',
   CompilerInstrSpec(2, 1, [])),
  ('truediv',
   CompilerInstrSpec(2, 1, [])),
  ('pow',
   CompilerInstrSpec(2, 1, [])),
  ('ipow',
   CompilerInstrSpec(1, 1, ['code'])),
  ('neg',
   CompilerInstrSpec(1, 1, [])),
  ('invert',
   CompilerInstrSpec(1, 1, [])),
  ('abs',
   CompilerInstrSpec(1, 1, [])),
  ('sqrt',
   CompilerInstrSpec(1, 1, [])),
  ('sin',
   CompilerInstrSpec(1, 1, [])),
  ('cos',
   CompilerInstrSpec(1, 1, [])),
  ('tan',
   CompilerInstrSpec(1, 1, [])),
  ('asin',
   CompilerInstrSpec(1, 1, [])),
  ('acos',
   CompilerInstrSpec(1, 1, [])),
  ('atan',
   CompilerInstrSpec(1, 1, [])),
  ('sinh',
   CompilerInstrSpec(1, 1, [])),
  ('cosh',
   CompilerInstrSpec(1, 1, [])),
  ('tanh',
   CompilerInstrSpec(1, 1, [])),
  ('asinh',
   CompilerInstrSpec(1, 1, [])),
  ('acosh',
   CompilerInstrSpec(1, 1, [])),
  ('atanh',
   CompilerInstrSpec(1, 1, [])),
  ('exp',
   CompilerInstrSpec(1, 1, [])),
  ('log',
   CompilerInstrSpec(1, 1, [])),
 ],
 ipow_range=(-2147483648, 2147483647))
