Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sage
Path: blob/develop/src/sage_setup/autogen/interpreters/internal/specs/element.py
4086 views
1
#*****************************************************************************
2
# Copyright (C) 2009 Carl Witty <[email protected]>
3
# Copyright (C) 2015 Jeroen Demeyer <[email protected]>
4
#
5
# This program is free software: you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation, either version 2 of the License, or
8
# (at your option) any later version.
9
# http://www.gnu.org/licenses/
10
#*****************************************************************************
11
12
from __future__ import print_function, absolute_import
13
14
from .base import StackInterpreter
15
from .python import (MemoryChunkPyConstant, MemoryChunkPythonArguments,
16
PythonInterpreter)
17
from ..storage import ty_python
18
from ..utils import reindent_lines as ri
19
20
21
class MemoryChunkElementArguments(MemoryChunkPythonArguments):
22
r"""
23
A special-purpose memory chunk, for the Python-object based
24
interpreters that want to process (and perhaps modify) the data.
25
26
We allocate a new list on every call to hold the modified arguments.
27
That's not strictly necessary -- we could pre-allocate a list and map into
28
it -- but this lets us use simpler code for a very-likely-negligible
29
efficiency cost. (The Element interpreter is going to allocate lots of
30
objects as it runs, anyway.)
31
"""
32
33
def setup_args(self):
34
r"""
35
Handle the arguments of __call__. Note: This hardcodes
36
"self._domain".
37
38
EXAMPLES::
39
40
sage: from sage_setup.autogen.interpreters.internal import *
41
sage: from sage_setup.autogen.interpreters.internal.specs.element import *
42
sage: mc = MemoryChunkElementArguments('args', ty_python)
43
sage: mc.setup_args()
44
'mapped_args = [self._domain(a) for a in args]\n'
45
"""
46
return "mapped_args = [self._domain(a) for a in args]\n"
47
48
def pass_argument(self):
49
r"""
50
Pass the innards of the argument tuple to the interpreter.
51
52
EXAMPLES::
53
54
sage: from sage_setup.autogen.interpreters.internal import *
55
sage: from sage_setup.autogen.interpreters.internal.specs.element import *
56
sage: mc = MemoryChunkElementArguments('args', ty_python)
57
sage: mc.pass_argument()
58
'(<PyListObject*>mapped_args).ob_item'
59
"""
60
return "(<PyListObject*>mapped_args).ob_item"
61
62
63
class ElementInterpreter(PythonInterpreter):
64
r"""
65
A subclass of PythonInterpreter, specifying an interpreter over
66
Sage elements with a particular parent.
67
68
This is very similar to the PythonInterpreter, but after every
69
instruction, the result is checked to make sure it actually an
70
element with the correct parent; if not, we attempt to convert it.
71
72
Uses the same instructions (with the same implementation) as
73
PythonInterpreter.
74
"""
75
76
name = 'el'
77
78
def __init__(self):
79
r"""
80
Initialize an ElementInterpreter.
81
82
EXAMPLES::
83
84
sage: from sage_setup.autogen.interpreters.internal import *
85
sage: from sage_setup.autogen.interpreters.internal.specs.element import *
86
sage: interp = ElementInterpreter()
87
sage: interp.name
88
'el'
89
sage: interp.mc_args
90
{MC:args}
91
sage: interp.chunks
92
[{MC:args}, {MC:constants}, {MC:stack}, {MC:domain}, {MC:code}]
93
sage: instrs = dict([(ins.name, ins) for ins in interp.instr_descs])
94
sage: instrs['add']
95
add: SS->S = 'o0 = PyNumber_Add(i0, i1);'
96
sage: instrs['py_call']
97
py_call: *->S = '\nPyObject *py_args...CREF(py_args);\n'
98
"""
99
100
super(ElementInterpreter, self).__init__()
101
# PythonInterpreter.__init__ gave us a MemoryChunkPythonArguments.
102
# Override with MemoryChunkElementArguments.
103
self.mc_args = MemoryChunkElementArguments('args', ty_python)
104
self.mc_domain_info = MemoryChunkPyConstant('domain')
105
self.chunks = [self.mc_args, self.mc_constants, self.mc_stack,
106
self.mc_domain_info, self.mc_code]
107
self.c_header = ri(0, """
108
#define CHECK(x) do_check(&(x), domain)
109
110
static inline int do_check(PyObject **x, PyObject *domain) {
111
if (*x == NULL) return 0;
112
PyObject *new_x = el_check_element(*x, domain);
113
Py_DECREF(*x);
114
*x = new_x;
115
if (*x == NULL) return 0;
116
return 1;
117
}
118
""")
119
120
self.pyx_header += ri(0, """
121
from sage.structure.element cimport Element
122
123
cdef public object el_check_element(object v, parent):
124
cdef Element v_el
125
126
if isinstance(v, Element):
127
v_el = <Element>v
128
if v_el._parent is parent:
129
return v_el
130
131
return parent(v)
132
"""[1:])
133
134