| title | Semantic IR Reference |
|---|---|
| audience | advanced users, developers |
| prerequisites | parser references, native datatype model |
| related | index.md |
| status | maintained |
| publication | draft |
| Semantic dtype | NumPy equivalent | Notes |
|---|---|---|
Bool |
numpy.bool_ |
Boolean scalar. |
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. |
Float128 |
numpy.longdouble |
Platform precision varies; numpy.float128 is not portable. |
Complex64, Complex128 |
numpy.complex64, numpy.complex128 |
Complex scalars. |
Complex256 |
numpy.clongdouble |
Platform precision varies. |
String |
numpy.str_ or byte storage at ABI boundary |
Character policy depends on wrapper ABI. |
SizeT |
numpy.uintp |
Target width is compiler-probed when available. |
Any |
object |
Used for void pointer pointees and intentionally opaque values. |
| Fortran spelling or kind | Semantic dtype | NumPy equivalent |
|---|---|---|
Unqualified integer, real, complex |
Compiler-probed default storage | Matching NumPy numeric dtype |
Numeric kinds such as kind=4/8/16 and kind(...) expressions |
Compiler-probed kind storage | Matching NumPy numeric dtype |
integer(int8/int16/int32/int64) |
Int8 / Int16 / Int32 / Int64 |
Matching NumPy signed integer |
real(real32/real64/real128) |
Float32 / Float64 / Float128 |
Matching NumPy real dtype |
complex(real32/real64/real128) |
Complex64 / Complex128 / Complex256 |
Matching NumPy complex dtype |
double precision, double complex |
Compiler-probed double-kind storage | Matching NumPy real or complex dtype |
Legacy numeric type*N, such as integer*8, real*8, complex*16, logical*1 |
Fixed N-byte total storage |
Matching NumPy dtype |
Legacy character*N, character*(*) |
String; N/* is length, not kind |
numpy.str_ or ABI byte storage |
procedure(...) |
Procedure |
Callback/interface policy |
Compiler-backed Fortran semantic CLI stages measure the storage of every
intrinsic type used by the source after resolving kind expressions. This is
required because default and numeric kind mappings are processor-dependent and
flags such as -fdefault-real-8 can change them. Results are cached by exact
compiler identity, target flags, expressions, environment, and runner.
Legacy numeric type*N extensions carry fixed total storage and therefore do
not need a compiler probe. In particular, complex*8 is an 8-byte
Complex64, while modern complex(kind=8) is a compiler kind that is
Complex128 on the documented gfortran target. DOUBLE PRECISION and
DOUBLE COMPLEX remain compiler-dependent and use the cached probe.
Direct converter calls without compiler facts retain the current GitHub
Actions gfortran profile as a fallback. Explicit iso_fortran_env kinds are
preferred when a portable source contract needs a fixed precision.
The following mapping snapshots are generated from the same compiler-backed
code paths used by prik. They target the linux-x86_64 profile used by GitHub
Actions. The executable documentation test reruns the commands and compares
their complete output, so a compiler fact or semantic mapping change must
update these examples.
Semantic .pyi is a Python-valid serialization and editing surface for
semantic IR, not a second semantic model. The syntax, metadata names,
projection notation, diagnostics, generated coverage, and editing workflow are
owned by Semantic .pyi format.
This IR reference keeps only the relationship between that surface and the underlying semantic model:
- source frontends populate
SemanticModule,SemanticFunction,SemanticArgument,SemanticVariable,SemanticClass, and related storage contracts; .pyiprinting exposes the public wrapper contract plus the native-call metadata required to reconstruct the same semantic IR;.pyiloading converts the documented contract subset back to semantic IR without reparsing native source; and- policy completion and lowering consume semantic IR, not raw
.pyisyntax.
The shared semantic model separates value type, storage and calling contract,
public array contract, ownership and transfer policy, and source-origin
metadata. The .pyi surface exposes only the facts that are part of the public
wrapper contract or required to reconstruct native-call topology. Native
source-provenance details not emitted into the public contract are
intentionally excluded from public contract equality.
Post-IR policy completion turns those facts into two explicit barrier actions before lowering:
- the Python barrier action, which tells Python binding generation how to extract or validate the Python object; and
- the native barrier action, which tells bridge generation how to hand the extracted value to native code.
The Python barrier distinguishes Python scalar values, rank-0 NumPy scalar storage, NumPy array storage, Python strings, raw address values, and generated wrapper instances. The native barrier distinguishes direct values, call-local addresses, caller/Python-backed storage addresses, raw addresses, packed array descriptors, and wrapper-owned native addresses. These decisions are semantic policy. Wrapper planning, binding/bridge lowering, and printers may create backend-local temporaries, but they must not infer or override a barrier action from datatype, source-declaration direction, array category, aliasing, or memory-storage checks.
Parser-model conversion and semantic/wrapper-model traversal use the shared
prik.utilities.visitor.ClassVisitor dispatcher and one configured
<prefix>_<ClassName> protocol. The default prefix is _visit; specialized
visitors may choose clearer names such as _print or _parse while still using
the same MRO dispatcher. Barrier/action dispatch tables are allowed only for
completed policy actions; the primitive ABI map is the other deliberate table
because it maps datatype classes to semantic dtypes rather than traversing model
nodes. These tables are separate from model-node dispatch.
prik.parsers.pyi parses the documented semantic .pyi subset into Python AST.
convert_pyi_to_ir converts that AST into the same public storage contracts
emitted by the source semantic pipelines; pyi_file_to_semantic_module combines file parsing
and conversion. Focused round-trip tests cover:
Fortran parser model -> semantic IR -> .pyi -> semantic IR
Generated and edited stubs must not use hidden native-source parsing as a
fallback. If the .pyi contract omits native facts required for policy
completion or lowering, prik reports a contract or wrapper-planning error instead of
guessing.
External source-language types are modeled in semantic IR by owner-module type
identity. Stub printing may emit owner-module dependency stubs, and
pyi_paths_to_semantic_modules reconciles those imports back into semantic
external_type_ref metadata. The concrete file syntax for those owner stubs is
documented in
Semantic .pyi format.