Path: blob/develop/src/sage_setup/autogen/interpreters/internal/specs/element.py
4086 views
#*****************************************************************************1# Copyright (C) 2009 Carl Witty <[email protected]>2# Copyright (C) 2015 Jeroen Demeyer <[email protected]>3#4# This program is free software: you can redistribute it and/or modify5# it under the terms of the GNU General Public License as published by6# the Free Software Foundation, either version 2 of the License, or7# (at your option) any later version.8# http://www.gnu.org/licenses/9#*****************************************************************************1011from __future__ import print_function, absolute_import1213from .base import StackInterpreter14from .python import (MemoryChunkPyConstant, MemoryChunkPythonArguments,15PythonInterpreter)16from ..storage import ty_python17from ..utils import reindent_lines as ri181920class MemoryChunkElementArguments(MemoryChunkPythonArguments):21r"""22A special-purpose memory chunk, for the Python-object based23interpreters that want to process (and perhaps modify) the data.2425We allocate a new list on every call to hold the modified arguments.26That's not strictly necessary -- we could pre-allocate a list and map into27it -- but this lets us use simpler code for a very-likely-negligible28efficiency cost. (The Element interpreter is going to allocate lots of29objects as it runs, anyway.)30"""3132def setup_args(self):33r"""34Handle the arguments of __call__. Note: This hardcodes35"self._domain".3637EXAMPLES::3839sage: from sage_setup.autogen.interpreters.internal import *40sage: from sage_setup.autogen.interpreters.internal.specs.element import *41sage: mc = MemoryChunkElementArguments('args', ty_python)42sage: mc.setup_args()43'mapped_args = [self._domain(a) for a in args]\n'44"""45return "mapped_args = [self._domain(a) for a in args]\n"4647def pass_argument(self):48r"""49Pass the innards of the argument tuple to the interpreter.5051EXAMPLES::5253sage: from sage_setup.autogen.interpreters.internal import *54sage: from sage_setup.autogen.interpreters.internal.specs.element import *55sage: mc = MemoryChunkElementArguments('args', ty_python)56sage: mc.pass_argument()57'(<PyListObject*>mapped_args).ob_item'58"""59return "(<PyListObject*>mapped_args).ob_item"606162class ElementInterpreter(PythonInterpreter):63r"""64A subclass of PythonInterpreter, specifying an interpreter over65Sage elements with a particular parent.6667This is very similar to the PythonInterpreter, but after every68instruction, the result is checked to make sure it actually an69element with the correct parent; if not, we attempt to convert it.7071Uses the same instructions (with the same implementation) as72PythonInterpreter.73"""7475name = 'el'7677def __init__(self):78r"""79Initialize an ElementInterpreter.8081EXAMPLES::8283sage: from sage_setup.autogen.interpreters.internal import *84sage: from sage_setup.autogen.interpreters.internal.specs.element import *85sage: interp = ElementInterpreter()86sage: interp.name87'el'88sage: interp.mc_args89{MC:args}90sage: interp.chunks91[{MC:args}, {MC:constants}, {MC:stack}, {MC:domain}, {MC:code}]92sage: instrs = dict([(ins.name, ins) for ins in interp.instr_descs])93sage: instrs['add']94add: SS->S = 'o0 = PyNumber_Add(i0, i1);'95sage: instrs['py_call']96py_call: *->S = '\nPyObject *py_args...CREF(py_args);\n'97"""9899super(ElementInterpreter, self).__init__()100# PythonInterpreter.__init__ gave us a MemoryChunkPythonArguments.101# Override with MemoryChunkElementArguments.102self.mc_args = MemoryChunkElementArguments('args', ty_python)103self.mc_domain_info = MemoryChunkPyConstant('domain')104self.chunks = [self.mc_args, self.mc_constants, self.mc_stack,105self.mc_domain_info, self.mc_code]106self.c_header = ri(0, """107#define CHECK(x) do_check(&(x), domain)108109static inline int do_check(PyObject **x, PyObject *domain) {110if (*x == NULL) return 0;111PyObject *new_x = el_check_element(*x, domain);112Py_DECREF(*x);113*x = new_x;114if (*x == NULL) return 0;115return 1;116}117""")118119self.pyx_header += ri(0, """120from sage.structure.element cimport Element121122cdef public object el_check_element(object v, parent):123cdef Element v_el124125if isinstance(v, Element):126v_el = <Element>v127if v_el._parent is parent:128return v_el129130return parent(v)131"""[1:])132133134