Ports the point/vector foundation of geometry/planar: Side and Signum
(three-valued signs), Limits, FloatPoint (approximate), and the exact
IntPoint/IntVector plus projective RationalPoint/RationalVector.
Arithmetic model per type is documented in each module. The key
simplification over the Java source: Python's unbounded int makes the
exact orientation determinants and rational (x,y,z) coordinates trivial,
so side_of is kept exact (upstream uses a double for speed) and no
BigInteger or CRIT_INT overflow promotion is needed. Rational points use
the projective triple with z=0 denoting the point at infinity.
Tests cover collinearity, determinants beyond Java long range, rational
equality/reduction, and integer/rational promotion.
Ports the write path of io/specctra/SesWriter.java to emit a valid
session from a parsed DsnBoard plus a RoutingResult. Each _write_*
function mirrors a write* method upstream:
- session scope with base_design, placement (resolution + components
echoed from the DSN), an empty was_is, and routes
- routes carries resolution, a reduced parser scope, library_out with
the via padstacks, and network_out
- network_out emits (net (wire (path layer width x1 y1 ...)) (via
padstack x y)) for each routed net; integer coordinates via round-
half-up to match Java Math.round
write_ses(board) with no result produces a valid no-op session,
proving the DSN-in / SES-out round trip. Only routes > network_out is
required by SesReader and kicad-cli; the rest is echoed for a
well-formed file.
18 tests: indent/quoting rules, no-op session structure, placement and
library_out echo, routed wire/via serialization, integer rounding, and
round-trips re-parsed through the project's own DSN tokenizer/sexp
(64 tests total across the suite, all green; ruff clean).
Ports the read path of FreeRouting's io/specctra/parser package to a
Java-free Python implementation:
- tokenizer: S-expression lexer mirroring SpecctraFileDescription.flex
(comments, quoted strings, the string_quote IGNORE_QUOTE directive,
case-insensitive keywords, and hash-prefixed names)
- sexp: nested S-expression tree builder
- shapes: rect/circle/polygon/path plus area-with-holes scopes
- model: typed dataclasses for layers, padstacks, images, placements,
nets, net classes, rules, keepouts
- reader: recursive-descent scope readers producing a DsnBoard, one
_read_* function per FreeRouting read_scope method
46 pytest cases cover the tokenizer, tree, shapes, and end-to-end
parsing against hand-crafted fixtures modeled on FreeRouting's own
test DSN files. Parses 90 of 91 upstream fixtures (the one failure is
a binary OLE file, not text DSN).