Skip to content
Merged

enum #42

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,18 +199,18 @@ python -m x2py tests/data/c/general/math_api.h --language c --pyi
```python
File: tests/data/c/general/math_api.h
def norm2(
n: Int32,
n: Int,
x: Const(Float64[1])
) -> Float64: ...

def scale(
n: Int32,
n: Int,
alpha: Float64,
x: Float64[1]
) -> None: ...

def dot(
n: Int32,
n: Int,
x: Ptr(Const(Float64)),
y: Ptr(Const(Float64))
) -> Float64: ...
Expand Down
8 changes: 5 additions & 3 deletions docs/c_parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,11 @@ python -m x2py.c_type_probe --compiler /usr/bin/gcc-13 --std c11
```

The report records arithmetic category, underlying C spelling, bit width, and
alignment for `size_t`, available `uint32_t`, and `time_t`; it records opaque
handle and pointer ABI facts for `FILE`. It also retains the generated C source
and exact compile/run commands.
alignment for builtin C `int`, `size_t`, available `uint32_t`, and `time_t`; it
records opaque handle and pointer ABI facts for `FILE`. It also retains the
generated C source and exact compile/run commands. Semantic conversion keeps
the name `Int` for builtin C `int` and stores the measured concrete dtype and
probe fact separately.

The probe must be run with the same target profile as the source being parsed.
It carries `-I`, `-D`, `-U`, and `--compiler-arg` options into the compile
Expand Down
3 changes: 3 additions & 0 deletions docs/developper_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@ from `semantics/models.py`.
- `semantics/c2ir.py` maps C functions, variables, structs/opaque structs,
enums, typedef chains, standard-type probe facts, macros, pointer/array
storage, and C-specific readiness blockers.
- C `int` keeps the semantic name `Int` while its compiler-probed concrete
precision is stored on the semantic type. C enums are open named semantic
declarations with unscoped module-level enumerator constants.
- `semantics/pyi_printer.py` emits editable user contracts.
- `semantics/pyi_parser.py` loads edited contracts back into semantic IR.
- `semantics/readiness.py` decides whether that IR is complete enough for
Expand Down
6 changes: 3 additions & 3 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,9 @@ Output:
<!-- x2py-doc-test-output -->
```text
def add(
a: Int32,
b: Int32
) -> Int32: ...
a: Int,
b: Int
) -> Int: ...
True
```

Expand Down
56 changes: 47 additions & 9 deletions docs/semantics.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ and eventual NumPy-oriented wrapper code.
| Semantic dtype | NumPy equivalent | Notes |
| --- | --- | --- |
| `Bool` | `numpy.bool_` | Boolean scalar. |
| `Int` | Target-dependent signed NumPy integer | Ordinary C `int`; the concrete `Int16`/`Int32`/`Int64` dtype and compiler fact are stored separately. |
| `Int8`, `Int16`, `Int32`, `Int64` | `numpy.int8`, `numpy.int16`, `numpy.int32`, `numpy.int64` | Signed integers. |
| `UInt8`, `UInt16`, `UInt32`, `UInt64` | `numpy.uint8`, `numpy.uint16`, `numpy.uint32`, `numpy.uint64` | Unsigned integers. |
| `Float32`, `Float64` | `numpy.float32`, `numpy.float64` | Binary floating-point scalars. |
Expand Down Expand Up @@ -57,7 +58,8 @@ and eventual NumPy-oriented wrapper code.
| `char`, `signed char` | `Int8` | `numpy.int8` |
| `unsigned char` | `UInt8` | `numpy.uint8` |
| `short`, `unsigned short` | `Int16`, `UInt16` | `numpy.int16`, `numpy.uint16` |
| `int`, `unsigned int` | `Int32`, `UInt32` | `numpy.int32`, `numpy.uint32` |
| `int` / `CInt` | `Int` with concrete probed dtype | Matching signed NumPy integer for the target |
| `unsigned int` | `UInt32` | `numpy.uint32` |
| `long`, `long long` | `Int64` | `numpy.int64` |
| `unsigned long`, `unsigned long long` | `UInt64` | `numpy.uint64` |
| `float`, `double`, `long double` | `Float32`, `Float64`, `Float128` | `numpy.float32`, `numpy.float64`, `numpy.longdouble` |
Expand All @@ -66,9 +68,12 @@ and eventual NumPy-oriented wrapper code.
| `uint8_t`, `uint16_t`, `uint32_t`, `uint64_t` | `UInt8`, `UInt16`, `UInt32`, `UInt64` | Matching unsigned NumPy integer |
| `size_t` | `SizeT` or probed unsigned width | `numpy.uintp` or matching `numpy.uint*` |

C integer spellings such as `long` are ABI-dependent in general C, but the
current semantic policy maps parsed primitive `long` and `long long` to 64-bit
semantic dtypes. Standard-library typedefs are refined through the compiler
C integer spellings are ABI-dependent. Ordinary C `int` keeps the stable
semantic identity `Int`; its concrete dtype and the compiler fact used to
derive it are stored on `SemanticType`. Without a supplied compiler report,
the concrete dtype uses a clearly marked 32-bit fallback. The current semantic
policy still maps parsed primitive `long` and `long long` to 64-bit semantic
dtypes. Standard-library typedefs are refined through the compiler
standard-type probe when facts are supplied.

## C To Semantic IR Mapping
Expand All @@ -87,9 +92,11 @@ policy is documented in the datatype mapping section above.
- `_Bool` -> `Bool`.
- `char` -> `Int8` with `c_char_policy` metadata; `signed char` -> `Int8`;
`unsigned char` -> `UInt8`.
- `short`, `int`, `long`, and `long long` map to fixed signed integer names
using the current Linux-oriented defaults: `Int16`, `Int32`, `Int64`,
`Int64`.
- `int` maps to `Int`. Its concrete dtype is derived from a supplied
`x2py.c_type_probe` report and stored with the fact source; without one it
carries a marked `Int32` fallback.
- `short`, `long`, and `long long` map to fixed signed integer names using the
current Linux-oriented defaults: `Int16`, `Int64`, `Int64`.
- Unsigned integer spellings map to `UInt16`, `UInt32`, `UInt64`, and
`UInt64`; fixed-width typedef spellings such as `uint32_t` map to the
matching `UInt*` fallback.
Expand All @@ -103,8 +110,20 @@ policy is documented in the datatype mapping section above.
`Int*`, `UInt*`, or `Float*` semantic names.
- Opaque standard-type probe facts such as `FILE` create named opaque semantic
classes when referenced by converted declarations.
- Object-like numeric macros and enum constants become `Final`-style semantic
variables through the `Constant` constraint.
- Enum definitions become open `SemanticEnum` declarations. Named enum
arguments and returns keep the enum datatype instead of flattening to an
integer.
- C enumerators remain unscoped module-level `Final[enum_name]` variables with
their known values. An open enum may still carry any value representable by
its underlying integer type; the listed enumerators are named constants, not
closed validation choices.
- Native enumerator expressions remain stored in semantic IR. The `.pyi`
initializer is emitted only when it can be represented as valid Python
expression syntax.
- Enum underlying storage currently assumes C `int` and records that
assumption unless an enum-specific compiler fact is supplied.
- Object-like numeric macros become `Final`-style semantic variables through
the `Constant` constraint.
- Struct definitions become `SemanticClass` entries. Incomplete structs become
opaque classes and may be used through direct `Ptr(...)` identity contracts.
- Explicit multi-header conversion resolves a struct to the header that defines
Expand All @@ -118,6 +137,25 @@ policy is documented in the datatype mapping section above.
metadata. `const` on the pointee makes the storage read-only, and `restrict`
is preserved as aliasing metadata.

For example:

```c
enum status { STATUS_OK = 0, STATUS_ERROR = 10 };
void set_status(enum status value);
```

becomes:

```python
class status(Enum[Int]):
pass

STATUS_OK: Final[status] = 0
STATUS_ERROR: Final[status] = 10

def set_status(value: status) -> None: ...
```

### Conservative Blockers

The converter does not silently invent wrapper policy. It attaches
Expand Down
6 changes: 3 additions & 3 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,18 @@ Expected output:
```python
File: tests/data/c/general/math_api.h
def norm2(
n: Int32,
n: Int,
x: Const(Float64[1])
) -> Float64: ...

def scale(
n: Int32,
n: Int,
alpha: Float64,
x: Float64[1]
) -> None: ...

def dot(
n: Int32,
n: Int,
x: Ptr(Const(Float64)),
y: Ptr(Const(Float64))
) -> Float64: ...
Expand Down
2 changes: 2 additions & 0 deletions semantics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
)
from .c2ir import (
CToIRConverter,
c_enum_to_semantic_enum,
c_file_to_semantic_module,
c_file_to_semantic_modules,
c_function_to_semantic_function,
Expand All @@ -24,6 +25,7 @@
"CToIRConverter",
"assess_pyi_wrap_readiness",
"assess_semantic_wrap_readiness",
"c_enum_to_semantic_enum",
"c_file_to_semantic_module",
"c_file_to_semantic_modules",
"c_function_to_semantic_function",
Expand Down
Loading
Loading