# Automatically generated by ext/gen_interpreters.py.  Do not edit!

include "sage/ext/stdsage.pxi"
from cpython cimport PyObject
cdef extern from "Python.h":
    void Py_DECREF(PyObject *o)
    void Py_INCREF(PyObject *o)
    void Py_CLEAR(PyObject *o)

cdef extern from "listobject.h":
    object PyList_New(Py_ssize_t len)
    ctypedef struct PyListObject:
        PyObject **ob_item

cdef extern from "tupleobject.h":
    ctypedef struct PyTupleObject:
        PyObject **ob_item

from sage.ext.fast_callable cimport Wrapper
from sage.structure.element cimport Element

cdef public object el_check_element(object v, parent):
    cdef Element v_el

    if PY_TYPE_CHECK(v, Element):
        v_el = <Element>v
        if v_el._parent is parent:
            return v_el

    return parent(v)


cdef extern from "interp_el.h":
    object interp_el(PyObject** args,
        PyObject** constants,
        PyObject** stack,
        PyObject* domain,
        int* code)
cdef class Wrapper_el(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
        val = args['constants']
        self._n_constants = len(val)
        self._list_constants = PyList_New(self._n_constants)
        self._constants = (<PyListObject *>self._list_constants).ob_item
        for i in range(len(val)):
            self._constants[i] = <PyObject *>val[i]; Py_INCREF(self._constants[i])
        count = args['stack']
        self._n_stack = count
        self._list_stack = PyList_New(self._n_stack)
        self._stack = (<PyListObject *>self._list_stack).ob_item
        self._domain = args['domain']
        val = args['code']
        self._n_code = len(val)
        self._code = <int*>sage_malloc(sizeof(int) * len(val))
        if self._code == NULL: raise MemoryError
        for i in range(len(val)):
            self._code[i] = val[i]

    def __dealloc__(self):
        cdef int i
        if self._code:
            sage_free(self._code)

    def __call__(self, *args):
        if self._n_args != len(args): raise ValueError
        mapped_args = map(self._domain, args)
        try:
            return interp_el((<PyListObject*>mapped_args).ob_item
                , self._constants
                , self._stack
                , <PyObject*>self._domain
                , self._code
                )
        except BaseException:
            for i in range(self._n_stack):
                Py_CLEAR(self._stack[i])
            raise


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, ['constants', 'n_inputs']), 3),
  'add':
  (CompilerInstrSpec(2, 1, []), 4),
  'sub':
  (CompilerInstrSpec(2, 1, []), 5),
  'mul':
  (CompilerInstrSpec(2, 1, []), 6),
  'div':
  (CompilerInstrSpec(2, 1, []), 7),
  'pow':
  (CompilerInstrSpec(2, 1, []), 8),
  'ipow':
  (CompilerInstrSpec(1, 1, ['constants']), 9),
  'neg':
  (CompilerInstrSpec(1, 1, []), 10),
  'invert':
  (CompilerInstrSpec(1, 1, []), 11),
  'abs':
  (CompilerInstrSpec(1, 1, []), 12),
 },
 by_opcode=[
  ('load_arg',
   CompilerInstrSpec(0, 1, ['args'])),
  ('load_const',
   CompilerInstrSpec(0, 1, ['constants'])),
  ('return',
   CompilerInstrSpec(1, 0, [])),
  ('py_call',
   CompilerInstrSpec(0, 1, ['constants', 'n_inputs'])),
  ('add',
   CompilerInstrSpec(2, 1, [])),
  ('sub',
   CompilerInstrSpec(2, 1, [])),
  ('mul',
   CompilerInstrSpec(2, 1, [])),
  ('div',
   CompilerInstrSpec(2, 1, [])),
  ('pow',
   CompilerInstrSpec(2, 1, [])),
  ('ipow',
   CompilerInstrSpec(1, 1, ['constants'])),
  ('neg',
   CompilerInstrSpec(1, 1, [])),
  ('invert',
   CompilerInstrSpec(1, 1, [])),
  ('abs',
   CompilerInstrSpec(1, 1, [])),
 ],
 ipow_range=True)
