Skip to content

Commit

Permalink
Updated field sizeof implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
MatrixEditor committed Apr 24, 2024
1 parent 7951726 commit f4a01cb
Show file tree
Hide file tree
Showing 12 changed files with 751 additions and 27 deletions.
29 changes: 29 additions & 0 deletions include/caterpillar/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,5 +208,34 @@ PyAPI_DATA(PyTypeObject) CpFieldAtom_Type;

#define CpFieldAtom_HEAD CpFieldAtomObject ob_base;

// -----------------------------------------------------------------------------
// field C atom
typedef struct _fieldcatomobj
{
CpCAtom_HEAD;
} CpFieldCAtomObject;

/// Field C atom type
PyAPI_DATA(PyTypeObject) CpFieldCAtom_Type;

/**
* @brief Check whether the given object is a field C atom
*
* @param v the object to check
* @return true if the object is a field C atom
* @return false if the object is not a field C atom
*/
#define CpFieldCAtom_CheckExact(v) Py_IS_TYPE((v), &CpFieldCAtom_Type)

/**
* @brief Check whether the given object is a field C atom
*
* @param v the object to check
* @return true if the object is a field C atom
* @return false if the object is not a field C atom
*/
#define CpFieldCAtom_Check(v) PyObject_TypeCheck((v), &CpFieldCAtom_Type)

#define CpFieldCAtom_HEAD CpFieldCAtomObject ob_base;

#endif
38 changes: 28 additions & 10 deletions src/atomobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,23 @@ cp_atom_dealloc(CpAtomObject* self)
}

static int
cp_atom_init(CpAtomObject* self, PyObject* args, PyObject* kw)
{
if ((args && PyTuple_Size(args)) || (kw && PyDict_Size(kw))) {
PyErr_SetString(PyExc_TypeError,
"atoms cannot be initialized with arguments");
return -1;
}
return 0;
}

static PyObject*
cp_atom_pack(CpAtomObject* self, PyObject* args, PyObject* kw)
{
PyErr_Format(PyExc_NotImplementedError,
"The atom of type '%s' cannot be packed (missing __pack__)",
Py_TYPE(self)->tp_name);
return -1;
return NULL;
}

static PyObject*
Expand Down Expand Up @@ -132,7 +143,7 @@ PyTypeObject CpAtom_Type = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
(initproc)cp_atom_init, /* tp_init */
0, /* tp_alloc */
cp_atom_new, /* tp_new */
0, /* tp_free */
Expand Down Expand Up @@ -178,46 +189,53 @@ cp_catom_init(CpCAtomObject* self, PyObject* args, PyObject* kw)
// We don't have to initialize anything here, because subclasses
// will overload the `__init__` method and place their method
// implementations.
if ((args && PyTuple_Size(args)) || (kw && PyDict_Size(kw))) {
PyErr_SetString(PyExc_TypeError,
"catoms cannot be initialized with arguments");
return -1;
}
return 0;
}

static int
static PyObject*
cp_catom_pack(CpCAtomObject* self, PyObject* args, PyObject* kw)
{
if (self->ob_pack == NULL) {
PyErr_Format(PyExc_NotImplementedError,
"The atom of type '%s' cannot be packed (missing __pack__)",
Py_TYPE(self)->tp_name);
return -1;
return NULL;
}

static char* kwlist[] = { "op", "context", NULL };
PyObject *op = NULL, *context = NULL;
if (PyArg_ParseTupleAndKeywords(args, kw, "OO", kwlist, &op, &context) < 0) {
return -1;
return NULL;
}

return self->ob_pack((PyObject*)self, op, context);
return self->ob_pack((PyObject*)self, op, context) ? Py_NewRef(Py_None)
: NULL;
}

static int
static PyObject*
cp_catom_pack_many(CpCAtomObject* self, PyObject* args, PyObject* kw)
{
if (self->ob_pack_many == NULL) {
PyErr_Format(
PyExc_NotImplementedError,
"The atom of type '%s' cannot be packed (missing __pack_many__)",
Py_TYPE(self)->tp_name);
return -1;
return NULL;
}

static char* kwlist[] = { "ops", "context", NULL };
PyObject *ops = NULL, *context = NULL;
if (PyArg_ParseTupleAndKeywords(args, kw, "OO", kwlist, &ops, &context) < 0) {
return -1;
return NULL;
}

return self->ob_pack_many((PyObject*)self, ops, context);
return self->ob_pack_many((PyObject*)self, ops, context) ? Py_NewRef(Py_None)
: NULL;
}

static PyObject*
Expand Down
235 changes: 235 additions & 0 deletions src/caterpillar/_core.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
from _typeshed import Incomplete
from typing import Any

DefaultOption: DefaultOptionType
FIELD_OPTIONS: set
F_DYNAMIC: Option
F_SEQUENTIAL: Option
HOST_ARCH: Arch
InvalidDefault: InvalidDefaultType
NATIVE_ENDIAN: Endian
STRUCT_OPTIONS: set
S_DISCARD_UNNAMED: Option
S_EVAL_ANNOTATIONS: Option
S_REPLACE_TYPES: Option
S_SLOTS: Option
S_UNION: Option

class Arch:
name: Incomplete
ptr_size: Incomplete
def __init__(self, *args, **kwargs) -> None: ...
def __call__(self, *args, **kwargs): ...
def __hash__(self) -> int: ...

class BinaryExpr:
expr: Incomplete
lhs: Incomplete
rhs: Incomplete
def __init__(self, *args, **kwargs) -> None: ...
def __call__(self, *args, **kwargs): ...

class Context(dict):
def __init__(self, *args, **kwargs) -> None: ...
def __context_getattr__(self, *args, **kwargs): ...

class ContextPath:
path: Incomplete
def __init__(self, path) -> Any: ...
def __add__(self, other): ...
def __and__(self, other): ...
def __call__(self, *args, **kwargs): ...
def __eq__(self, other: object) -> bool: ...
def __floordiv__(self, other): ...
def __ge__(self, other: object) -> bool: ...
def __gt__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def __invert__(self): ...
def __le__(self, other: object) -> bool: ...
def __lshift__(self, other): ...
def __lt__(self, other: object) -> bool: ...
def __matmul__(self, *args, **kwargs): ...
def __mod__(self, other): ...
def __mul__(self, other): ...
def __ne__(self, other: object) -> bool: ...
def __neg__(self): ...
def __or__(self, other): ...
def __pos__(self): ...
def __pow__(self, other): ...
def __radd__(self, other): ...
def __rand__(self, other): ...
def __rfloordiv__(self, other): ...
def __rlshift__(self, other): ...
def __rmatmul__(self, *args, **kwargs): ...
def __rmod__(self, other): ...
def __rmul__(self, other): ...
def __ror__(self, other): ...
def __rpow__(self, other): ...
def __rrshift__(self, other): ...
def __rshift__(self, other): ...
def __rsub__(self, other): ...
def __rtruediv__(self, other): ...
def __rxor__(self, other): ...
def __size__(self, *args, **kwargs): ...
def __sub__(self, other): ...
def __truediv__(self, other): ...
def __type__(self, *args, **kwargs): ...
def __xor__(self, other): ...

class DefaultOptionType:
@classmethod
def __init__(cls, *args, **kwargs) -> None: ...

class Endian:
ch: Incomplete
name: Incomplete
def __init__(self, *args, **kwargs) -> None: ...
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: object) -> bool: ...
def __gt__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def __le__(self, other: object) -> bool: ...
def __lt__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...

class Field:
arch: Incomplete
atom: Incomplete
condition: Incomplete
default: Incomplete
endian: Incomplete
length: Incomplete
name: Incomplete
offset: Incomplete
options: Incomplete
switch: Incomplete
def __init__(self, *args, **kwargs) -> None: ...
def __add__(self, other): ...
def __floordiv__(self, other): ...
def __getitem__(self, index): ...
def __matmul__(self, *args, **kwargs): ...
def __or__(self, other): ...
def __radd__(self, other): ...
def __rfloordiv__(self, other): ...
def __rmatmul__(self, *args, **kwargs): ...
def __ror__(self, other): ...
def __rrshift__(self, other): ...
def __rshift__(self, other): ...
def __rxor__(self, other): ...
def __xor__(self, other): ...

class InvalidDefaultType:
@classmethod
def __init__(cls, *args, **kwargs) -> None: ...

class Option:
name: Incomplete
value: Incomplete
def __init__(self, *args, **kwargs) -> None: ...
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: object) -> bool: ...
def __gt__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def __le__(self, other: object) -> bool: ...
def __lt__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...

class State:
globals: Incomplete
io: Incomplete
offset_table: Incomplete
def __init__(self, *args, **kwargs) -> None: ...
def read(self, *args, **kwargs): ...
def seek(self, *args, **kwargs): ...
def tell(self, *args, **kwargs): ...
def write(self, *args, **kwargs): ...

class Struct(fieldatom):
members: Incomplete
model: Incomplete
options: Incomplete
def __init__(self, *args, **kwargs) -> None: ...

class UnaryExpr:
expr: Incomplete
value: Incomplete
def __init__(self, expr, value) -> Any: ...
def __call__(self, *args, **kwargs): ...
def __hash__(self) -> int: ...

class atom:
@classmethod
def __init__(cls, *args, **kwargs) -> None: ...
def __pack__(self, obj, ctx) -> Any: ...
def __size__(self, ctx) -> Any: ...
def __type__(self) -> Any: ...
def __unpack__(self, ctx) -> Any: ...

class catom(atom):
def __init__(self, *args, **kwargs) -> None: ...
def __pack__(self, *args, **kwargs): ...
def __pack_many__(self, *args, **kwargs): ...
def __size__(self, *args, **kwargs): ...
def __type__(self, *args, **kwargs): ...
def __unpack__(self, *args, **kwargs): ...
def __unpack_many__(self, *args, **kwargs): ...

class fieldatom(atom):
@classmethod
def __init__(cls, *args, **kwargs) -> None: ...
def __add__(self, other): ...
def __floordiv__(self, other): ...
def __getitem__(self, index): ...
def __matmul__(self, *args, **kwargs): ...
def __or__(self, other): ...
def __radd__(self, other): ...
def __rfloordiv__(self, other): ...
def __rmatmul__(self, *args, **kwargs): ...
def __ror__(self, other): ...
def __rrshift__(self, other): ...
def __rshift__(self, other): ...
def __rxor__(self, other): ...
def __xor__(self, other): ...

class fieldcatom(catom):
@classmethod
def __init__(cls, *args, **kwargs) -> None: ...
def __add__(self, other): ...
def __floordiv__(self, other): ...
def __getitem__(self, index): ...
def __matmul__(self, *args, **kwargs): ...
def __or__(self, other): ...
def __radd__(self, other): ...
def __rfloordiv__(self, other): ...
def __rmatmul__(self, *args, **kwargs): ...
def __ror__(self, other): ...
def __rrshift__(self, other): ...
def __rshift__(self, other): ...
def __rxor__(self, other): ...
def __xor__(self, other): ...

class fieldinfo:
excluded: Incomplete
field: Incomplete
def __init__(self, *args, **kwargs) -> None: ...

class layer:
field: Incomplete
greedy: Incomplete
index: Incomplete
length: Incomplete
obj: Incomplete
parent: Incomplete
path: Incomplete
sequence: Incomplete
sequential: Incomplete
state: Incomplete
value: Incomplete
def __init__(self, *args, **kwargs) -> None: ...
def __context_getattr__(self, *args, **kwargs): ...

def pack(*args, **kwargs): ...
def pack_into(*args, **kwargs): ...
def sizeof(*args, **kwargs): ...
def typeof(*args, **kwargs): ...
def unpack(*args, **kwargs): ...
1 change: 1 addition & 0 deletions src/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ CpContext_GetAttr(PyObject* ctx, PyObject* key, _modulestate* m)
{
// TODO
// return PyObject_CallMethodOneArg(ctx, m->str, PyObject *arg)
PyErr_SetString(PyExc_NotImplementedError, "GetAttr not implemented yet");
return NULL;
}

Expand Down
Loading

0 comments on commit f4a01cb

Please sign in to comment.