HALGEN is a macOS Swift code generator for AVR microcontrollers. It reads ATDF XML plus supplemental JSON docs and emits Swift HAL source files. Targets:
SwiftAVRGenerator- SwiftUI macOS appSwiftAVRGeneratorCLI- command-line generator Dependencies:swift-syntax,XMLCoderKey paths:atdf/- source ATDF device descriptionsdocs/- supplemental JSON docs (general.jsonplus per-chip files)Output/- generated Swift outputScripts/generate_avr_tools_device_file.swift- ATDF model regeneration helper Data flow:atdf/*.atdf->XMLDecoder->AVRToolsDeviceFile->GenerationPipeline-> peripheral generators -> formatted Swift output inOutput/<ChipName>/...
Checked:
.cursorrules.cursor/rules/.github/copilot-instructions.mdNo Cursor or Copilot rule files were found.
SwiftAVRGenerator/CLI/main.swift- CLI entry pointSwiftAVRGenerator/App/- SwiftUI app targetSwiftAVRGenerator/Generators/- pipeline, registry, peripheral generatorsSwiftAVRGenerator/CodeGeneration/- register/bitfield generation and formatterSwiftAVRGenerator/Documentation/- supplemental doc models and loaderSwiftAVRGenerator/AVRToolsDeviceFile/- ATDF decoding modelsSwiftAVRGeneratorTests/- XCTest coverageSwiftAVRGeneratorUITests/- UI test stubs Schemes:SwiftAVRGenerator,SwiftAVRGeneratorCLI
./generate.sh
./generate.sh --all
./generate.sh --output /tmp/halgen-test
./generate.sh --all --output /tmp/halgen-test
xcodebuild \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGeneratorCLI \
-configuration Release \
-destination "platform=macOS,arch=arm64" \
-derivedDataPath .build
.build/Build/Products/Release/SwiftAVRGeneratorCLI [--all] [--output <path>]
xcodebuild \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGenerator \
-configuration Debug \
-destination "platform=macOS,arch=arm64" \
-derivedDataPath .build./generate.sh --help was verified locally and successfully built the CLI.
xcodebuild test \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGenerator \
-destination "platform=macOS,arch=arm64"
xcodebuild test \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGenerator \
-destination "platform=macOS,arch=arm64" \
-only-testing:SwiftAVRGeneratorTests/SwiftAVRGeneratorTests
xcodebuild test \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGenerator \
-destination "platform=macOS,arch=arm64" \
-only-testing:SwiftAVRGeneratorTests/SwiftAVRGeneratorTests/testExample
xcodebuild test \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGenerator \
-destination "platform=macOS,arch=arm64" \
-only-testing:SwiftAVRGeneratorUITests/SwiftAVRGeneratorUITests/testLaunchPerformanceIf xcodebuild test fails with No signing certificate "Mac Development" found, append CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY="" DEVELOPMENT_TEAM="".
A single unit test succeeded locally with that signing-disabled suffix.
Add new tests under SwiftAVRGeneratorTests/ unless the work is specifically UI behavior.
- No
SwiftLint,SwiftFormat, or other standalone repo-wide lint config is present. - There is no separate lint command to run.
- Generated code is normalized by
CodeFormatterandHALGENCodeFormatinSwiftAVRGenerator/CodeGeneration/Linter/. - Export runs also write
formatting-report.txtandlogs.json.
- Prefer changing generator code or documentation inputs over hand-editing generated files.
- Do not edit
Output/unless the task is specifically about generated output inspection. - When changing docs behavior, check both
docs/general.jsonanddocs/<Chip>.json. - If you need to update the ATDF decode layer, inspect
Scripts/generate_avr_tools_device_file.swiftfirst. - Keep changes scoped; generator logic is shared across many chips.
- Match local style in the file you touch; newer code uses
SwiftSyntaxBuilder, older files sometimes build strings directly.
File header:
//
// FileName.swift
// SwiftAVRGenerator
//
// Created by <Author> on <date>.
//Imports:
- Import only what the file uses.
- Put
Foundationfirst when needed, Apple modules likeDispatchnext, package imports after that, andSwiftUIlast. - In tests, keep
@testable import SwiftAVRGeneratorafter normal imports. - Remove unused imports. Formatting:
- Match surrounding indentation and brace style; 4 spaces are standard.
- Prefer readable multiline code over dense one-liners, and keep blank lines/doc comments intentional.
- Prefer ASCII unless the file already uses something else.
- When building
SwiftSyntaxBuilderoutput, call.formatted().descriptionbefore emitting text. exportAllalso runs generated content throughCodeFormatter; do not assume a separate formatter step exists. Types and modeling:- Prefer
structfor generators, value types, report types, and decode models. - Use
classonly when shared mutable state or caching is needed, such asChipDocumentationLoader. - Keep ATDF/XML models as nested
Codablestructs and use XMLCoder's@Attributewrapper for XML attributes. - Prefer
letovervar; mutate only when decoding or generation logic requires it. - Use
String-backed enums when exact source tokens matter. - Avoid new module-level mutable globals;
listOfValuesis the main legacy exception. Naming: - Types and protocols use
UpperCamelCase. - Functions, methods, properties, and locals use
lowerCamelCase. - Boolean names should read as predicates, such as
hasMissingSupplementalData,shouldExport, orsupports(device:). - Static constants usually use
lowerCamelCase, for exampleallGenerators. - Preserve meaningful XML terms where they matter, such as
nameInModule,bitAddressable, orocdRw. Documentation: - Use
///for public APIs and generated register/bitfield docs. - Include datasheet section references when known.
- Keep supplemental docs additive; avoid duplicating the same prose in both generator code and JSON docs.
- Use
// TODO:for genuine follow-up work only. Error handling: - In CLI code and helper scripts, validate arguments explicitly, print fatal errors to
stderrwithfputs, and exit nonzero. - In library and generator code, prefer
do/catchand useful diagnostics overexit. - Avoid
try!; usetry?only when failure is genuinely optional. preconditionFailureis acceptable for impossible internal states, but prefer validating external input first.- Never swallow errors silently when a user or agent needs to know what failed.
- New peripherals belong in
SwiftAVRGenerator/Generators/Peripherals/. - Conform new peripherals to
PeripheralGeneratorwithname,subdirectory,supports(device:), andgenerate(device:documentation:). - Register new generators in
GeneratorRegistry.allGenerators. - Generated files export under
Output/<ChipName>/<subdirectory>/. - Keep generated register accessors consistent with the current style:
@inlinable,@inline(__always),public static var, and_volatileRegisterReadUInt8or_volatileRegisterWriteUInt8. - Prefer
SwiftSyntaxBuilderfor structured multi-declaration output; small string fragments are acceptable in older files when that matches local style.
- Run focused tests for the area you changed when practical.
- For generator changes,
./generate.shis usually the most valuable verification step. - Inspect both
logs.jsonandformatting-report.txtafter generation. - Check at least one representative chip, usually
ATmega328P, unless the task targets another device. - If you touch CLI path handling or documentation loading, verify with
./generate.sh --output /tmp/halgen-test. - If full tests are not practical, say exactly what you ran and what you could not verify.