Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sage
Path: blob/develop/src/sage_setup/autogen/interpreters/internal/specs/base.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
"""Base classes for interpreter specs."""
13
14
from __future__ import print_function, absolute_import
15
16
from ..memory import (MemoryChunkConstants, MemoryChunkArguments,
17
MemoryChunkScratch)
18
from ..storage import StorageTypeAssignable, ty_int
19
20
21
class InterpreterSpec(object):
22
r"""
23
Each interpreter to be generated by this module is represented
24
by an InterpreterSpec.
25
"""
26
27
name = ''
28
29
def __init__(self):
30
r"""
31
Initialize an InterpreterSpec.
32
33
Initializes the following fields:
34
35
- ``c_header`` -- a code snippet to go at the top of the C
36
interpreter source file
37
- ``pxd_header`` -- a code snippet to go at the top of the
38
wrapper class .pxd file
39
- ``pyx_header`` -- a code snippet to go at the top of the
40
wrapper class source file
41
- ``err_return`` -- a string indicating the value to be
42
returned in case of a Python exception
43
- ``mc_code`` -- a memory chunk to use for the interpreted code
44
- ``extra_class_members`` -- Class members for the wrapper that
45
don't correspond to memory chunks
46
- ``extra_members_initialize`` -- Code to initialize
47
extra_class_members
48
49
EXAMPLES::
50
51
sage: from sage_setup.autogen.interpreters.internal import *
52
sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter
53
sage: from sage_setup.autogen.interpreters.internal.specs.rr import RRInterpreter
54
sage: interp = RDFInterpreter()
55
sage: interp.c_header
56
'#include <gsl/gsl_math.h>'
57
sage: interp.pxd_header
58
''
59
sage: interp.pyx_header
60
'cimport sage.libs.gsl.math # Add dependency on GSL'
61
sage: interp.err_return
62
'-1094648009105371'
63
sage: interp.mc_code
64
{MC:code}
65
sage: interp = RRInterpreter()
66
sage: interp.extra_class_members
67
''
68
sage: interp.extra_members_initialize
69
''
70
"""
71
self.c_header = ''
72
self.pxd_header = ''
73
self.pyx_header = ''
74
self.err_return = 'NULL'
75
self.mc_code = MemoryChunkConstants('code', ty_int)
76
self.extra_class_members = ''
77
self.extra_members_initialize = ''
78
79
def _set_opcodes(self):
80
r"""
81
Assign opcodes to the instructions in this interpreter.
82
83
Must be called at the end of __init__ by any subclass of
84
InterpreterSpec.
85
86
EXAMPLES::
87
88
sage: from sage_setup.autogen.interpreters.internal import *
89
sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter
90
sage: interp = RDFInterpreter()
91
sage: interp.instr_descs[5].opcode
92
5
93
"""
94
for i in range(len(self.instr_descs)):
95
self.instr_descs[i].opcode = i
96
97
98
class StackInterpreter(InterpreterSpec):
99
r"""
100
A subclass of InterpreterSpec, specialized for stack-based
101
interpreters. (Currently all interpreters are stack-based.)
102
"""
103
104
def __init__(self, type, mc_retval=None):
105
r"""
106
Initialize a StackInterpreter.
107
108
INPUT:
109
110
- type -- A StorageType; the basic type that this interpreter
111
operates on
112
- mc_retval -- default None; if not None, a special-purpose
113
MemoryChunk to use as a return value
114
115
Initializes the fields described in the documentation for
116
InterpreterSpec.__init__, as well as the following:
117
118
- mc_args, mc_constants, mc_stack -- MemoryChunk values
119
- return_type -- the type returned by the C interpreter (None for int,
120
where 1 means success and 0 means error)
121
- mc_retval -- None, or the MemoryChunk to use as a return value
122
- ipow_range -- the range of exponents supported by the ipow
123
instruction (default is False, meaning never use ipow)
124
- adjust_retval -- None, or a string naming a function to call
125
in the wrapper's __call__ to modify the return
126
value of the interpreter
127
- implement_call_c -- True if the wrapper should have a fast cdef call_c
128
method (that bypasses the Python call overhead)
129
(default: ``True``)
130
131
EXAMPLES::
132
133
sage: from sage_setup.autogen.interpreters.internal import *
134
sage: from sage_setup.autogen.interpreters.internal.specs.rdf import RDFInterpreter
135
sage: from sage_setup.autogen.interpreters.internal.specs.rr import RRInterpreter
136
sage: from sage_setup.autogen.interpreters.internal.specs.element import ElementInterpreter
137
sage: rdf = RDFInterpreter()
138
sage: rr = RRInterpreter()
139
sage: el = ElementInterpreter()
140
sage: rdf.mc_args
141
{MC:args}
142
sage: rdf.mc_constants
143
{MC:constants}
144
sage: rdf.mc_stack
145
{MC:stack}
146
sage: rr.mc_retval
147
{MC:retval}
148
sage: rr.return_type is None
149
True
150
sage: rdf.return_type.type
151
'double'
152
sage: rdf.implement_call_c
153
True
154
sage: el.implement_call_c
155
False
156
"""
157
super(StackInterpreter, self).__init__()
158
self.mc_args = MemoryChunkArguments('args', type)
159
self.mc_constants = MemoryChunkConstants('constants', type)
160
self.mc_stack = MemoryChunkScratch('stack', type, is_stack=True)
161
if isinstance(type, StorageTypeAssignable):
162
self.return_type = type
163
else:
164
self.return_type = None
165
self.mc_retval = mc_retval
166
self.ipow_range = False
167
self.adjust_retval = None
168
self.implement_call_c = True
169
170