Skip to content

Commit 2654ccc

Browse files
authored
Merge pull request #34 from PyNumLab/c_semantics
add semantics for c
2 parents c6c0633 + 64eccd6 commit 2654ccc

41 files changed

Lines changed: 3474 additions & 274 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎docs/README.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ examples. Contribution and pull-request requirements remain in
1010
long-term architecture and runtime model.
1111
- [Wrapper `.pyi` format](semantics/pyi_format.md): editable semantic
1212
interface syntax and conversion behavior.
13+
- [C to semantic IR mapping](semantics/c2ir_mapping.md): implemented C
14+
semantic conversion subset and blocker policy.
1315
- [Self-contained C semantic `.pyi` specification](semantics/c_pyi_self_contained_specification.md):
1416
staged C wrapper interface design.
1517

@@ -29,8 +31,8 @@ examples. Contribution and pull-request requirements remain in
2931

3032
### C
3133

32-
- [C parser reference](c_parser/c_parser_reference.md): implemented parse-only
33-
frontend behavior and testing workflow.
34+
- [C parser reference](c_parser/c_parser_reference.md): implemented parser
35+
behavior, semantic handoff, and testing workflow.
3436
- [C parser architecture plan](c_parser/c_parser_architecture.md): design and
3537
integration decisions.
3638
- [C parser CLI workflow plan](c_parser/c_parser_cli_workflow.md): command

‎docs/c_parser/c_parser_architecture.md‎

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The x2py CLI also has a shared C/Fortran preprocessing option surface and can
1212
run an exact compiler/preprocessor executable for C compiler mode. Compiler
1313
and preprocessed C inputs preserve `#line`/GCC linemarker source locations for
1414
parsed declarations and diagnostics. A separate compiler-derived standard-type
15-
probe supplies target ABI facts needed by later C semantic conversion.
15+
probe supplies target ABI facts consumed by C semantic conversion.
1616

1717
This document records the target architecture for the C parser frontend in
1818
x2py. The initial skeleton has grown into a partial parser, and the remaining
@@ -91,12 +91,18 @@ Implemented now:
9191
preserving compiler/runner/source provenance for semantic conversion. It
9292
carries target-relevant include, macro, undefine, and compiler-argument flags
9393
and records the requested project standard as provenance.
94-
- `--language c --semantics`, `--language c --pyi`, and C wrap-readiness are
95-
rejected until semantic conversion exists.
94+
- `semantics.c2ir` converts the supported C parser subset into semantic IR,
95+
including scalar functions, pointer storage contracts, declared arrays,
96+
structs/opaque structs, enum and numeric macro constants, local typedef
97+
chains, target standard-type probe facts, and C-specific readiness blockers.
98+
- `--language c --semantics`, `--language c --wrap-readiness`, and starter
99+
exact-contract `--language c --pyi` output are enabled for the supported C
100+
semantic subset.
96101
- Focused partial CLI/API, declaration/function, diagnostic color, project
97102
include/index, raw lexer/directive, project golden, error golden, preprocessed
98-
linemarker remapping, and JSON schema tests are active. Remaining
99-
parser-suite skips are limited to the pinned corpus roadmap.
103+
linemarker remapping, JSON schema, and cJSON partial-parse regression tests
104+
are active. A separately pinned/provenanced corpus remains deferred work,
105+
not a skipped test.
100106
- `tests/data/c/` contains general fixtures modeled after the Fortran general
101107
fixture themes, additional C-specific API shapes, fatal diagnostic inputs,
102108
and real-world cJSON/jsmn/tinyexpr/linmath/NanoSVG/stb inputs whose partial
@@ -110,7 +116,7 @@ Deferred:
110116
- compiler attributes and alignment specifiers
111117
- broader compiler-family validation for preprocessing; parsed declarations
112118
already retain preprocessed origin and mapped source identity
113-
- C semantic readiness, semantic IR conversion, and `.pyi` output
119+
- broader C callback/ownership policy beyond exact starter `.pyi` stubs
114120

115121
Documentation rule: any future C parser implementation change must update all
116122
affected docs under `docs/c_parser/` in the same change. This applies to model,
@@ -328,8 +334,8 @@ class CParser:
328334

329335
These entrypoints are exposed from both `c_parser` and `x2py.__init__`, using
330336
the same top-level file/project invocation pattern already provided for
331-
Fortran. C semantic conversion remains unavailable despite the parse API
332-
export.
337+
Fortran. C semantic conversion is exposed separately through
338+
`semantics.c2ir` and top-level `x2py` compatibility helpers.
333339

334340
## Core Model Families
335341

@@ -723,9 +729,9 @@ Python APIs.
723729

724730
## `.pyi` Integration
725731

726-
Generated `.pyi` stubs for C should come after parser models and semantic IR
727-
conversion are stable. Readiness, if added for C, should follow the semantic
728-
layer pattern already used by the project.
732+
Generated `.pyi` stubs for C are emitted from semantic IR for the supported
733+
exact-contract subset. Readiness follows the semantic-layer pattern already
734+
used by the project.
729735

730736
Likely stub patterns:
731737

‎docs/c_parser/c_parser_cli_workflow.md‎

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ represent parenthesized pointer/array precedence through concrete
1313
parameters expose both declared and C-adjusted effective type facts. The CLI
1414
also exposes shared C/Fortran preprocessing flags and can run exact
1515
compiler/preprocessor executables for compiler mode. Target-specific standard
16-
header type facts for later C semantics are available through the separate
17-
`python -m x2py.c_type_probe` command.
16+
header type facts for C semantics are available through the separate
17+
`python -m x2py.c_type_probe` command. C semantic IR, readiness, and starter
18+
exact-contract `.pyi` output are available through the shared `x2py` CLI.
1819

1920
This document records the implemented C parse command shape, output schema,
2021
and diagnostic contract, plus deferred CLI behavior.
@@ -28,6 +29,9 @@ python -m x2py path/to/api.h --language c --parse
2829
python -m x2py path/to/api.h --language c --parse --json
2930
python -m x2py path/to/api.h --language c --parse --out report.json
3031
python -m x2py path/to/api.h --language c --parse --preprocess compiler --compiler clang-18 -I include -D API_EXPORT= --std c11
32+
python -m x2py path/to/api.h --language c --semantics
33+
python -m x2py path/to/api.h --language c --wrap-readiness
34+
python -m x2py path/to/api.h --language c --pyi
3135
```
3236

3337
The C parser accepts explicit `.c`, `.h`, and direct `.i` files, plus
@@ -86,17 +90,15 @@ as `int i; int i;` are also merged. Duplicate definitions and incompatible
8690
top-level redeclarations are reported as diagnostics. Local declarations inside
8791
function bodies are not parsed.
8892

89-
Unsupported C stages:
93+
Unsupported C display controls:
9094

9195
```bash
92-
python -m x2py path/to/api.h --language c --semantics
93-
python -m x2py path/to/api.h --language c --pyi
94-
python -m x2py path/to/api.h --language c --wrap-readiness
96+
python -m x2py path/to/api.h --language c --parse --show-vars
97+
python -m x2py path/to/api.h --language c --parse --print-limit 20
9598
```
9699

97-
These commands return clear argparse errors until C semantic IR conversion and
98-
`.pyi` generation are implemented. Fortran-only parse display flags such as
99-
`--show-vars` and `--print-limit` are rejected in C mode.
100+
Fortran-only parse display flags such as `--show-vars` and `--print-limit`
101+
return clear argparse errors in C mode until C-specific display controls exist.
100102

101103
## Current CLI Baseline
102104

@@ -402,9 +404,9 @@ JSON output for a file without raw directives:
402404
}
403405
```
404406

405-
The parser should not claim C files are wrappable. If C readiness is added
406-
later, it should follow the semantics-owned readiness boundary used elsewhere
407-
in x2py, not become parser JSON.
407+
The parser should not claim C files are wrappable. C readiness follows the
408+
semantics-owned readiness boundary used elsewhere in x2py and does not become
409+
parser JSON.
408410

409411
For raw directives, the same JSON shape is used, but `includes`, `macros`,
410412
`raw_directives`, `macro_dependencies`, and `diagnostics` may contain populated
@@ -597,10 +599,9 @@ The active CLI/parser tests cover the current partial subset:
597599
by focused C tests.
598600
- `--show-vars` and `--print-limit` are rejected in C mode until C-specific
599601
display controls exist.
600-
- `--semantics` with `--language c` is rejected until C semantic conversion is
601-
implemented.
602-
- `--pyi` with `--language c` is rejected until C `.pyi` emission is
603-
implemented.
602+
- `--semantics`, `--wrap-readiness`, and `--pyi` with `--language c` use
603+
`semantics.c2ir`, the semantic readiness checker, and the shared `.pyi`
604+
emitter for the supported exact-contract subset.
604605

605606
## Integration Order
606607

@@ -648,8 +649,10 @@ Completed order:
648649
including recursively mapped preprocessed provenance.
649650
21. Added `_Atomic(type)` type-specifier parsing on the shared declarator path
650651
and executable parser-developer walkthrough tests.
651-
22. Added compiler-derived standard-header ABI probing for future C semantic
652-
mapping without hard-coded host type aliases.
652+
22. Added compiler-derived standard-header ABI probing for C semantic mapping
653+
without hard-coded host type aliases.
654+
23. Added C semantic IR, readiness, and starter exact-contract `.pyi` output
655+
through `x2py --language c`.
653656

654657
Next implementation work should continue with fixture-driven compiler
655658
extension policy and broader project conflict policy

‎docs/c_parser/c_parser_reference.md‎

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# C Parser Reference
22

3-
Status: current reference for the parse-only C frontend. The `c_parser`
3+
Status: current reference for the partial C frontend. The `c_parser`
44
package, typed parser models, explicit C CLI parse path, raw directive
55
metadata, compiler-assisted preprocessing, source-location remapping, project
6-
indexes, parser goldens, and C standard-type probe are implemented. C semantic
7-
readiness, semantic IR conversion, and `.pyi` generation remain future work and
8-
are intentionally rejected by the CLI.
6+
indexes, parser goldens, C standard-type probe, first semantic IR conversion
7+
subset, semantic readiness path, and starter exact-contract C `.pyi`
8+
generation are implemented.
99

1010
## Purpose
1111

@@ -52,8 +52,11 @@ Implemented:
5252
the `c_parser` package entrypoints
5353
- `CParseError` with compiler-style diagnostic formatting
5454
- explicit `x2py --language c --parse` output
55+
- explicit `x2py --language c --semantics` and
56+
`x2py --language c --wrap-readiness` output
57+
- starter exact-contract `x2py --language c --pyi` output for the supported C
58+
semantic subset
5559
- C JSON partial output and `--out` behavior
56-
- rejection of C `--semantics`, `--pyi`, and `--wrap-readiness`
5760
- raw lexer records with comment stripping, line-continuation folding, and
5861
lightweight token source locations
5962
- top-level source splitting that tracks braces, parentheses, brackets, and
@@ -123,14 +126,19 @@ Implemented:
123126
`tests/data/c/errors/parser/`, and partial-parser regression inputs under
124127
`tests/data/c/json/`, `tests/data/c/tinyexpr/`, `tests/data/c/linmath/`,
125128
`tests/data/c/nanosvg/`, and top-level C inputs from `tests/data/c/stb/`
129+
- `semantics.c2ir` conversion for the first identity subset: scalar
130+
functions, const/mutable pointer storage contracts, declared arrays,
131+
structs/opaque structs, enums, numeric macro constants, local typedef
132+
chains, standard-type probe facts, and explicit semantic readiness blockers
126133

127134
Still deferred:
128135

129136
- callback policy metadata beyond parser-side callback candidates
130137
- broad compiler-extension declarators
131138
- broader typedef/tag conflict policy beyond the implemented basic project
132139
resolution
133-
- semantic readiness, semantic IR conversion, and `.pyi` generation
140+
- richer C ownership/callback projection policy beyond exact starter `.pyi`
141+
stubs
134142

135143
## Supported C Subset
136144

@@ -292,9 +300,8 @@ target-relevant flags from the matching entry to the probe explicitly.
292300
For cross targets, provide a runner, for example `--runner=qemu-aarch64
293301
--runner=-L --runner=/opt/aarch64-sysroot`.
294302

295-
The eventual C semantic converter should accept this report as target context.
296-
The parser model remains source-faithful and does not embed host ABI
297-
assumptions.
303+
The C semantic converter accepts this report as target context. The parser
304+
model remains source-faithful and does not embed host ABI assumptions.
298305

299306
## Public API
300307

@@ -603,16 +610,16 @@ Test families should mirror the Fortran parser:
603610
- typedef tests
604611
- macro/constant tests
605612
- include/project tests
606-
- semantic readiness tests once C semantic conversion exists
613+
- C semantic readiness tests
607614
- CLI tests
608615
- semantic conversion tests
609616
- `.pyi` generation/parser tests
610617
- fixture/golden parser tests
611618
- error fixture/golden tests
612619
- corpus parse-only tests
613620

614-
The C test area contains active partial-parser/raw-metadata tests plus narrowly
615-
scoped roadmap skips under `tests/parser/c/`. The active tests cover
621+
The C test area contains active partial-parser/raw-metadata tests, including
622+
parse-only cJSON regression coverage under `tests/parser/c/`. The active tests cover
616623
public entrypoints, empty model serialization, CLI discovery, JSON/output-file
617624
behavior, unsupported C stages, comment stripping, line-continuation folding,
618625
top-level splitting, include collection, simple macro collection, macro-shaped
@@ -625,8 +632,8 @@ prototypes/definitions, function-definition start/end locations, JSON golden
625632
serialization, fatal diagnostic goldens, and project-level callback typedef
626633
resolution. The `json` regression inputs
627634
intentionally retain recoverable diagnostics from unsupported constructs; they
628-
do not claim complete library parsing. Remaining parser-suite skips cover the
629-
pinned/provenanced corpus target. Golden comparison tests rewrite their baselines when
635+
do not claim complete library parsing. A separately pinned/provenanced corpus
636+
target remains deferred without disabling parser tests. Golden comparison tests rewrite their baselines when
630637
`C_PARSER_UPDATE_GOLDENS=1` is set. Future implementation branches should
631638
activate only the tests for the capability they implement.
632639

‎docs/semantics/c2ir_mapping.md‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# C To Semantic IR Mapping
2+
3+
Status: first C semantic conversion subset implemented in `semantics/c2ir.py`.
4+
The converter consumes `c_parser` models and emits the same language-neutral
5+
semantic IR used by Fortran and edited `.pyi` files.
6+
7+
## Supported Identity Subset
8+
9+
- C translation unit -> one `SemanticModule` named from the source file stem.
10+
- C function -> `SemanticFunction`, preserving native name and parameter order.
11+
- C parameter -> `SemanticArgument`.
12+
- `void` return -> `None`.
13+
- `_Bool` -> `Bool`.
14+
- `char` -> `Int8` with `c_char_policy` metadata; `signed char` -> `Int8`;
15+
`unsigned char` -> `UInt8`.
16+
- `short`, `int`, `long`, and `long long` map to fixed signed integer names
17+
using the current Linux-oriented defaults: `Int16`, `Int32`, `Int64`,
18+
`Int64`.
19+
- Unsigned integer spellings map to `UInt16`, `UInt32`, `UInt64`, and
20+
`UInt64`; fixed-width typedef spellings such as `uint32_t` map to the
21+
matching `UInt*` fallback.
22+
- `float` -> `Float32`; `double` -> `Float64`.
23+
- `float _Complex` -> `Complex64`; `double _Complex` -> `Complex128`.
24+
- Local typedef chains are resolved when their parser model definitions are
25+
available.
26+
- `size_t` maps to `SizeT` without a target probe; supplied
27+
`x2py.c_type_probe` facts override standard typedefs with width-specific
28+
`Int*`, `UInt*`, or `Float*` semantic names.
29+
- Opaque standard-type probe facts such as `FILE` create named opaque semantic
30+
classes when referenced by converted declarations.
31+
- Object-like numeric macros and enum constants become `Final`-style semantic
32+
variables through the `Constant` constraint.
33+
- Struct definitions become `SemanticClass` entries. Incomplete structs become
34+
opaque classes and may be used through direct `Ptr(...)` identity contracts.
35+
- Declared C arrays, including adjusted array parameters, become semantic array
36+
storage contracts with C order for rank greater than one.
37+
- Pointers become explicit `SemanticStorageContract` pointer/reference
38+
metadata. `const` on the pointee makes the storage read-only, and `restrict`
39+
is preserved as aliasing metadata.
40+
41+
## Conservative Blockers
42+
43+
The converter does not silently invent wrapper policy. It attaches
44+
`readiness_blockers` metadata that the semantic readiness checker reports:
45+
46+
- unresolved typedef or unknown type references;
47+
- macro-dependent declarations in raw C input;
48+
- variadic functions;
49+
- function pointer/callback signatures without edited `.pyi` `Callable`
50+
policy;
51+
- mutable numeric or `void *` pointer parameters without ownership,
52+
scalar-reference, or array policy;
53+
- arrays with unknown extents;
54+
- incomplete structs used by value;
55+
- unions used in semantic signatures;
56+
- `long double`, `volatile`, `_Atomic`, bitfields, and unsupported declarator
57+
compositions.
58+
59+
The current C semantic path supports `--language c --semantics`,
60+
`--language c --wrap-readiness`, and starter exact-contract
61+
`--language c --pyi` output for this supported subset. Generated stubs remain
62+
conservative: ambiguous ownership, callback, ABI-extension, and Pythonic
63+
projection policy stays out of the generated `.pyi` until supplied by the
64+
semantic model or an edited interface.

‎docs/semantics/c_pyi_self_contained_specification.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ constraint is written.
196196
not part of the canonical public array annotation unless they produce an
197197
actual storage constraint. In particular, Fortran dummy bounds are
198198
established by native association rather than supplied as Python array
199-
metadata. This does not add C semantic conversion support; C conversion
200-
remains deferred.
199+
metadata. The implemented C conversion subset is described in
200+
[C to semantic IR mapping](c2ir_mapping.md).
201201

202202
Stride-aware dimensions use a slice step marker:
203203

‎docs/semantics/pyi_format.md‎

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ language-neutral: Fortran and future C inputs use the same type, storage,
55
pointer, array, layout and metadata notation. Source language differences are
66
represented by contracts and metadata, not by separate syntax families.
77

8-
This document describes the behavior implemented for the current Fortran path
9-
and the shared notation it establishes for later C semantic conversion. C
10-
semantic conversion and C `.pyi` generation remain deferred.
8+
This document describes the behavior implemented for the current Fortran and C
9+
semantic conversion paths.
1110

1211
## Canonical Type And Storage Contract
1312

@@ -39,6 +38,10 @@ entries express range or stride contracts (`Float64[1:n]`,
3938
`Float64[::Strided]`, `Float64[:, 0:n:m]`). `Strided` means the runtime stride
4039
is part of the accepted storage contract.
4140

41+
Generic semantic constraints are not represented as type subscriptions.
42+
Constants use `Final[T]`; other constraints and non-dimensional array metadata
43+
use `Annotated[T[...], Constraint, ...]`.
44+
4245
`Annotated[...]` carries non-dimensional metadata:
4346

4447
- `ORDER_F` for a Fortran-oriented multidimensional contract.
@@ -411,20 +414,21 @@ visible Python values
411414
The projection mechanism is language-neutral. It can later adapt exact
412415
Fortran or C contracts through the same notation and runtime concepts, but
413416
this milestone does not implement automatic Pythonic generation, current
414-
exact-reference adaptation, coercion/contract execution or C semantic
415-
conversion/output.
417+
exact-reference adaptation, coercion/contract execution or C wrapper lowering.
418+
The C frontend can generate starter exact-contract `.pyi` output for the
419+
implemented semantic subset.
416420

417421
## Deferred C Work
418422

419-
The shared model is capable of representing future C functions, variables,
423+
The shared model represents the current C semantic conversion subset for
424+
functions, variables,
420425
fields, constants, scalar references, pointers, arrays with known contracts,
421-
origin metadata, mutability and ownership facts. This task does not implement:
426+
origin metadata, mutability and ownership facts. The C frontend can generate
427+
starter exact-contract stubs from that model. Remaining C work includes:
422428

423-
- `semantics/c2ir.py`;
424-
- C semantic conversion;
425-
- C `.pyi` generation;
426429
- C wrapper lowering;
427-
- C ownership, callback or pointer policy inference.
430+
- C ownership, callback or pointer policy inference beyond facts already
431+
present in exact contracts.
428432

429433
Future C conversion should use the same notation: by-value scalars as bare
430434
types, unrefined pointers as `Ptr(T)` or `Ptr(Const(T))`, and array notation

0 commit comments

Comments
 (0)