Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
20 changes: 20 additions & 0 deletions docs/pyi_format.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,26 @@ Common constraints include:
- `Allocatable` for allocatable values.
- `Pointer` for pointer values.

## Constants

Fortran `parameter` declarations are constants. The printer emits them with
`Final[...]` instead of a generic type constraint:

```python
answer: Final[Int32]
scale: Final[Float64]
```

When a constant is private, `private[...]` remains the outer visibility marker:

```python
hidden_answer: private[Final[Int32]]
```

The `.pyi` parser accepts `Final[...]` and restores it to the semantic IR as a
`Constant` constraint, so edited stubs still round-trip through the existing IR
model.

## Visibility

Private procedures and classes use decorators:
Expand Down
16 changes: 12 additions & 4 deletions fortran_parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,24 @@ and practical usage from terminal and Python.

- Module discovery
- Module variable extraction
- Shared specification-part parsing for module-like scopes (modules,
submodules, programs, and block-data units), preserving original line
numbers while skipping contained procedure bodies where they are not
wrap-relevant
- `use` extraction at module and procedure scope
- Explicit `use` symbol mappings preserve imported `source` names and local
`target` names for renamed imports
- Propagation of module-level `use` imports into contained procedures
- Folder/project parsing with dependency-aware ordering
- Cross-file kind constant resolution (e.g., kinds modules)
- Cached compile-time expression resolution for local/module parameters,
module/program variable shapes, and character lengths

### 1.5 Derived type parsing

- `type :: ... end type` and legacy `type name ... end type` discovery
- Parameterized derived-type headers such as `type :: buffer_type(k, n)`
and declarations such as `type(buffer_type(real64, 4))`
- Type attributes (e.g., `abstract`)
- Inheritance (`extends(parent)`)
- Field extraction including shape/pointer/allocatable
Expand Down Expand Up @@ -78,15 +86,15 @@ sections so maintainers can navigate the file by concern instead of by history:
diagnostics, shape evaluation, compile-time expression resolution,
dependency ordering)
- `FortranParser` internals grouped by domain:
- visitor-style API entrypoints (`visit_file`, `visit_project`,
`visit_wrap_readiness`)
- signature/declaration parsing
- module-variable parsing
- file/project orchestration
- program-unit parsers (types, modules, interfaces, submodules, programs,
block-data)
- visitor-style API wrappers (`visit_file`, `visit_project`,
`visit_wrap_readiness`)
- compatibility aliases (`parse_file`, `parse_project`,
`assess_wrap_readiness`)
- `_helper_*` methods for scoped parsing, expression resolution, and shared
specification-part collection
- Thin module-level convenience wrappers that delegate to a shared parser
instance

Expand Down
6 changes: 3 additions & 3 deletions fortran_parser/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ def _parse_paths(paths: list[str]) -> dict[str, dict]:

for p in sorted(set(expanded)):
code = p.read_text(encoding="utf-8")
parsed = parser.parse_file(code, filename=str(p))
parsed = parser.visit_file(code, filename=str(p))
out[str(p)] = {
"signatures": [_to_dict_no_parent(s) for s in parsed.procedures],
"types": [_to_dict_no_parent(t) for t in parsed.derived_types],
"modules": [_to_dict_no_parent(m) for m in parsed.modules],
"submodules": [_to_dict_no_parent(m) for m in parsed.submodules],
"programs": [_to_dict_no_parent(m) for m in parsed.programs],
"block_data": [_to_dict_no_parent(m) for m in parsed.block_data_units],
"wrap_readiness": parser.assess_wrap_readiness(code, filename=str(p)),
"wrap_readiness": parser.visit_wrap_readiness(code, filename=str(p)),
}
return out

Expand All @@ -92,7 +92,7 @@ def _semantic_report(paths: list[str]) -> dict[str, dict]:

for fname in parsed:
code = Path(fname).read_text(encoding="utf-8")
fobj = parser.parse_file(code, filename=fname)
fobj = parser.visit_file(code, filename=fname)
modules = [fortran_module_to_semantic_module(m) for m in fobj.modules]
semantic_out[fname] = {
"semantic_modules": [asdict(m) for m in modules],
Expand Down
6 changes: 5 additions & 1 deletion fortran_parser/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def format_diagnostic(self, *, color: bool = False, debug: bool | None = None) -
class FortranVariable:
name: str
base_type: str = "unknown"
kind: Optional[str] = None
kind: str = ""
rank: int = 0
shape: list[str] = field(default_factory=list)
lbound: list[str | None] = field(default_factory=list)
Expand All @@ -213,6 +213,10 @@ class FortranVariable:
dimensions: list[int] = field(default_factory=list)
visibility: str = "public"

def __post_init__(self) -> None:
if self.kind is None:
self.kind = ""

@property
def shape_info(self) -> list[dict[str, str | None]]:
"""Structured per-dimension shape metadata derived from `shape` tokens."""
Expand Down
Loading
Loading