@typecad/cuttlefish 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +79 -0
- package/dist/api/board-types.d.ts +1 -0
- package/dist/api/board-types.js +4 -0
- package/dist/api/capabilities.d.ts +12 -0
- package/dist/api/capabilities.js +1 -0
- package/dist/api/config.d.ts +120 -0
- package/dist/api/config.js +7 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.js +2 -0
- package/dist/api/schema/builder.d.ts +14 -0
- package/dist/api/schema/builder.js +15 -0
- package/dist/api/schema/index.d.ts +2 -0
- package/dist/api/schema/index.js +1 -0
- package/dist/api/schema/types.d.ts +257 -0
- package/dist/api/schema/types.js +4 -0
- package/dist/api/shared/async-runtime-static.d.ts +8 -0
- package/dist/api/shared/async-runtime-static.js +201 -0
- package/dist/api/shared/async-types.d.ts +42 -0
- package/dist/api/shared/async-types.js +8 -0
- package/dist/api/shared/board-resolver.d.ts +12 -0
- package/dist/api/shared/board-resolver.js +7 -0
- package/dist/api/shared/cpp-type-ir.d.ts +229 -0
- package/dist/api/shared/cpp-type-ir.js +672 -0
- package/dist/api/shared/display-adapter.d.ts +12 -0
- package/dist/api/shared/display-adapter.js +145 -0
- package/dist/api/shared/display-adapters/eink-mono.d.ts +2 -0
- package/dist/api/shared/display-adapters/eink-mono.js +53 -0
- package/dist/api/shared/display-adapters/sdl.d.ts +2 -0
- package/dist/api/shared/display-adapters/sdl.js +452 -0
- package/dist/api/shared/display-adapters/ssd1309.d.ts +2 -0
- package/dist/api/shared/display-adapters/ssd1309.js +136 -0
- package/dist/api/shared/display-adapters/st7796.d.ts +2 -0
- package/dist/api/shared/display-adapters/st7796.js +132 -0
- package/dist/api/shared/display-capabilities.d.ts +45 -0
- package/dist/api/shared/display-capabilities.js +54 -0
- package/dist/api/shared/display-op-ir.d.ts +62 -0
- package/dist/api/shared/display-op-ir.js +19 -0
- package/dist/api/shared/display-profile.d.ts +265 -0
- package/dist/api/shared/display-profile.js +338 -0
- package/dist/api/shared/graphics-strategy.d.ts +29 -0
- package/dist/api/shared/graphics-strategy.js +11 -0
- package/dist/api/shared/hal-op-ir.d.ts +393 -0
- package/dist/api/shared/hal-op-ir.js +18 -0
- package/dist/api/shared/index.d.ts +26 -0
- package/dist/api/shared/index.js +21 -0
- package/dist/api/shared/ir-core.d.ts +363 -0
- package/dist/api/shared/ir-core.js +8 -0
- package/dist/api/shared/ir-declarations.d.ts +201 -0
- package/dist/api/shared/ir-declarations.js +26 -0
- package/dist/api/shared/ir.d.ts +85 -0
- package/dist/api/shared/ir.js +13 -0
- package/dist/api/shared/platform-strategy.d.ts +402 -0
- package/dist/api/shared/platform-strategy.js +14 -0
- package/dist/api/shared/polyfill-helper-registry.d.ts +11 -0
- package/dist/api/shared/polyfill-helper-registry.js +86 -0
- package/dist/api/shared/polyfill-types.d.ts +33 -0
- package/dist/api/shared/polyfill-types.js +76 -0
- package/dist/api/shared/promise-runtime.d.ts +10 -0
- package/dist/api/shared/promise-runtime.js +244 -0
- package/dist/api/shared/snprintf-types.d.ts +29 -0
- package/dist/api/shared/snprintf-types.js +8 -0
- package/dist/api/shared/string-method-registry.d.ts +53 -0
- package/dist/api/shared/string-method-registry.js +168 -0
- package/dist/api/shared/toolchain-types.d.ts +63 -0
- package/dist/api/shared/toolchain-types.js +71 -0
- package/dist/api/shared/types.d.ts +50 -0
- package/dist/api/shared/types.js +6 -0
- package/dist/ast/parse.d.ts +2 -0
- package/dist/ast/parse.js +4 -0
- package/dist/cache.d.ts +26 -0
- package/dist/cache.js +95 -0
- package/dist/cli-utils.d.ts +37 -0
- package/dist/cli-utils.js +250 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +635 -0
- package/dist/config-loader.d.ts +78 -0
- package/dist/config-loader.js +508 -0
- package/dist/config-schema.d.ts +233 -0
- package/dist/config-schema.js +83 -0
- package/dist/create/board-checklist.d.ts +2 -0
- package/dist/create/board-checklist.js +52 -0
- package/dist/create/board-codegen.d.ts +9 -0
- package/dist/create/board-codegen.js +238 -0
- package/dist/create/board-generators.d.ts +12 -0
- package/dist/create/board-generators.js +652 -0
- package/dist/create/board-spec.d.ts +640 -0
- package/dist/create/board-spec.js +215 -0
- package/dist/create/eslint-rules-template.d.ts +2 -0
- package/dist/create/eslint-rules-template.js +672 -0
- package/dist/create/index.d.ts +11 -0
- package/dist/create/index.js +8 -0
- package/dist/create/init-scaffold.d.ts +27 -0
- package/dist/create/init-scaffold.js +150 -0
- package/dist/create/init-templates.d.ts +24 -0
- package/dist/create/init-templates.js +379 -0
- package/dist/create/init-wizard.d.ts +8 -0
- package/dist/create/init-wizard.js +168 -0
- package/dist/debug/breakpoint-loader.d.ts +24 -0
- package/dist/debug/breakpoint-loader.js +137 -0
- package/dist/debug/index.d.ts +3 -0
- package/dist/debug/index.js +7 -0
- package/dist/debug/preprocessor.d.ts +9 -0
- package/dist/debug/preprocessor.js +214 -0
- package/dist/debug/types.d.ts +32 -0
- package/dist/debug/types.js +6 -0
- package/dist/diagnostics/diagnostics-report.d.ts +51 -0
- package/dist/diagnostics/diagnostics-report.js +333 -0
- package/dist/diagnostics/json-schema.d.ts +138 -0
- package/dist/diagnostics/json-schema.js +27 -0
- package/dist/diagnostics/md-writer.d.ts +10 -0
- package/dist/diagnostics/md-writer.js +336 -0
- package/dist/diagnostics/mermaid-builder.d.ts +65 -0
- package/dist/diagnostics/mermaid-builder.js +681 -0
- package/dist/emit/cpp-emitter.d.ts +6 -0
- package/dist/emit/cpp-emitter.js +48 -0
- package/dist/emit/emitters/class-emitter.d.ts +2 -0
- package/dist/emit/emitters/class-emitter.js +523 -0
- package/dist/emit/emitters/emitter-context.d.ts +174 -0
- package/dist/emit/emitters/emitter-context.js +1 -0
- package/dist/emit/emitters/entrypoint-synthesizer.d.ts +2 -0
- package/dist/emit/emitters/entrypoint-synthesizer.js +175 -0
- package/dist/emit/emitters/function-emitter-impl.d.ts +19 -0
- package/dist/emit/emitters/function-emitter-impl.js +428 -0
- package/dist/emit/emitters/line-appender.d.ts +15 -0
- package/dist/emit/emitters/line-appender.js +344 -0
- package/dist/emit/emitters/namespace-emitter.d.ts +2 -0
- package/dist/emit/emitters/namespace-emitter.js +324 -0
- package/dist/emit/emitters/output-finalizer.d.ts +4 -0
- package/dist/emit/emitters/output-finalizer.js +267 -0
- package/dist/emit/emitters/setup.d.ts +3 -0
- package/dist/emit/emitters/setup.js +851 -0
- package/dist/emit/emitters/top-level-prep.d.ts +2 -0
- package/dist/emit/emitters/top-level-prep.js +706 -0
- package/dist/emit/emitters/type-decl-emitter.d.ts +2 -0
- package/dist/emit/emitters/type-decl-emitter.js +251 -0
- package/dist/emit/emitters/ui-emitter.d.ts +21 -0
- package/dist/emit/emitters/ui-emitter.js +564 -0
- package/dist/emit/enum-emitter.d.ts +1 -0
- package/dist/emit/enum-emitter.js +1 -0
- package/dist/emit/expression-renderer.d.ts +283 -0
- package/dist/emit/expression-renderer.js +1477 -0
- package/dist/emit/native-helpers-emitter.d.ts +11 -0
- package/dist/emit/native-helpers-emitter.js +34 -0
- package/dist/emit/route-hal-op.d.ts +5 -0
- package/dist/emit/route-hal-op.js +13 -0
- package/dist/emit/snprintf-helpers.d.ts +17 -0
- package/dist/emit/snprintf-helpers.js +462 -0
- package/dist/emit/statement-renderer.d.ts +189 -0
- package/dist/emit/statement-renderer.js +948 -0
- package/dist/emit/utils/async-state-machine.d.ts +42 -0
- package/dist/emit/utils/async-state-machine.js +343 -0
- package/dist/emit/utils/comment-helpers.d.ts +20 -0
- package/dist/emit/utils/comment-helpers.js +31 -0
- package/dist/emit/utils/cpp-helpers.d.ts +47 -0
- package/dist/emit/utils/cpp-helpers.js +85 -0
- package/dist/emit/utils/include-resolver.d.ts +58 -0
- package/dist/emit/utils/include-resolver.js +155 -0
- package/dist/emit/utils/index.d.ts +8 -0
- package/dist/emit/utils/index.js +12 -0
- package/dist/emit/utils/type-inference.d.ts +159 -0
- package/dist/emit/utils/type-inference.js +559 -0
- package/dist/eslint-check.d.ts +10 -0
- package/dist/eslint-check.js +102 -0
- package/dist/framework-package.d.ts +10 -0
- package/dist/framework-package.js +58 -0
- package/dist/framework-registry.d.ts +39 -0
- package/dist/framework-registry.js +30 -0
- package/dist/incremental-cache.d.ts +116 -0
- package/dist/incremental-cache.js +335 -0
- package/dist/ir/adc-range-validation.d.ts +11 -0
- package/dist/ir/adc-range-validation.js +250 -0
- package/dist/ir/ast-node-utils.d.ts +8 -0
- package/dist/ir/ast-node-utils.js +32 -0
- package/dist/ir/board-pin-utils.d.ts +13 -0
- package/dist/ir/board-pin-utils.js +65 -0
- package/dist/ir/board-resolver.d.ts +36 -0
- package/dist/ir/board-resolver.js +437 -0
- package/dist/ir/build-ir-state.d.ts +167 -0
- package/dist/ir/build-ir-state.js +306 -0
- package/dist/ir/build-ir.d.ts +2 -0
- package/dist/ir/build-ir.js +808 -0
- package/dist/ir/call-graph.d.ts +35 -0
- package/dist/ir/call-graph.js +194 -0
- package/dist/ir/compile-time-only.d.ts +2 -0
- package/dist/ir/compile-time-only.js +16 -0
- package/dist/ir/declaration-builders.d.ts +9 -0
- package/dist/ir/declaration-builders.js +608 -0
- package/dist/ir/entry-points.d.ts +30 -0
- package/dist/ir/entry-points.js +191 -0
- package/dist/ir/expression-to-ir.d.ts +5 -0
- package/dist/ir/expression-to-ir.js +2249 -0
- package/dist/ir/extract-property-chain.d.ts +10 -0
- package/dist/ir/extract-property-chain.js +30 -0
- package/dist/ir/feature-prescan.d.ts +3 -0
- package/dist/ir/feature-prescan.js +43 -0
- package/dist/ir/feature-registry.d.ts +30 -0
- package/dist/ir/feature-registry.js +816 -0
- package/dist/ir/filter.d.ts +7 -0
- package/dist/ir/filter.js +85 -0
- package/dist/ir/function-builder.d.ts +19 -0
- package/dist/ir/function-builder.js +670 -0
- package/dist/ir/hal/hal-emitter.d.ts +62 -0
- package/dist/ir/hal/hal-emitter.js +735 -0
- package/dist/ir/hal/hal-parser.d.ts +61 -0
- package/dist/ir/hal/hal-parser.js +473 -0
- package/dist/ir/hal/hal-plugins.d.ts +34 -0
- package/dist/ir/hal/hal-plugins.js +706 -0
- package/dist/ir/hal-resolver.d.ts +5 -0
- package/dist/ir/hal-resolver.js +5 -0
- package/dist/ir/heap-analysis.d.ts +8 -0
- package/dist/ir/heap-analysis.js +350 -0
- package/dist/ir/heap-array-validation.d.ts +24 -0
- package/dist/ir/heap-array-validation.js +29 -0
- package/dist/ir/identifier-collector.d.ts +18 -0
- package/dist/ir/identifier-collector.js +439 -0
- package/dist/ir/interrupt-analysis.d.ts +39 -0
- package/dist/ir/interrupt-analysis.js +467 -0
- package/dist/ir/memory-budget-validation.d.ts +10 -0
- package/dist/ir/memory-budget-validation.js +86 -0
- package/dist/ir/namespace-builder.d.ts +7 -0
- package/dist/ir/namespace-builder.js +152 -0
- package/dist/ir/ownership-analysis.d.ts +9 -0
- package/dist/ir/ownership-analysis.js +1207 -0
- package/dist/ir/peripheral-ownership.d.ts +3 -0
- package/dist/ir/peripheral-ownership.js +152 -0
- package/dist/ir/peripheral-symbols.d.ts +7 -0
- package/dist/ir/peripheral-symbols.js +57 -0
- package/dist/ir/peripheral-usage.d.ts +54 -0
- package/dist/ir/peripheral-usage.js +691 -0
- package/dist/ir/peripheral-validation.d.ts +8 -0
- package/dist/ir/peripheral-validation.js +77 -0
- package/dist/ir/pin-alias-conflict.d.ts +4 -0
- package/dist/ir/pin-alias-conflict.js +34 -0
- package/dist/ir/pin-capability-validation.d.ts +6 -0
- package/dist/ir/pin-capability-validation.js +413 -0
- package/dist/ir/pin-mode-validation.d.ts +10 -0
- package/dist/ir/pin-mode-validation.js +301 -0
- package/dist/ir/pin-safety.d.ts +11 -0
- package/dist/ir/pin-safety.js +58 -0
- package/dist/ir/program-analysis.d.ts +44 -0
- package/dist/ir/program-analysis.js +589 -0
- package/dist/ir/pulldown-validation.d.ts +7 -0
- package/dist/ir/pulldown-validation.js +49 -0
- package/dist/ir/pwm-timer-sharing.d.ts +4 -0
- package/dist/ir/pwm-timer-sharing.js +93 -0
- package/dist/ir/reachability.d.ts +68 -0
- package/dist/ir/reachability.js +224 -0
- package/dist/ir/register-decorators.d.ts +6 -0
- package/dist/ir/register-decorators.js +49 -0
- package/dist/ir/render-expr.d.ts +4 -0
- package/dist/ir/render-expr.js +127 -0
- package/dist/ir/resource-analysis.d.ts +19 -0
- package/dist/ir/resource-analysis.js +153 -0
- package/dist/ir/statement-to-ir.d.ts +23 -0
- package/dist/ir/statement-to-ir.js +349 -0
- package/dist/ir/symbol-table.d.ts +68 -0
- package/dist/ir/symbol-table.js +179 -0
- package/dist/ir/symbol-types.d.ts +56 -0
- package/dist/ir/symbol-types.js +107 -0
- package/dist/ir/timer0-pwm-timing-conflict.d.ts +4 -0
- package/dist/ir/timer0-pwm-timing-conflict.js +71 -0
- package/dist/ir/timing-validation.d.ts +7 -0
- package/dist/ir/timing-validation.js +95 -0
- package/dist/ir/transformers/array-methods.d.ts +8 -0
- package/dist/ir/transformers/array-methods.js +493 -0
- package/dist/ir/transformers/call-statement.d.ts +5 -0
- package/dist/ir/transformers/call-statement.js +758 -0
- package/dist/ir/transformers/callback-context-registry.d.ts +20 -0
- package/dist/ir/transformers/callback-context-registry.js +55 -0
- package/dist/ir/transformers/canvas-lowering.d.ts +42 -0
- package/dist/ir/transformers/canvas-lowering.js +249 -0
- package/dist/ir/transformers/control-flow.d.ts +8 -0
- package/dist/ir/transformers/control-flow.js +508 -0
- package/dist/ir/transformers/expressions.d.ts +7 -0
- package/dist/ir/transformers/expressions.js +406 -0
- package/dist/ir/transformers/hal-call-resolver.d.ts +29 -0
- package/dist/ir/transformers/hal-call-resolver.js +274 -0
- package/dist/ir/transformers/hal-emit-helpers.d.ts +14 -0
- package/dist/ir/transformers/hal-emit-helpers.js +63 -0
- package/dist/ir/transformers/namespace-methods.d.ts +20 -0
- package/dist/ir/transformers/namespace-methods.js +110 -0
- package/dist/ir/transformers/register-assignment.d.ts +5 -0
- package/dist/ir/transformers/register-assignment.js +56 -0
- package/dist/ir/transformers/ui-call-resolver.d.ts +149 -0
- package/dist/ir/transformers/ui-call-resolver.js +1136 -0
- package/dist/ir/transformers/ui-callback-lowering.d.ts +62 -0
- package/dist/ir/transformers/ui-callback-lowering.js +623 -0
- package/dist/ir/transformers/ui-mount.d.ts +20 -0
- package/dist/ir/transformers/ui-mount.js +35 -0
- package/dist/ir/transformers/ui-reactive.d.ts +68 -0
- package/dist/ir/transformers/ui-reactive.js +129 -0
- package/dist/ir/transformers/variables.d.ts +14 -0
- package/dist/ir/transformers/variables.js +1045 -0
- package/dist/ir/try-catch-validation.d.ts +26 -0
- package/dist/ir/try-catch-validation.js +128 -0
- package/dist/ir/type-resolution.d.ts +31 -0
- package/dist/ir/type-resolution.js +977 -0
- package/dist/ir/ui-element-auto-wire.d.ts +50 -0
- package/dist/ir/ui-element-auto-wire.js +218 -0
- package/dist/ir/unit-suspicion-validation.d.ts +12 -0
- package/dist/ir/unit-suspicion-validation.js +296 -0
- package/dist/ir/utils/walk-ir.d.ts +6 -0
- package/dist/ir/utils/walk-ir.js +162 -0
- package/dist/ir/validation-orchestrator.d.ts +4 -0
- package/dist/ir/validation-orchestrator.js +45 -0
- package/dist/libdef/base-class-resolver.d.ts +23 -0
- package/dist/libdef/base-class-resolver.js +50 -0
- package/dist/libdef/cpp-to-decl.d.ts +34 -0
- package/dist/libdef/cpp-to-decl.js +584 -0
- package/dist/libdef/header-parser.d.ts +53 -0
- package/dist/libdef/header-parser.js +269 -0
- package/dist/libdef/registry.d.ts +10 -0
- package/dist/libdef/registry.js +142 -0
- package/dist/mapping/peripheral-names.d.ts +23 -0
- package/dist/mapping/peripheral-names.js +63 -0
- package/dist/mapping/source-map.d.ts +46 -0
- package/dist/mapping/source-map.js +207 -0
- package/dist/orchestrator/dts-generator.d.ts +17 -0
- package/dist/orchestrator/dts-generator.js +83 -0
- package/dist/orchestrator/graph-builder.d.ts +18 -0
- package/dist/orchestrator/graph-builder.js +218 -0
- package/dist/orchestrator/semantic-facts-verifier.d.ts +38 -0
- package/dist/orchestrator/semantic-facts-verifier.js +121 -0
- package/dist/orchestrator/semantic-facts.d.ts +141 -0
- package/dist/orchestrator/semantic-facts.js +652 -0
- package/dist/orchestrator/type-checker.d.ts +39 -0
- package/dist/orchestrator/type-checker.js +760 -0
- package/dist/platform/async-runtime.d.ts +8 -0
- package/dist/platform/async-runtime.js +26 -0
- package/dist/platform/generic-strategy.d.ts +101 -0
- package/dist/platform/generic-strategy.js +289 -0
- package/dist/platform/index.d.ts +4 -0
- package/dist/platform/index.js +9 -0
- package/dist/platform/registry.d.ts +21 -0
- package/dist/platform/registry.js +42 -0
- package/dist/platform/toolchain.d.ts +4 -0
- package/dist/platform/toolchain.js +43 -0
- package/dist/preview/client.d.ts +1 -0
- package/dist/preview/client.js +137 -0
- package/dist/preview/server.d.ts +5 -0
- package/dist/preview/server.js +199 -0
- package/dist/profiler/index.d.ts +28 -0
- package/dist/profiler/index.js +28 -0
- package/dist/profiler/profiler.d.ts +95 -0
- package/dist/profiler/profiler.js +338 -0
- package/dist/profiler/types.d.ts +87 -0
- package/dist/profiler/types.js +12 -0
- package/dist/stores/display-profile-store.d.ts +16 -0
- package/dist/stores/display-profile-store.js +48 -0
- package/dist/stores/theme-store.d.ts +13 -0
- package/dist/stores/theme-store.js +30 -0
- package/dist/testing.d.ts +45 -0
- package/dist/testing.js +47 -0
- package/dist/transpile/resolution.d.ts +29 -0
- package/dist/transpile/resolution.js +282 -0
- package/dist/transpile.d.ts +3 -0
- package/dist/transpile.js +722 -0
- package/dist/types.d.ts +217 -0
- package/dist/types.js +1 -0
- package/dist/ui/ui-bridge.d.ts +4 -0
- package/dist/ui/ui-bridge.js +34 -0
- package/dist/ui-hook.d.ts +84 -0
- package/dist/ui-hook.js +45 -0
- package/dist/utils/cli.d.ts +3 -0
- package/dist/utils/cli.js +463 -0
- package/dist/utils/fs.d.ts +4 -0
- package/dist/utils/fs.js +23 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +8 -0
- package/dist/utils/strings.d.ts +35 -0
- package/dist/utils/strings.js +142 -0
- package/dist/utils/ui.d.ts +66 -0
- package/dist/utils/ui.js +149 -0
- package/dist/watch.d.ts +35 -0
- package/dist/watch.js +111 -0
- package/package.json +127 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Peripheral Ownership Validation
|
|
3
|
+
//
|
|
4
|
+
// Validates opt-in bus ownership via take()/release(). When take() is used
|
|
5
|
+
// anywhere in the program, this pass checks that:
|
|
6
|
+
// 1. I/O on owned buses only occurs between take() and release()
|
|
7
|
+
// 2. take() is not called on an already-owned bus (double-take error)
|
|
8
|
+
// 3. release() is not called on a bus that wasn't taken
|
|
9
|
+
//
|
|
10
|
+
// If take() is never used, no diagnostics are generated (opt-in).
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
import { scanNestedStatements } from './interrupt-analysis.js';
|
|
13
|
+
export function validatePeripheralOwnership(program) {
|
|
14
|
+
const diagnostics = [];
|
|
15
|
+
const ownedBuses = new Map();
|
|
16
|
+
const busesRequiringOwnership = new Set();
|
|
17
|
+
// Helper to extract the bus object from a property access (e.g., I2C0.begin -> I2C0)
|
|
18
|
+
const getBusName = (callee) => {
|
|
19
|
+
const busMatch = callee.match(/^(I2C\d|SPI\d|UART\d|Wire|Serial\d?)\b/);
|
|
20
|
+
return busMatch ? busMatch[1] : undefined;
|
|
21
|
+
};
|
|
22
|
+
/** Scan an expression for take() calls. */
|
|
23
|
+
const scanExpression = (expr, span) => {
|
|
24
|
+
if (!expr || typeof expr !== 'object')
|
|
25
|
+
return;
|
|
26
|
+
if (expr.kind === 'method-call') {
|
|
27
|
+
const bus = getBusName(expr.callee);
|
|
28
|
+
if (bus) {
|
|
29
|
+
if (expr.callee.endsWith('.take')) {
|
|
30
|
+
if (ownedBuses.has(bus)) {
|
|
31
|
+
diagnostics.push({
|
|
32
|
+
severity: 'error',
|
|
33
|
+
message: `Double-take: '${bus}' is already owned.`,
|
|
34
|
+
hint: `Call '${bus}.release()' before taking it again.`,
|
|
35
|
+
line: span.startLine,
|
|
36
|
+
column: span.startColumn,
|
|
37
|
+
code: 'hal-ownership-double-take',
|
|
38
|
+
source: 'peripheral-ownership',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
ownedBuses.set(bus, span);
|
|
42
|
+
busesRequiringOwnership.add(bus);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
expr.args.forEach(arg => scanExpression(arg, span));
|
|
46
|
+
}
|
|
47
|
+
if (expr.kind === 'callback') {
|
|
48
|
+
expr.statements.forEach(checkStatement);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/** Scan a statement for I/O and release() calls. */
|
|
52
|
+
const checkStatement = (stmt) => {
|
|
53
|
+
if (!stmt || typeof stmt !== 'object')
|
|
54
|
+
return;
|
|
55
|
+
const span = stmt.sourceSpan;
|
|
56
|
+
if (stmt.kind === 'call') {
|
|
57
|
+
let bus = getBusName(stmt.callee);
|
|
58
|
+
let isRelease = stmt.callee.endsWith('.release');
|
|
59
|
+
let isBegin = stmt.callee.endsWith('.begin');
|
|
60
|
+
let isTake = stmt.callee.endsWith('.take');
|
|
61
|
+
// Special case: scan HAL-resolved emits for bus usage
|
|
62
|
+
if (stmt.callee === '__EMIT__' && stmt.args[0]?.kind === 'string') {
|
|
63
|
+
const rawCode = stmt.args[0].value;
|
|
64
|
+
const busMatch = rawCode.match(/\b(Wire|SPI|Serial\d?)\./);
|
|
65
|
+
if (busMatch) {
|
|
66
|
+
const rawBus = busMatch[1];
|
|
67
|
+
if (rawBus === 'Wire')
|
|
68
|
+
bus = 'I2C0';
|
|
69
|
+
else if (rawBus === 'SPI')
|
|
70
|
+
bus = 'SPI0';
|
|
71
|
+
else if (rawBus.startsWith('Serial'))
|
|
72
|
+
bus = 'UART0';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (bus) {
|
|
76
|
+
if (isTake) {
|
|
77
|
+
if (ownedBuses.has(bus)) {
|
|
78
|
+
diagnostics.push({
|
|
79
|
+
severity: 'error',
|
|
80
|
+
message: `Double-take: '${bus}' is already owned.`,
|
|
81
|
+
hint: `Call '${bus}.release()' before taking it again.`,
|
|
82
|
+
line: span.startLine,
|
|
83
|
+
column: span.startColumn,
|
|
84
|
+
code: 'hal-ownership-double-take',
|
|
85
|
+
source: 'peripheral-ownership',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
ownedBuses.set(bus, span);
|
|
89
|
+
busesRequiringOwnership.add(bus);
|
|
90
|
+
}
|
|
91
|
+
else if (isRelease) {
|
|
92
|
+
if (!ownedBuses.has(bus)) {
|
|
93
|
+
diagnostics.push({
|
|
94
|
+
severity: 'warning',
|
|
95
|
+
message: `'${bus}.release()' called but bus was not taken.`,
|
|
96
|
+
hint: `Ensure you call '${bus}.take()' before releasing.`,
|
|
97
|
+
line: span.startLine,
|
|
98
|
+
column: span.startColumn,
|
|
99
|
+
code: 'hal-ownership-unowned-release',
|
|
100
|
+
source: 'peripheral-ownership',
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
ownedBuses.delete(bus);
|
|
104
|
+
}
|
|
105
|
+
else if (busesRequiringOwnership.has(bus) && !ownedBuses.has(bus) && !isBegin) {
|
|
106
|
+
// If ownership mode is opt-in and active for this bus, all calls must be owned
|
|
107
|
+
diagnostics.push({
|
|
108
|
+
severity: 'error',
|
|
109
|
+
message: `Unowned access: '${bus}' is used without being taken.`,
|
|
110
|
+
hint: `Call 'const bus = ${bus}.take();' and use the returned 'bus' object, or ensure '${bus}' is taken in the current scope.`,
|
|
111
|
+
line: span.startLine,
|
|
112
|
+
column: span.startColumn,
|
|
113
|
+
code: 'hal-ownership-unowned-access',
|
|
114
|
+
source: 'peripheral-ownership',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
stmt.args.forEach(arg => scanExpression(arg, span));
|
|
119
|
+
}
|
|
120
|
+
if (stmt.kind === 'var_decl' && stmt.initializer) {
|
|
121
|
+
scanExpression(stmt.initializer, span);
|
|
122
|
+
}
|
|
123
|
+
if (stmt.kind === 'assign' && stmt.value) {
|
|
124
|
+
scanExpression(stmt.value, span);
|
|
125
|
+
}
|
|
126
|
+
// Recurse into nested statements
|
|
127
|
+
scanNestedStatements(stmt, checkStatement);
|
|
128
|
+
};
|
|
129
|
+
// Scan top-level statements
|
|
130
|
+
for (const stmt of program.topLevelStatements) {
|
|
131
|
+
checkStatement(stmt);
|
|
132
|
+
}
|
|
133
|
+
// Scan function bodies
|
|
134
|
+
for (const fn of program.functions) {
|
|
135
|
+
for (const stmt of fn.statements) {
|
|
136
|
+
checkStatement(stmt);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Check for unreleased buses at end of program
|
|
140
|
+
for (const [bus, busSpan] of ownedBuses) {
|
|
141
|
+
diagnostics.push({
|
|
142
|
+
severity: 'warning',
|
|
143
|
+
message: `'${bus}' was taken but never released.`,
|
|
144
|
+
hint: `Call '${bus}.release()' when finished with the bus.`,
|
|
145
|
+
line: busSpan.startLine,
|
|
146
|
+
column: busSpan.startColumn,
|
|
147
|
+
code: 'hal-ownership-leak',
|
|
148
|
+
source: 'peripheral-ownership',
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return diagnostics;
|
|
152
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type PeripheralReceiverKind = "i2c" | "spi" | "serial";
|
|
2
|
+
export declare function inferPeripheralKindByName(name: string): PeripheralReceiverKind | undefined;
|
|
3
|
+
export declare function parsePeripheralInstance(name: string): {
|
|
4
|
+
kind: PeripheralReceiverKind;
|
|
5
|
+
index: number;
|
|
6
|
+
} | undefined;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Peripheral symbol helpers
|
|
3
|
+
//
|
|
4
|
+
// Shared detection/parsing for named bus instances like I2C0, SPI1, UART0,
|
|
5
|
+
// Serial, and Serial2.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
const I2C_INSTANCE_PATTERN = /^I2C(\d+)$/;
|
|
8
|
+
const SPI_INSTANCE_PATTERN = /^SPI(\d+)$/;
|
|
9
|
+
const UART_INSTANCE_PATTERN = /^UART(\d+)$/;
|
|
10
|
+
const SERIAL_INSTANCE_PATTERN = /^Serial(\d*)$/;
|
|
11
|
+
import { getCurrentBoardConstants } from "./build-ir-state.js";
|
|
12
|
+
export function inferPeripheralKindByName(name) {
|
|
13
|
+
const resolved = resolveCanonicalPeripheral(name);
|
|
14
|
+
return resolved?.kind;
|
|
15
|
+
}
|
|
16
|
+
export function parsePeripheralInstance(name) {
|
|
17
|
+
return resolveCanonicalPeripheral(name);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolves a peripheral name (e.g. "UART0", "Serial", "Wire", "I2C1")
|
|
21
|
+
* to its canonical kind and index using the current board manifest aliases.
|
|
22
|
+
*/
|
|
23
|
+
function resolveCanonicalPeripheral(name) {
|
|
24
|
+
const bc = getCurrentBoardConstants();
|
|
25
|
+
// 1. Check if name is already canonical (UART0, I2C1, etc.)
|
|
26
|
+
const canonicalMatch = name.match(/^(UART|I2C|SPI)(\d+)$/);
|
|
27
|
+
if (canonicalMatch) {
|
|
28
|
+
return {
|
|
29
|
+
kind: canonicalMatch[1] === "UART" ? "serial" : canonicalMatch[1].toLowerCase(),
|
|
30
|
+
index: parseInt(canonicalMatch[2], 10)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// 2. Check if name is a platform alias (e.g. "Serial" -> UART0)
|
|
34
|
+
if (bc) {
|
|
35
|
+
for (const [key, value] of bc.entries()) {
|
|
36
|
+
if (key.startsWith("peripherals.aliases.") && value === name) {
|
|
37
|
+
const canonical = key.replace("peripherals.aliases.", "");
|
|
38
|
+
const match = canonical.match(/^(UART|I2C|SPI)(\d+)$/);
|
|
39
|
+
if (match) {
|
|
40
|
+
return {
|
|
41
|
+
kind: match[1] === "UART" ? "serial" : match[1].toLowerCase(),
|
|
42
|
+
index: parseInt(match[2], 10)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// 3. Fallback to standard Arduino patterns (e.g. Serial2 -> UART2)
|
|
49
|
+
const serialMatch = name.match(/^Serial(\d*)$/);
|
|
50
|
+
if (serialMatch) {
|
|
51
|
+
return {
|
|
52
|
+
kind: "serial",
|
|
53
|
+
index: serialMatch[1] === "" ? 0 : parseInt(serialMatch[1], 10)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ProgramIR } from '../api/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Tracks which hardware peripherals are used in the program.
|
|
4
|
+
*/
|
|
5
|
+
export interface PeripheralUsage {
|
|
6
|
+
/** ADC is used (analogRead on A0-A5) */
|
|
7
|
+
adc: boolean;
|
|
8
|
+
/** PWM is used (analogWrite on D3, D5, D6, D9, D10, D11) */
|
|
9
|
+
pwm: boolean;
|
|
10
|
+
/** External interrupts are used (attachInterrupt on D2, D3) */
|
|
11
|
+
externalInterrupts: boolean;
|
|
12
|
+
/** Timer0-based timing is used (millis, micros) */
|
|
13
|
+
timer0: boolean;
|
|
14
|
+
/** I2C bus is used */
|
|
15
|
+
i2c: boolean;
|
|
16
|
+
/** SPI bus is used */
|
|
17
|
+
spi: boolean;
|
|
18
|
+
/** UART/Serial is used */
|
|
19
|
+
uart: boolean;
|
|
20
|
+
/** Specific PWM pins used (for targeted timer initialization) */
|
|
21
|
+
pwmPinsUsed: Set<number>;
|
|
22
|
+
/** Specific ADC channels used */
|
|
23
|
+
adcChannelsUsed: Set<number>;
|
|
24
|
+
/** Pins configured as output (for batch DDR initialization) */
|
|
25
|
+
outputPins: Set<number>;
|
|
26
|
+
/** Pins configured as input with pullup */
|
|
27
|
+
inputPullupPins: Set<number>;
|
|
28
|
+
/** Pins configured as input (no pullup) */
|
|
29
|
+
inputPins: Set<number>;
|
|
30
|
+
/** Pins configured as input with pulldown */
|
|
31
|
+
inputPulldownPins: Set<number>;
|
|
32
|
+
/** Specific I2C bus instances used (0 for I2C0, 1 for I2C1, etc.) */
|
|
33
|
+
i2cInstancesUsed: Set<number>;
|
|
34
|
+
/** Specific SPI bus instances used (0 for SPI0, 1 for SPI1, etc.) */
|
|
35
|
+
spiInstancesUsed: Set<number>;
|
|
36
|
+
/** Specific UART instances used (0 for UART0/Serial, 1 for UART1/Serial1, etc.) */
|
|
37
|
+
uartInstancesUsed: Set<number>;
|
|
38
|
+
/** All pin names used (for unsafe pin validation) */
|
|
39
|
+
pinsUsed: Set<string>;
|
|
40
|
+
/** Specific pins used for external interrupts */
|
|
41
|
+
interruptPinsUsed: Set<number>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create an empty PeripheralUsage object.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createEmptyPeripheralUsage(): PeripheralUsage;
|
|
47
|
+
/**
|
|
48
|
+
* Analyze a program's IR to detect peripheral usage.
|
|
49
|
+
*/
|
|
50
|
+
export declare function analyzePeripheralUsage(program: ProgramIR): PeripheralUsage;
|
|
51
|
+
/**
|
|
52
|
+
* Parse pin number from receiver string (D13 -> 13, A0 -> 14, LED -> 13)
|
|
53
|
+
*/
|
|
54
|
+
export declare function parsePinNumber(receiver: string): number | null;
|