@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,250 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// ADC Range Validation
|
|
3
|
+
//
|
|
4
|
+
// Detects comparisons against analogRead() values that exceed the board's
|
|
5
|
+
// ADC resolution (e.g., comparing to > 1023 on a 10-bit Arduino Uno).
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
/**
|
|
8
|
+
* Get ADC configuration from board constants.
|
|
9
|
+
*/
|
|
10
|
+
function getADCConfig(boardConstants) {
|
|
11
|
+
if (!boardConstants)
|
|
12
|
+
return null;
|
|
13
|
+
// Try to get ADC resolution from board constants
|
|
14
|
+
const resolution = boardConstants.get('peripherals.adc.0.resolution');
|
|
15
|
+
if (resolution !== undefined) {
|
|
16
|
+
return {
|
|
17
|
+
resolution,
|
|
18
|
+
maxValue: Math.pow(2, resolution) - 1,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
// No board ADC resolution available — cannot validate
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if an expression is an analog read.
|
|
26
|
+
*
|
|
27
|
+
* Two IR shapes carry an ADC read inline:
|
|
28
|
+
* - `hal-expr` with operation `adc.read` / `adc.read_voltage` (the structured
|
|
29
|
+
* HAL form — the common case for `A0.readAnalog()` inline in a comparison)
|
|
30
|
+
* - `raw` whose value text contains `analogRead(` (the lowered text form,
|
|
31
|
+
* reached when the HAL op has already been resolved to C++ text)
|
|
32
|
+
* An assignment `const v = A0.readAnalog(); if (v > 2000)` is NOT caught — `v`
|
|
33
|
+
* is an identifier by the comparison site, and correlating the two would
|
|
34
|
+
* require data-flow analysis beyond this validator's scope.
|
|
35
|
+
*/
|
|
36
|
+
function isAnalogRead(expr) {
|
|
37
|
+
if (!expr || typeof expr !== 'object')
|
|
38
|
+
return false;
|
|
39
|
+
if (expr.kind === 'hal-expr') {
|
|
40
|
+
const op = expr.operation?.operation;
|
|
41
|
+
return op === 'adc.read' || op === 'adc.read_voltage';
|
|
42
|
+
}
|
|
43
|
+
if (expr.kind === 'raw') {
|
|
44
|
+
return /analogRead\s*\(/.test(expr.value);
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Try to extract a numeric value from an expression.
|
|
50
|
+
*/
|
|
51
|
+
function extractNumericValue(expr) {
|
|
52
|
+
if (!expr || typeof expr !== 'object')
|
|
53
|
+
return null;
|
|
54
|
+
if (expr.kind === 'number') {
|
|
55
|
+
return expr.value;
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check binary comparison expressions for ADC range issues.
|
|
61
|
+
*/
|
|
62
|
+
function checkComparisonForADCRange(left, operator, right, adcConfig, diagnostics) {
|
|
63
|
+
// Check if one side is an analog read and the other is a literal
|
|
64
|
+
let analogReadSide = null;
|
|
65
|
+
let literalValue = null;
|
|
66
|
+
if (isAnalogRead(left) && extractNumericValue(right) !== null) {
|
|
67
|
+
analogReadSide = 'left';
|
|
68
|
+
literalValue = extractNumericValue(right);
|
|
69
|
+
}
|
|
70
|
+
else if (isAnalogRead(right) && extractNumericValue(left) !== null) {
|
|
71
|
+
analogReadSide = 'right';
|
|
72
|
+
literalValue = extractNumericValue(left);
|
|
73
|
+
}
|
|
74
|
+
if (analogReadSide === null || literalValue === null)
|
|
75
|
+
return;
|
|
76
|
+
// Check if the literal exceeds ADC max
|
|
77
|
+
if (literalValue > adcConfig.maxValue) {
|
|
78
|
+
// Adjust operator based on which side the analog read is on
|
|
79
|
+
const comparisonDesc = analogReadSide === 'left'
|
|
80
|
+
? `analogRead() ${operator} ${literalValue}`
|
|
81
|
+
: `${literalValue} ${operator} analogRead()`;
|
|
82
|
+
diagnostics.push({
|
|
83
|
+
severity: 'info',
|
|
84
|
+
message: `Comparison ${comparisonDesc} may never be true. ADC resolution is ${adcConfig.resolution}-bit (max ${adcConfig.maxValue}) on this board.`,
|
|
85
|
+
code: 'adc-range-warning',
|
|
86
|
+
source: 'adc-range-validation',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Scan an expression for ADC range issues.
|
|
92
|
+
*/
|
|
93
|
+
function scanExpressionForADCRange(expr, adcConfig, diagnostics) {
|
|
94
|
+
if (!expr || typeof expr !== 'object')
|
|
95
|
+
return;
|
|
96
|
+
// Check binary comparisons
|
|
97
|
+
if (expr.kind === 'binary') {
|
|
98
|
+
const bin = expr;
|
|
99
|
+
const comparisonOps = ['>', '>=', '<', '<=', '===', '==', '!==', '!='];
|
|
100
|
+
if (comparisonOps.includes(bin.operator)) {
|
|
101
|
+
checkComparisonForADCRange(bin.left, bin.operator, bin.right, adcConfig, diagnostics);
|
|
102
|
+
}
|
|
103
|
+
// Recursively scan both sides
|
|
104
|
+
scanExpressionForADCRange(bin.left, adcConfig, diagnostics);
|
|
105
|
+
scanExpressionForADCRange(bin.right, adcConfig, diagnostics);
|
|
106
|
+
}
|
|
107
|
+
// Check ternary conditions
|
|
108
|
+
if (expr.kind === 'ternary') {
|
|
109
|
+
const ternary = expr;
|
|
110
|
+
scanExpressionForADCRange(ternary.condition, adcConfig, diagnostics);
|
|
111
|
+
scanExpressionForADCRange(ternary.whenTrue, adcConfig, diagnostics);
|
|
112
|
+
scanExpressionForADCRange(ternary.whenFalse, adcConfig, diagnostics);
|
|
113
|
+
}
|
|
114
|
+
// Check property access
|
|
115
|
+
if (expr.kind === 'property-access') {
|
|
116
|
+
const pa = expr;
|
|
117
|
+
scanExpressionForADCRange(pa.object, adcConfig, diagnostics);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Scan a statement for ADC range issues.
|
|
122
|
+
*/
|
|
123
|
+
function scanStatementForADCRange(stmt, adcConfig, diagnostics) {
|
|
124
|
+
if (!stmt || typeof stmt !== 'object')
|
|
125
|
+
return;
|
|
126
|
+
switch (stmt.kind) {
|
|
127
|
+
case 'var_decl': {
|
|
128
|
+
const varDecl = stmt;
|
|
129
|
+
if (varDecl.initializer) {
|
|
130
|
+
scanExpressionForADCRange(varDecl.initializer, adcConfig, diagnostics);
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case 'assign': {
|
|
135
|
+
const assign = stmt;
|
|
136
|
+
if (assign.value) {
|
|
137
|
+
scanExpressionForADCRange(assign.value, adcConfig, diagnostics);
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
case 'if': {
|
|
142
|
+
const ifStmt = stmt;
|
|
143
|
+
if (ifStmt.condition) {
|
|
144
|
+
scanExpressionForADCRange(ifStmt.condition, adcConfig, diagnostics);
|
|
145
|
+
}
|
|
146
|
+
if (ifStmt.thenBranch) {
|
|
147
|
+
for (const s of ifStmt.thenBranch) {
|
|
148
|
+
scanStatementForADCRange(s, adcConfig, diagnostics);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (ifStmt.elseBranch) {
|
|
152
|
+
for (const s of ifStmt.elseBranch) {
|
|
153
|
+
scanStatementForADCRange(s, adcConfig, diagnostics);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case 'while': {
|
|
159
|
+
const whileStmt = stmt;
|
|
160
|
+
if (whileStmt.condition) {
|
|
161
|
+
scanExpressionForADCRange(whileStmt.condition, adcConfig, diagnostics);
|
|
162
|
+
}
|
|
163
|
+
if (whileStmt.body) {
|
|
164
|
+
for (const s of whileStmt.body) {
|
|
165
|
+
scanStatementForADCRange(s, adcConfig, diagnostics);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case 'for': {
|
|
171
|
+
const forStmt = stmt;
|
|
172
|
+
if (forStmt.condition) {
|
|
173
|
+
scanExpressionForADCRange(forStmt.condition, adcConfig, diagnostics);
|
|
174
|
+
}
|
|
175
|
+
if (forStmt.body) {
|
|
176
|
+
for (const s of forStmt.body) {
|
|
177
|
+
scanStatementForADCRange(s, adcConfig, diagnostics);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
case 'return': {
|
|
183
|
+
const retStmt = stmt;
|
|
184
|
+
if (retStmt.value) {
|
|
185
|
+
scanExpressionForADCRange(retStmt.value, adcConfig, diagnostics);
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case 'call': {
|
|
190
|
+
const call = stmt;
|
|
191
|
+
if (call.args) {
|
|
192
|
+
for (const arg of call.args) {
|
|
193
|
+
scanExpressionForADCRange(arg, adcConfig, diagnostics);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
default:
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Validate ADC range comparisons in a program.
|
|
204
|
+
*
|
|
205
|
+
* @param program - The program IR to validate
|
|
206
|
+
* @param boardConstants - Board constants containing ADC resolution
|
|
207
|
+
* @returns Array of diagnostics for ADC range issues
|
|
208
|
+
*/
|
|
209
|
+
export function validateADCRange(program, boardConstants) {
|
|
210
|
+
const diagnostics = [];
|
|
211
|
+
const adcConfig = getADCConfig(boardConstants);
|
|
212
|
+
if (!adcConfig)
|
|
213
|
+
return diagnostics;
|
|
214
|
+
// Scan top-level statements
|
|
215
|
+
if (program.topLevelStatements) {
|
|
216
|
+
for (const stmt of program.topLevelStatements) {
|
|
217
|
+
scanStatementForADCRange(stmt, adcConfig, diagnostics);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Scan function bodies
|
|
221
|
+
if (program.functions) {
|
|
222
|
+
for (const fn of program.functions) {
|
|
223
|
+
if (fn.statements) {
|
|
224
|
+
for (const stmt of fn.statements) {
|
|
225
|
+
scanStatementForADCRange(stmt, adcConfig, diagnostics);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// Scan class methods
|
|
231
|
+
if (program.classes) {
|
|
232
|
+
for (const cls of program.classes) {
|
|
233
|
+
if (cls.methods) {
|
|
234
|
+
for (const method of cls.methods) {
|
|
235
|
+
if (method.statements) {
|
|
236
|
+
for (const stmt of method.statements) {
|
|
237
|
+
scanStatementForADCRange(stmt, adcConfig, diagnostics);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (cls.constructor?.statements) {
|
|
243
|
+
for (const stmt of cls.constructor.statements) {
|
|
244
|
+
scanStatementForADCRange(stmt, adcConfig, diagnostics);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return diagnostics;
|
|
250
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { Diagnostic, SourceSpan } from "../types.js";
|
|
3
|
+
export declare function makeDiagnostic(sourceText: string, position: number, message: string, severity?: Diagnostic["severity"], code?: string): Diagnostic;
|
|
4
|
+
export declare function makeSourceSpan(node: ts.Node, filePath: string, sourceText: string): SourceSpan;
|
|
5
|
+
export declare function extractNodeComments(node: ts.Node, sourceText: string): {
|
|
6
|
+
leadingComments: string[];
|
|
7
|
+
trailingComments: string[];
|
|
8
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { withLineColumn } from "../utils/strings.js";
|
|
3
|
+
export function makeDiagnostic(sourceText, position, message, severity = "warning", code) {
|
|
4
|
+
const { line, column } = withLineColumn(sourceText, position);
|
|
5
|
+
return { severity, message, line, column, code };
|
|
6
|
+
}
|
|
7
|
+
export function makeSourceSpan(node, filePath, sourceText) {
|
|
8
|
+
const startOffset = node.getStart();
|
|
9
|
+
const endOffset = node.getEnd();
|
|
10
|
+
const start = withLineColumn(sourceText, startOffset);
|
|
11
|
+
const end = withLineColumn(sourceText, endOffset);
|
|
12
|
+
return {
|
|
13
|
+
filePath,
|
|
14
|
+
startOffset,
|
|
15
|
+
endOffset,
|
|
16
|
+
startLine: start.line,
|
|
17
|
+
startColumn: start.column,
|
|
18
|
+
endLine: end.line,
|
|
19
|
+
endColumn: end.column,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function extractNodeComments(node, sourceText) {
|
|
23
|
+
const leadingRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart()) ?? [];
|
|
24
|
+
const trailingRanges = ts.getTrailingCommentRanges(sourceText, node.getEnd()) ?? [];
|
|
25
|
+
const normalize = (ranges) => ranges
|
|
26
|
+
.map((range) => sourceText.slice(range.pos, range.end).trim())
|
|
27
|
+
.filter((value) => value.length > 0);
|
|
28
|
+
return {
|
|
29
|
+
leadingComments: normalize(leadingRanges),
|
|
30
|
+
trailingComments: normalize(trailingRanges),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BoardConstants } from './board-resolver.js';
|
|
2
|
+
interface BoardPinInfo {
|
|
3
|
+
number?: number;
|
|
4
|
+
name: string;
|
|
5
|
+
aliases: string[];
|
|
6
|
+
warnings: string[];
|
|
7
|
+
note?: string;
|
|
8
|
+
alternateFunctions: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function getBoardPins(boardConstants: BoardConstants | undefined): BoardPinInfo[];
|
|
11
|
+
export declare function findBoardPinByName(pinName: string, boardConstants: BoardConstants | undefined): BoardPinInfo | undefined;
|
|
12
|
+
export declare function formatPinReference(usedPinName: string, boardPin: BoardPinInfo | undefined): string;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
function parseCsvField(value) {
|
|
2
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
3
|
+
return [];
|
|
4
|
+
}
|
|
5
|
+
return value
|
|
6
|
+
.split(',')
|
|
7
|
+
.map(entry => entry.trim())
|
|
8
|
+
.filter(Boolean);
|
|
9
|
+
}
|
|
10
|
+
export function getBoardPins(boardConstants) {
|
|
11
|
+
if (!boardConstants) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const pins = [];
|
|
15
|
+
for (const [key, value] of boardConstants) {
|
|
16
|
+
if (!key.startsWith('pins.all.') || !key.endsWith('.name') || typeof value !== 'string') {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
const prefix = key.slice(0, -'.name'.length);
|
|
20
|
+
const numberValue = boardConstants.get(`${prefix}.number`);
|
|
21
|
+
const aliases = parseCsvField(boardConstants.get(`${prefix}.aliases`));
|
|
22
|
+
const warnings = parseCsvField(boardConstants.get(`${prefix}.warnings`));
|
|
23
|
+
const alternateFunctions = parseCsvField(boardConstants.get(`${prefix}.alternateFunctions`));
|
|
24
|
+
const noteValue = boardConstants.get(`${prefix}.notes`);
|
|
25
|
+
pins.push({
|
|
26
|
+
number: typeof numberValue === 'number' ? numberValue : undefined,
|
|
27
|
+
name: value,
|
|
28
|
+
aliases,
|
|
29
|
+
warnings,
|
|
30
|
+
note: typeof noteValue === 'string' && noteValue.length > 0 ? noteValue : undefined,
|
|
31
|
+
alternateFunctions,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return pins.sort((left, right) => {
|
|
35
|
+
const leftNumber = left.number ?? Number.MAX_SAFE_INTEGER;
|
|
36
|
+
const rightNumber = right.number ?? Number.MAX_SAFE_INTEGER;
|
|
37
|
+
return leftNumber - rightNumber || left.name.localeCompare(right.name);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export function findBoardPinByName(pinName, boardConstants) {
|
|
41
|
+
const pins = getBoardPins(boardConstants);
|
|
42
|
+
const match = pins.find(pin => pin.name === pinName || pin.aliases.includes(pinName));
|
|
43
|
+
if (match)
|
|
44
|
+
return match;
|
|
45
|
+
// Fallback: resolve D/A patterns by pin number.
|
|
46
|
+
// D3 → pin with number 3, A0 → pin with number 0+analogOffset.
|
|
47
|
+
const dMatch = pinName.match(/^D(\d+)$/);
|
|
48
|
+
if (dMatch) {
|
|
49
|
+
const num = parseInt(dMatch[1], 10);
|
|
50
|
+
return pins.find(pin => pin.number === num);
|
|
51
|
+
}
|
|
52
|
+
const aMatch = pinName.match(/^A(\d+)$/);
|
|
53
|
+
if (aMatch && boardConstants) {
|
|
54
|
+
const offset = Number(boardConstants.get('pins.analogOffset') ?? 0);
|
|
55
|
+
const num = parseInt(aMatch[1], 10) + offset;
|
|
56
|
+
return pins.find(pin => pin.number === num);
|
|
57
|
+
}
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
export function formatPinReference(usedPinName, boardPin) {
|
|
61
|
+
if (!boardPin || usedPinName === boardPin.name) {
|
|
62
|
+
return `Pin '${usedPinName}'`;
|
|
63
|
+
}
|
|
64
|
+
return `Pin '${usedPinName}' (alias of ${boardPin.name})`;
|
|
65
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { BoardConstants } from "../api/shared/index.js";
|
|
2
|
+
export type { BoardConstants };
|
|
3
|
+
/**
|
|
4
|
+
* Returns a set of default board constants (standard Arduino Uno-like)
|
|
5
|
+
* used as a fallback when no specific board manifest is loaded.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getDefaultBoardConstants(): BoardConstants;
|
|
8
|
+
/**
|
|
9
|
+
* Parse a TypeScript board-definition source file and return a flat map of
|
|
10
|
+
* all compile-time constant scalar values exported as a `BoardDefinition`.
|
|
11
|
+
*
|
|
12
|
+
* Properties whose values are arrays, spread elements, or other non-literal
|
|
13
|
+
* expressions are silently skipped (no partial constant maps for board pins
|
|
14
|
+
* etc. are needed by the emitter).
|
|
15
|
+
*
|
|
16
|
+
* @param defFilePath Absolute path to the board definition `index.ts`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveBoardConstants(defFilePath: string): BoardConstants;
|
|
19
|
+
/**
|
|
20
|
+
* Given a source file path and a relative import module specifier, check
|
|
21
|
+
* whether the import resolves to a TypeCAD board-definition package
|
|
22
|
+
* (path pattern: /code/board-*\/index.ts).
|
|
23
|
+
*
|
|
24
|
+
* Returns the absolute path to the board index.ts on match, otherwise
|
|
25
|
+
* undefined.
|
|
26
|
+
*/
|
|
27
|
+
export declare function tryResolveBoardDefFile(fromFile: string, moduleSpecifier: string, boardPackage?: string): string | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the framework-specific build target (e.g. Arduino FQBN) from the
|
|
30
|
+
* board package's manifest.
|
|
31
|
+
*
|
|
32
|
+
* @param boardPackage Board package identifier or path.
|
|
33
|
+
* @param configPath Path to the project config file (for relative resolution).
|
|
34
|
+
* @param framework Target framework name (default: 'arduino').
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveBoardBuildTarget(boardPackage: string, configPath: string, framework?: string): string | undefined;
|