1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
# This file is part of PeachPy package and is licensed under the Simplified BSD license.
# See license.rst for the full text of the license.
class Argument(object):
"""
Function argument.
An argument must have a C type and a name.
:ivar c_type: the type of the argument in C
:type c_type: :class:`peachpy.c.types.Type`
:ivar name: the name of the argument
:type name: str
"""
def __init__(self, c_type, name=None):
"""
:param peachpy.c.types.Type c_type: the type of the argument in C.
When Go function is generated, the type is automatically converted to similar Go type.
Note that the ``short``, ``int``, ``long``, and ``long long`` types do not have an equivalents in Go.
In particular, C's ``int`` type is not an equivalent of Go's ``int`` type. To get Go's ``int`` and ``uint``
types use ``ptrdiff_t`` and ``size_t`` correspondingly.
:param str name: the name of the argument. If the name is not provided explicitly, PeachPy tries to parse it
from the caller code. The name must follow the C rules for identifiers:
- It can contain only Latin letters, digits, and underscore symbol
- It can not start with a digit
- It can not start with double underscore (these names are reserved for PeachPy)
- Name must be unique among the function arguments
"""
from peachpy.c.types import Type
if not isinstance(c_type, Type):
raise TypeError("%s is not a C type" % str(c_type))
self.c_type = c_type
if name is None:
import inspect
import re
_, _, _, _, caller_lines, _ = inspect.stack()[1]
if caller_lines is None:
raise ValueError("Argument name is not specified and the caller context is not available")
source_line = caller_lines[0].strip()
match = re.match("(?:\\w+\\.)*(\\w+)\\s*=\\s*(?:\\w+\\.)*Argument\\(.+\\)", source_line)
if match:
name = match.group(1)
while name.startswith("_"):
name = name[1:]
if name.endswith("argument") or name.endswith("Argument"):
name = name[:-len("argument")]
if name.endswith("arg") or name.endswith("Arg"):
name = name[:-len("arg")]
while name.endswith("_"):
name = name[:-1]
if not name:
raise ValueError("Argument name is not specified and can not be parsed from the code")
from peachpy.name import Name
Name.check_name(name)
self.name = name
def __str__(self):
return str(self.c_type) + " " + self.name
def __repr__(self):
return str(self)
def __eq__(self, other):
return isinstance(other, Argument) and self.c_type == other.c_type and self.name == other.name
def __ne__(self, other):
return not isinstance(other, Argument) or self.c_type != other.c_type or self.name != other.name
@property
def is_floating_point(self):
return self.c_type.is_floating_point
@property
def is_codeunit(self):
return self.c_type.is_codeunit
@property
def is_integer(self):
return self.c_type.is_integer
@property
def is_unsigned_integer(self):
return self.c_type.is_unsigned_integer
@property
def is_signed_integer(self):
return self.c_type.is_signed_integer
@property
def is_size_integer(self):
return self.c_type.is_size_integer
@property
def is_pointer_integer(self):
return self.c_type.is_pointer_integer
@property
def is_pointer(self):
return self.c_type.is_pointer
@property
def is_vector(self):
return self.c_type.is_vector
@property
def is_mask(self):
return self.c_type.is_mask
@property
def size(self):
return self.c_type.size
|