Skip to content
Open
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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,21 @@ breaking changes to the API or the command-line interface; patch releases
line 0 (issue #134).
- Deck reader: a ground-plane statement's warnings are reported in
source-clause order (issue #136).
- Deck reader: **node names are case-insensitive** (issue #156), as the
User's Guide documents (§1.1, §1.3), in every mode and every position —
node and in-plane node declarations, `E` endpoints, `.external` and
`.equiv`. This reverses the earlier case-sensitive decision: a deck that
declared both `N1` and `n1` now gets a line-numbered duplicate-definition
error naming both spellings, instead of two nodes. A port's default
`<+>/<->` label is now lowercased (an explicit label is kept as written).
`.equiv` now implements the documented **pseudonyms** (§1.3.7): a name
not yet defined becomes a pseudonym for the list's first defined node,
usable afterwards as an endpoint or in `.external`; a list with no
defined name is an error (`no defined node in .equiv`), and declaring a
node under a pseudonym's name is a duplicate error. Previously every
`.equiv` name had to be defined already. Under `--fasthenry-compat`,
`.equiv x x` (naming one node twice) is a warning and a no-op; natively
it is still an error.
- Deck reader: a corner-point `G` statement's `contact rect` or `contact
decay_rect` wholly outside the plane's footprint is no longer a plane
assembly error on line 0 ("contact region … lies outside the plane
Expand Down
8 changes: 5 additions & 3 deletions docs/fasthenry-compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Status key:
| Blank lines | Supported | Dropped like comments, anywhere in the file, including trailing lines after `.end`. |
| Whitespace around `=` (`k = v`, `k= v`, `k =v`, tabs) | Supported | Issue #141. In every mode, on `N`, `E`, `.default` and `.freq` lines — continuations included — a `key`, `=`, `value` split by spaces or tabs is rejoined into one `key=value` before the line is read, so every spacing parses exactly like `k=v`; `G` lines already allowed it in their own scanner. A dangling `x=` with no value (at the end of the statement, or followed by another assignment) is still a line-numbered error naming the field. |
| Directive keywords case-insensitive (`.UNITS` = `.units`) | Supported | Matched via `to_ascii_lowercase()`. |
| Node/element names case-sensitive | Supported | `N1` and `n1` are different nodes; every reference (`.external`, `E` endpoints, `.equiv`) is matched by exact string equality. |
| Node names case-insensitive (`N1` = `n1`) | Supported | Issue #156, which **reverses** this row's earlier "case-sensitive" decision. The User's Guide says so twice — §1.1 "Everything is case INsensitive", §1.3 "Uppercase is converted to lower case" — and its own §1.2 example declares `N3` and later writes `.equiv nin n3`, which the case-sensitive reader rejected (`unknown node 'n3'`); black-box runs on self-authored decks confirm the documented behavior. In every mode, every node name is folded to lowercase before it is matched: node declarations, in-plane node declarations (`G` statement `N<name> (x, y, z)` and the `contact equiv_rect`/`connection` nodes), `E` endpoints, `.external` and `.equiv`. Names reach output lowercased (a port's default `<+>/<->` label); an explicit `.external` label is a label rather than a node name and is kept as written. A deck that relied on `N1` ≠ `n1` now gets an explicit line-numbered duplicate-definition error naming both spellings — never a silent reinterpretation as one node, nor two nodes. Element (`E`) names are never referenced, so their case is moot; `group=` names stay case-sensitive (this reader's own extension, below). |
| `.end` required | Supported, differs | A deck without `.end` is rejected. FastHenry decks conventionally end with `.end`, but this reader treats its absence as an error rather than an implicit end-of-file — consistent with the "no default swallows a mistake" design already applied to `.units`. |
| Content after `.end` | Supported, differs | Comments and blank lines after `.end` are fine (dropped before the `.end` state is even consulted, same as elsewhere in the file); another directive/node/segment line after `.end` is an error. Multi-deck-in-one-file constructs some formats allow after a terminator are out of scope: this reader parses exactly one deck per input. |

Expand Down Expand Up @@ -71,7 +71,7 @@ Status key:
| `rho=` | Supported | Issue #70; same rules as `.default rho=`. |
| `rw=`, `rh=` | Supported, differs | Issue #71. The ratio of adjacent filament extents across the width / height, each axis independently, coarsening from both surfaces inward (`nwinc=5 rw=2` cuts the width 1:2:4:2:1). A ratio must be a number ≥ 1 (below 1 is rejected, not guessed at); an omitted ratio keeps the uniform grid, so decks without `rw`/`rh` solve exactly as before. See `inp.rs`'s `# Semantics` section. |
| `wx=`, `wy=`, `wz=` | Supported | Issue #71. A dimensionless vector along the cross-section's width (only its component perpendicular to the segment counts); a component given nowhere is 0 once any is given. A zero vector, or one parallel to the segment, is a line-numbered error. |
| `group=<name>` | Supported, extended | This reader's own addition, feeding `.couples` (below) — not a documented FastHenry field. Case-sensitive, like node names. |
| `group=<name>` | Supported, extended | This reader's own addition, feeding `.couples` (below) — not a documented FastHenry field. Case-sensitive — unlike node names (issue #156), since it is not a FastHenry name at all. |

## `.external`

Expand All @@ -93,7 +93,9 @@ Status key:
| Field | Status | Notes |
|---|---|---|
| `.equiv N<a> N<b>` | Supported | `b` becomes an alias of `a`. |
| `.equiv N<a> N<b> N<c> …` (more than two nodes) | Supported | Every later name aliases to the first (`.equiv a b c` is `.equiv a b` followed by `.equiv a c`). Landed with the ground-plane work (issue #69); this audit adds `equiv_joins_more_than_two_nodes` and `equiv_chain_rejects_a_node_repeated_with_itself` to `inp.rs`'s test module to pin the behavior. Naming a node together with itself is a line-numbered error. |
| `.equiv N<a> N<b> N<c> …` (more than two nodes) | Supported | Every later defined name aliases to the first defined one (`.equiv a b c` is `.equiv a b` followed by `.equiv a c`). Landed with the ground-plane work (issue #69); this audit adds `equiv_joins_more_than_two_nodes` and `equiv_chain_rejects_a_node_repeated_with_itself` to `inp.rs`'s test module to pin the behavior. |
| Pseudonyms: a name not yet defined | Supported | Issue #156; User's Guide §1.3.7 ("If any of the node names are not previously defined, then they become pseudonyms for those nodes in the list which are defined"). In every mode, a name in the list not yet defined becomes a pseudonym for the list's canonical node — its first *defined* name — wherever it stands in the list (first, last or in between), and from then on it may be used like any node name, as a later `E` endpoint or in `.external`. A list with no defined name is a line-numbered error (`no defined node in .equiv`), and declaring a node under a name that is already a pseudonym is the duplicate-definition error, naming the pseudonym's line. There are still no forward references: an `E` endpoint or `.external` naming a node defined on a later line is an error, and a `.equiv` name defined only later is a pseudonym whose later declaration is that duplicate error. |
| Naming one node twice (`.equiv x x`, or two names already joined) | Supported, differs (opt-in) | Issue #156. FastHenry only warns. Natively this reader keeps it a line-numbered error — a deck that joins a node to itself almost certainly meant another node — and under `--fasthenry-compat` it is a line-numbered warning and a no-op, the rest of the list still being joined. |
| Resolution order (a reference before vs. after the directive) | Supported | Every reference resolves through the alias chain regardless of where in the deck it appears; the deck is one circuit, not a timeline. |
| Joining an in-plane node (`G` statement `N<name> (x, y, z)`) | Supported, differs | If any node in the joined set is an in-plane node, the whole set lands on that plane's nearest live cell-centre node, whichever side of the directive named it — so wiring a via into a plane does not depend on argument order. Joining in-plane nodes of two *different* planes is rejected (connect planes with a segment) rather than silently attaching to one. |

Expand Down
3 changes: 2 additions & 1 deletion fasterhenry-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ pub struct RunArgs {
/// line 1 is prose. Off by default: line 1 is parsed like any other
/// and `.title <text>` sets the title. A later `.title` is still
/// honored in this mode. Also gives a segment or ground plane with no
/// conductivity FastHenry's copper default (5.8e7 S/m), with a warning.
/// conductivity FastHenry's copper default (5.8e7 S/m), with a warning,
/// and turns a `.equiv` of a node with itself into a warning.
#[arg(long)]
pub fasthenry_compat: bool,
}
Expand Down
Loading
Loading