@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,706 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { getCurrentBoardConstants, halInstances } from "../build-ir-state.js";
|
|
3
|
+
import { resolveExpressionText } from "./hal-emitter.js";
|
|
4
|
+
import { renderExprAsText } from "../render-expr.js";
|
|
5
|
+
/**
|
|
6
|
+
* Split a comma-joined argument list back into individual arguments, respecting
|
|
7
|
+
* nesting (parens/brackets/braces) and string literals so a comma inside one of
|
|
8
|
+
* those does not split. Used to recover the per-arg array from the spread
|
|
9
|
+
* mechanism's comma-joined text (e.g. for printf varargs).
|
|
10
|
+
*/
|
|
11
|
+
function splitArgList(joined) {
|
|
12
|
+
const out = [];
|
|
13
|
+
let depth = 0;
|
|
14
|
+
let current = "";
|
|
15
|
+
let inString = null;
|
|
16
|
+
for (let i = 0; i < joined.length; i++) {
|
|
17
|
+
const ch = joined[i];
|
|
18
|
+
if (inString) {
|
|
19
|
+
current += ch;
|
|
20
|
+
if (ch === "\\") {
|
|
21
|
+
// Keep the escaped char with its backslash.
|
|
22
|
+
current += joined[++i] ?? "";
|
|
23
|
+
}
|
|
24
|
+
else if (ch === inString) {
|
|
25
|
+
inString = null;
|
|
26
|
+
}
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (ch === '"' || ch === "'") {
|
|
30
|
+
inString = ch;
|
|
31
|
+
current += ch;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (ch === "(" || ch === "[" || ch === "{")
|
|
35
|
+
depth++;
|
|
36
|
+
else if (ch === ")" || ch === "]" || ch === "}")
|
|
37
|
+
depth--;
|
|
38
|
+
if (ch === "," && depth === 0) {
|
|
39
|
+
out.push(current.trim());
|
|
40
|
+
current = "";
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
current += ch;
|
|
44
|
+
}
|
|
45
|
+
if (current.trim())
|
|
46
|
+
out.push(current.trim());
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
function resolveI2cBufferArg(args, idx, instance, paramNames, callArgTexts, paramDefaults, callArgs) {
|
|
50
|
+
const arg = args[idx];
|
|
51
|
+
if (!arg)
|
|
52
|
+
return null;
|
|
53
|
+
if (ts.isArrayLiteralExpression(arg)) {
|
|
54
|
+
const bytes = arg.elements.map((element) => {
|
|
55
|
+
if (ts.isNumericLiteral(element))
|
|
56
|
+
return Number(element.text);
|
|
57
|
+
return resolveExpressionText(element, instance, paramNames, callArgTexts, paramDefaults) ?? "0";
|
|
58
|
+
});
|
|
59
|
+
return { kind: "bytes", bytes };
|
|
60
|
+
}
|
|
61
|
+
if (ts.isIdentifier(arg) && callArgs) {
|
|
62
|
+
const paramIdx = paramNames.indexOf(arg.text);
|
|
63
|
+
if (paramIdx !== -1) {
|
|
64
|
+
const paramArg = callArgs[paramIdx];
|
|
65
|
+
if (paramArg?.kind === "array") {
|
|
66
|
+
const bytes = paramArg.elements.map((element) => renderExprAsText(element) ?? "0");
|
|
67
|
+
return { kind: "bytes", bytes };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const data = resolveSemanticArg(args, idx, instance, paramNames, callArgTexts, paramDefaults);
|
|
72
|
+
if (data === null)
|
|
73
|
+
return null;
|
|
74
|
+
return { kind: "buffer", data };
|
|
75
|
+
}
|
|
76
|
+
/** Resolve a single argument from a semantic call's AST node list. */
|
|
77
|
+
export function resolveSemanticArg(args, idx, instance, paramNames, callArgTexts, paramDefaults) {
|
|
78
|
+
const arg = args[idx];
|
|
79
|
+
if (!arg)
|
|
80
|
+
return null;
|
|
81
|
+
return resolveExpressionText(arg, instance, paramNames, callArgTexts, paramDefaults);
|
|
82
|
+
}
|
|
83
|
+
/** Resolve a numeric argument, returning its numeric value or null. */
|
|
84
|
+
export function resolveNumericArg(args, idx, instance, paramNames, callArgTexts, paramDefaults) {
|
|
85
|
+
const text = resolveSemanticArg(args, idx, instance, paramNames, callArgTexts, paramDefaults);
|
|
86
|
+
if (text === null)
|
|
87
|
+
return null;
|
|
88
|
+
// R1: Boolean coercion — true → 1, false → 0
|
|
89
|
+
if (text === "true")
|
|
90
|
+
return 1;
|
|
91
|
+
if (text === "false")
|
|
92
|
+
return 0;
|
|
93
|
+
const n = Number(text);
|
|
94
|
+
return isNaN(n) ? null : n;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve an argument that may be a compile-time literal OR a runtime expression.
|
|
98
|
+
* Tries numeric resolution first (for compile-time folding); falls back to the
|
|
99
|
+
* raw expression text for runtime values (variables, computed expressions).
|
|
100
|
+
* Returns the number (if literal) or the expression string, or null if unresolvable.
|
|
101
|
+
*/
|
|
102
|
+
function resolveNumericOrExpression(args, idx, instance, paramNames, callArgTexts, paramDefaults) {
|
|
103
|
+
const num = resolveNumericArg(args, idx, instance, paramNames, callArgTexts, paramDefaults);
|
|
104
|
+
if (num !== null)
|
|
105
|
+
return num;
|
|
106
|
+
return resolveSemanticArg(args, idx, instance, paramNames, callArgTexts, paramDefaults);
|
|
107
|
+
}
|
|
108
|
+
/** Extract the MCU port name from the current HAL instance, if available. */
|
|
109
|
+
export function portFromInstance(instance) {
|
|
110
|
+
const port = instance.fieldValues.get('_port');
|
|
111
|
+
return port && port !== '' ? port : undefined;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Resolve a boardResolve() argument to a dot-path string.
|
|
115
|
+
* Handles both static string paths ("peripherals.adc.0.resolution") and
|
|
116
|
+
* dynamic paths ("peripherals.adc.0.referenceVoltages." + this._reference).
|
|
117
|
+
*/
|
|
118
|
+
export function tryResolveBoardResolveArg(args, instance, paramNames, callArgTexts, paramDefaults) {
|
|
119
|
+
const arg = args[0];
|
|
120
|
+
if (!arg)
|
|
121
|
+
return null;
|
|
122
|
+
// Static string literal: boardResolve("peripherals.adc.0.resolution")
|
|
123
|
+
if (ts.isStringLiteral(arg))
|
|
124
|
+
return arg.text;
|
|
125
|
+
// Dynamic path via string concat or template literal. Flatten the expression
|
|
126
|
+
// into a dot-path WITHOUT going through resolveExpressionText (which renders
|
|
127
|
+
// `+` as a C++ expression "a + b", corrupting the path). String literals
|
|
128
|
+
// contribute their text; this._field contributes the resolved field value;
|
|
129
|
+
// template literals contribute head + interpolated spans.
|
|
130
|
+
return resolveConcatPath(arg, instance, paramNames, callArgTexts, paramDefaults);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Recursively flatten a `+`-concatenation / template-literal expression into a
|
|
134
|
+
* board-resolve dot-path string. Returns null if any operand cannot be
|
|
135
|
+
* resolved to a concrete string fragment.
|
|
136
|
+
*/
|
|
137
|
+
export function resolveConcatPath(expr, instance, paramNames, callArgTexts, paramDefaults) {
|
|
138
|
+
// String literal fragment
|
|
139
|
+
if (ts.isStringLiteral(expr))
|
|
140
|
+
return expr.text;
|
|
141
|
+
// No-substitution template literal: `text`
|
|
142
|
+
if (ts.isNoSubstitutionTemplateLiteral(expr))
|
|
143
|
+
return expr.text;
|
|
144
|
+
// Template expression: `text ${expr} more`
|
|
145
|
+
if (ts.isTemplateExpression(expr)) {
|
|
146
|
+
let result = expr.head.text;
|
|
147
|
+
for (const span of expr.templateSpans) {
|
|
148
|
+
const resolved = resolveConcatPath(span.expression, instance, paramNames, callArgTexts, paramDefaults);
|
|
149
|
+
if (resolved === null)
|
|
150
|
+
return null;
|
|
151
|
+
result += resolved + span.literal.text;
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
// Binary `+` concatenation — recurse on both sides
|
|
156
|
+
if (ts.isBinaryExpression(expr) && expr.operatorToken.kind === ts.SyntaxKind.PlusToken) {
|
|
157
|
+
const left = resolveConcatPath(expr.left, instance, paramNames, callArgTexts, paramDefaults);
|
|
158
|
+
const right = resolveConcatPath(expr.right, instance, paramNames, callArgTexts, paramDefaults);
|
|
159
|
+
if (left === null || right === null)
|
|
160
|
+
return null;
|
|
161
|
+
return left + right;
|
|
162
|
+
}
|
|
163
|
+
// Parenthesized expression — unwrap
|
|
164
|
+
if (ts.isParenthesizedExpression(expr)) {
|
|
165
|
+
return resolveConcatPath(expr.expression, instance, paramNames, callArgTexts, paramDefaults);
|
|
166
|
+
}
|
|
167
|
+
// this._field → resolved instance field value (e.g. this._instance → "1")
|
|
168
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
169
|
+
const isThis = expr.expression.kind === ts.SyntaxKind.ThisKeyword
|
|
170
|
+
|| (ts.isIdentifier(expr.expression) && expr.expression.text === "this")
|
|
171
|
+
|| expr.expression.getText() === "this";
|
|
172
|
+
if (isThis) {
|
|
173
|
+
const fieldName = expr.name.text;
|
|
174
|
+
const val = instance.fieldValues.get(fieldName)
|
|
175
|
+
?? instance.fieldValues.get(fieldName.startsWith("_") ? fieldName.slice(1) : "_" + fieldName);
|
|
176
|
+
if (val !== undefined && val !== null)
|
|
177
|
+
return val;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Try to resolve a compound return expression that contains semantic calls.
|
|
184
|
+
* For example, `(gpioRead(this._pin) === HIGH)` should produce a halOp for
|
|
185
|
+
* `gpioRead` and return a combined expression with the strategy-resolved form.
|
|
186
|
+
* Returns the resolved text with placeholders, or null if no semantic calls found.
|
|
187
|
+
*/
|
|
188
|
+
export function tryResolveCompoundSemanticReturn(expr, instance, paramNames, callArgTexts, paramDefaults, halOps, callArgs) {
|
|
189
|
+
const semanticPlaceholders = new Map();
|
|
190
|
+
// Walk the expression tree looking for semantic calls
|
|
191
|
+
function findSemanticCalls(node) {
|
|
192
|
+
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
|
|
193
|
+
const semanticOp = tryResolveSemanticCall(node.expression.text, node.arguments, instance, paramNames, callArgTexts, paramDefaults, callArgs);
|
|
194
|
+
if (semanticOp) {
|
|
195
|
+
halOps.push(semanticOp);
|
|
196
|
+
semanticPlaceholders.set(node, halOps.length - 1);
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
let found = false;
|
|
201
|
+
if (ts.isBinaryExpression(node)) {
|
|
202
|
+
found = findSemanticCalls(node.left) || findSemanticCalls(node.right);
|
|
203
|
+
}
|
|
204
|
+
else if (ts.isParenthesizedExpression(node)) {
|
|
205
|
+
found = findSemanticCalls(node.expression);
|
|
206
|
+
}
|
|
207
|
+
else if (ts.isAsExpression(node)) {
|
|
208
|
+
found = findSemanticCalls(node.expression);
|
|
209
|
+
}
|
|
210
|
+
else if (ts.isPrefixUnaryExpression(node)) {
|
|
211
|
+
found = findSemanticCalls(node.operand);
|
|
212
|
+
}
|
|
213
|
+
else if (ts.isConditionalExpression(node)) {
|
|
214
|
+
found = findSemanticCalls(node.condition) || findSemanticCalls(node.whenTrue) || findSemanticCalls(node.whenFalse);
|
|
215
|
+
}
|
|
216
|
+
return found;
|
|
217
|
+
}
|
|
218
|
+
if (!findSemanticCalls(expr))
|
|
219
|
+
return null;
|
|
220
|
+
// Now resolve the expression text, substituting semantic calls with their resolved forms
|
|
221
|
+
function resolveWithSemantics(node) {
|
|
222
|
+
// If this node was a semantic call, return a placeholder for the halOp expression
|
|
223
|
+
const opIdx = semanticPlaceholders.get(node);
|
|
224
|
+
if (opIdx !== undefined) {
|
|
225
|
+
return `__hal_op_expr_${opIdx}__`;
|
|
226
|
+
}
|
|
227
|
+
// Delegate non-semantic parts to resolveExpressionText
|
|
228
|
+
if (ts.isBinaryExpression(node)) {
|
|
229
|
+
const left = resolveWithSemantics(node.left);
|
|
230
|
+
const right = resolveWithSemantics(node.right);
|
|
231
|
+
if (left === null || right === null)
|
|
232
|
+
return null;
|
|
233
|
+
let op = node.operatorToken.getText();
|
|
234
|
+
if (op === "===")
|
|
235
|
+
op = "==";
|
|
236
|
+
else if (op === "!==")
|
|
237
|
+
op = "!=";
|
|
238
|
+
return `${left} ${op} ${right}`;
|
|
239
|
+
}
|
|
240
|
+
if (ts.isParenthesizedExpression(node)) {
|
|
241
|
+
const inner = resolveWithSemantics(node.expression);
|
|
242
|
+
return inner !== null ? `(${inner})` : null;
|
|
243
|
+
}
|
|
244
|
+
if (ts.isAsExpression(node)) {
|
|
245
|
+
// Unwrap type assertions (e.g., gpioRead(pin) as unknown as boolean)
|
|
246
|
+
return resolveWithSemantics(node.expression);
|
|
247
|
+
}
|
|
248
|
+
if (ts.isPrefixUnaryExpression(node)) {
|
|
249
|
+
const operand = resolveWithSemantics(node.operand);
|
|
250
|
+
if (operand === null)
|
|
251
|
+
return null;
|
|
252
|
+
const op = node.operator === ts.SyntaxKind.ExclamationToken ? "!" : node.operator === ts.SyntaxKind.MinusToken ? "-" : "";
|
|
253
|
+
return `${op}${operand}`;
|
|
254
|
+
}
|
|
255
|
+
// Fall back to text resolution for non-semantic parts
|
|
256
|
+
return resolveExpressionText(node, instance, paramNames, callArgTexts, paramDefaults);
|
|
257
|
+
}
|
|
258
|
+
const resolved = resolveWithSemantics(expr);
|
|
259
|
+
if (resolved === null)
|
|
260
|
+
return null;
|
|
261
|
+
return resolved.replace(/===/g, "==").replace(/!==/g, "!=");
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Try to resolve a semantic HAL function call to a HALOpIR node.
|
|
265
|
+
* Returns the HALOpIR if the function name is recognized, or null.
|
|
266
|
+
*/
|
|
267
|
+
export function tryResolveSemanticCall(fnName, args, instance, paramNames, callArgTexts, paramDefaults, callArgs) {
|
|
268
|
+
// Extract MCU port name from instance (set by Pin.fromPort())
|
|
269
|
+
const port = portFromInstance(instance);
|
|
270
|
+
switch (fnName) {
|
|
271
|
+
// ── GPIO ──
|
|
272
|
+
case "gpioWrite": {
|
|
273
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
274
|
+
if (pin === null)
|
|
275
|
+
return null;
|
|
276
|
+
// Try literal resolution first (compile-time 0/1/true/false)
|
|
277
|
+
const numValue = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
278
|
+
if (numValue !== null) {
|
|
279
|
+
return { operation: "gpio.write", port, pin, value: (numValue ? 1 : 0) };
|
|
280
|
+
}
|
|
281
|
+
// Fall back to runtime expression (e.g. a variable, negated expression)
|
|
282
|
+
const exprValue = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
283
|
+
if (exprValue !== null) {
|
|
284
|
+
return { operation: "gpio.write", port, pin, value: exprValue };
|
|
285
|
+
}
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
case "gpioRead": {
|
|
289
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
290
|
+
if (pin === null)
|
|
291
|
+
return null;
|
|
292
|
+
return { operation: "gpio.read", port, pin };
|
|
293
|
+
}
|
|
294
|
+
case "gpioToggle": {
|
|
295
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
296
|
+
if (pin === null)
|
|
297
|
+
return null;
|
|
298
|
+
return { operation: "gpio.toggle", port, pin };
|
|
299
|
+
}
|
|
300
|
+
case "gpioSetMode": {
|
|
301
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
302
|
+
const mode = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
303
|
+
if (pin === null || mode === null)
|
|
304
|
+
return null;
|
|
305
|
+
return { operation: "gpio.set_mode", port, pin, mode };
|
|
306
|
+
}
|
|
307
|
+
// ── PWM ──
|
|
308
|
+
case "pwmWrite": {
|
|
309
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
310
|
+
const duty = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
311
|
+
if (pin === null || duty === null)
|
|
312
|
+
return null;
|
|
313
|
+
return { operation: "pwm.write", port, pin, duty };
|
|
314
|
+
}
|
|
315
|
+
// ── ADC ──
|
|
316
|
+
case "adcRead": {
|
|
317
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
318
|
+
if (pin === null)
|
|
319
|
+
return null;
|
|
320
|
+
return { operation: "adc.read", port, pin };
|
|
321
|
+
}
|
|
322
|
+
case "adcSetReference": {
|
|
323
|
+
const ref = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
324
|
+
if (ref === null)
|
|
325
|
+
return null;
|
|
326
|
+
const numRef = Number(ref);
|
|
327
|
+
return { operation: "adc.set_reference", reference: isNaN(numRef) ? ref : numRef };
|
|
328
|
+
}
|
|
329
|
+
case "adcReadVoltage": {
|
|
330
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
331
|
+
if (pin === null)
|
|
332
|
+
return null;
|
|
333
|
+
const op = { operation: "adc.read_voltage", port, pin };
|
|
334
|
+
const bc = getCurrentBoardConstants();
|
|
335
|
+
if (bc) {
|
|
336
|
+
// Check if ADC has a non-default reference set
|
|
337
|
+
const adcInst = halInstances.get("ADC");
|
|
338
|
+
const ref = adcInst?.fieldValues.get("_reference");
|
|
339
|
+
const refKey = ref && ref !== "DEFAULT" ? ref : null;
|
|
340
|
+
const vRefPath = refKey
|
|
341
|
+
? `peripherals.adc.0.referenceVoltages.${refKey}`
|
|
342
|
+
: `peripherals.adc.0.referenceVoltage`;
|
|
343
|
+
const vRef = bc.get(vRefPath);
|
|
344
|
+
const maxValue = bc.get("peripherals.adc.0.maxValue");
|
|
345
|
+
if (vRef !== undefined)
|
|
346
|
+
op.vRef = Number(vRef);
|
|
347
|
+
if (maxValue !== undefined)
|
|
348
|
+
op.maxValue = Number(maxValue);
|
|
349
|
+
}
|
|
350
|
+
return op;
|
|
351
|
+
}
|
|
352
|
+
// ── DAC ──
|
|
353
|
+
case "dacWrite": {
|
|
354
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
355
|
+
const value = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
356
|
+
if (pin === null || value === null)
|
|
357
|
+
return null;
|
|
358
|
+
return { operation: "dac.write", port, pin, value };
|
|
359
|
+
}
|
|
360
|
+
// ── Watchdog timer ──
|
|
361
|
+
case "wdtEnable": {
|
|
362
|
+
const timeout = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
363
|
+
if (timeout === null)
|
|
364
|
+
return null;
|
|
365
|
+
return { operation: "wdt.enable", timeout };
|
|
366
|
+
}
|
|
367
|
+
case "wdtReset":
|
|
368
|
+
return { operation: "wdt.reset" };
|
|
369
|
+
case "wdtDisable":
|
|
370
|
+
return { operation: "wdt.disable" };
|
|
371
|
+
// ── Power ──
|
|
372
|
+
case "powerDeepSleep": {
|
|
373
|
+
const ms = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
374
|
+
if (ms === null)
|
|
375
|
+
return null;
|
|
376
|
+
return { operation: "power.deep_sleep", ms };
|
|
377
|
+
}
|
|
378
|
+
case "powerLightSleep":
|
|
379
|
+
return { operation: "power.light_sleep" };
|
|
380
|
+
case "powerSetCpuFrequency": {
|
|
381
|
+
const mhz = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
382
|
+
if (mhz === null)
|
|
383
|
+
return null;
|
|
384
|
+
return { operation: "power.set_cpu_frequency", mhz };
|
|
385
|
+
}
|
|
386
|
+
// ── Interrupts ──
|
|
387
|
+
case "interruptAttach": {
|
|
388
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
389
|
+
const handler = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
390
|
+
const mode = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
|
|
391
|
+
if (pin === null || handler === null || mode === null)
|
|
392
|
+
return null;
|
|
393
|
+
return { operation: "interrupt.attach", port, pin, handler, mode };
|
|
394
|
+
}
|
|
395
|
+
case "interruptDetach": {
|
|
396
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
397
|
+
if (pin === null)
|
|
398
|
+
return null;
|
|
399
|
+
return { operation: "interrupt.detach", port, pin };
|
|
400
|
+
}
|
|
401
|
+
// ── Tone ──
|
|
402
|
+
case "tonePlay": {
|
|
403
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
404
|
+
const frequency = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
405
|
+
const duration = resolveNumericOrExpression(args, 2, instance, paramNames, callArgTexts, paramDefaults);
|
|
406
|
+
if (pin === null || frequency === null)
|
|
407
|
+
return null;
|
|
408
|
+
return { operation: "tone.play", port, pin, frequency, ...(duration !== null ? { duration } : {}) };
|
|
409
|
+
}
|
|
410
|
+
case "toneStop": {
|
|
411
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
412
|
+
if (pin === null)
|
|
413
|
+
return null;
|
|
414
|
+
return { operation: "tone.stop", port, pin };
|
|
415
|
+
}
|
|
416
|
+
// ── Timing ──
|
|
417
|
+
case "delayMs": {
|
|
418
|
+
const ms = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
419
|
+
if (ms === null)
|
|
420
|
+
return null;
|
|
421
|
+
return { operation: "timing.delay", ms };
|
|
422
|
+
}
|
|
423
|
+
case "delayMicro": {
|
|
424
|
+
const us = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
425
|
+
if (us === null)
|
|
426
|
+
return null;
|
|
427
|
+
return { operation: "timing.delay_microseconds", us };
|
|
428
|
+
}
|
|
429
|
+
case "getMillis":
|
|
430
|
+
return { operation: "timing.millis" };
|
|
431
|
+
case "getMicros":
|
|
432
|
+
return { operation: "timing.micros" };
|
|
433
|
+
case "getFreeHeap":
|
|
434
|
+
return { operation: "timing.free_heap" };
|
|
435
|
+
// ── I2C ──
|
|
436
|
+
case "i2cBegin": {
|
|
437
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
438
|
+
const address = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
439
|
+
if (bus === null)
|
|
440
|
+
return null;
|
|
441
|
+
return { operation: "i2c.begin", bus, ...(address !== null ? { address } : {}) };
|
|
442
|
+
}
|
|
443
|
+
case "i2cEnd": {
|
|
444
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
445
|
+
if (bus === null)
|
|
446
|
+
return null;
|
|
447
|
+
return { operation: "i2c.end", bus };
|
|
448
|
+
}
|
|
449
|
+
case "i2cSetClock": {
|
|
450
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
451
|
+
const hz = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
452
|
+
if (bus === null || hz === null)
|
|
453
|
+
return null;
|
|
454
|
+
return { operation: "i2c.set_clock", bus, hz };
|
|
455
|
+
}
|
|
456
|
+
case "i2cBeginTx": {
|
|
457
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
458
|
+
const address = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
459
|
+
if (bus === null || address === null)
|
|
460
|
+
return null;
|
|
461
|
+
return { operation: "i2c.begin_transmission", bus, address };
|
|
462
|
+
}
|
|
463
|
+
case "i2cWrite": {
|
|
464
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
465
|
+
if (bus === null)
|
|
466
|
+
return null;
|
|
467
|
+
const resolved = resolveI2cBufferArg(args, 1, instance, paramNames, callArgTexts, paramDefaults, callArgs);
|
|
468
|
+
if (!resolved)
|
|
469
|
+
return null;
|
|
470
|
+
if (resolved.kind === "bytes") {
|
|
471
|
+
return { operation: "i2c.write_bytes", bus, bytes: resolved.bytes };
|
|
472
|
+
}
|
|
473
|
+
return { operation: "i2c.write", bus, data: resolved.data };
|
|
474
|
+
}
|
|
475
|
+
case "i2cWriteBuffer": {
|
|
476
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
477
|
+
if (bus === null)
|
|
478
|
+
return null;
|
|
479
|
+
const resolved = resolveI2cBufferArg(args, 1, instance, paramNames, callArgTexts, paramDefaults, callArgs);
|
|
480
|
+
if (!resolved)
|
|
481
|
+
return null;
|
|
482
|
+
if (resolved.kind === "bytes") {
|
|
483
|
+
return { operation: "i2c.write_bytes", bus, bytes: resolved.bytes };
|
|
484
|
+
}
|
|
485
|
+
return { operation: "i2c.write_buffer", bus, data: resolved.data };
|
|
486
|
+
}
|
|
487
|
+
case "i2cReadBuffer": {
|
|
488
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
489
|
+
const count = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
490
|
+
if (bus === null || count === null)
|
|
491
|
+
return null;
|
|
492
|
+
return { operation: "i2c.read_buffer", bus, count, buffer: "__HAL_READ_BUF__" };
|
|
493
|
+
}
|
|
494
|
+
case "i2cEndTx": {
|
|
495
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
496
|
+
const stop = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
497
|
+
if (bus === null || stop === null)
|
|
498
|
+
return null;
|
|
499
|
+
return { operation: "i2c.end_transmission", bus, stop: stop !== "false" };
|
|
500
|
+
}
|
|
501
|
+
case "i2cRequestFrom": {
|
|
502
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
503
|
+
const address = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
504
|
+
const quantity = resolveNumericOrExpression(args, 2, instance, paramNames, callArgTexts, paramDefaults);
|
|
505
|
+
if (bus === null || address === null || quantity === null)
|
|
506
|
+
return null;
|
|
507
|
+
// stop is optional; default to true (Arduino sends a STOP by default).
|
|
508
|
+
const stopRaw = resolveSemanticArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
|
|
509
|
+
const stop = stopRaw === null ? true : stopRaw !== "false";
|
|
510
|
+
return { operation: "i2c.request_from", bus, address, quantity, stop };
|
|
511
|
+
}
|
|
512
|
+
case "i2cAvailable": {
|
|
513
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
514
|
+
if (bus === null)
|
|
515
|
+
return null;
|
|
516
|
+
return { operation: "i2c.available", bus };
|
|
517
|
+
}
|
|
518
|
+
case "i2cRead": {
|
|
519
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
520
|
+
if (bus === null)
|
|
521
|
+
return null;
|
|
522
|
+
return { operation: "i2c.read", bus };
|
|
523
|
+
}
|
|
524
|
+
// ── SPI ──
|
|
525
|
+
case "spiBegin": {
|
|
526
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
527
|
+
if (bus === null)
|
|
528
|
+
return null;
|
|
529
|
+
return { operation: "spi.begin", bus };
|
|
530
|
+
}
|
|
531
|
+
case "spiEnd": {
|
|
532
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
533
|
+
if (bus === null)
|
|
534
|
+
return null;
|
|
535
|
+
return { operation: "spi.end", bus };
|
|
536
|
+
}
|
|
537
|
+
case "spiTransfer": {
|
|
538
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
539
|
+
const data = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
540
|
+
if (bus === null || data === null)
|
|
541
|
+
return null;
|
|
542
|
+
return { operation: "spi.transfer", bus, data };
|
|
543
|
+
}
|
|
544
|
+
case "spiBeginTx": {
|
|
545
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
546
|
+
const settings = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
547
|
+
if (bus === null || settings === null)
|
|
548
|
+
return null;
|
|
549
|
+
return { operation: "spi.begin_transaction", bus, settings };
|
|
550
|
+
}
|
|
551
|
+
case "spiEndTx": {
|
|
552
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
553
|
+
if (bus === null)
|
|
554
|
+
return null;
|
|
555
|
+
return { operation: "spi.end_transaction", bus };
|
|
556
|
+
}
|
|
557
|
+
case "spiCsLow": {
|
|
558
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
559
|
+
if (pin === null)
|
|
560
|
+
return null;
|
|
561
|
+
return { operation: "spi.cs_low", port, pin };
|
|
562
|
+
}
|
|
563
|
+
case "spiCsHigh": {
|
|
564
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
565
|
+
if (pin === null)
|
|
566
|
+
return null;
|
|
567
|
+
return { operation: "spi.cs_high", port, pin };
|
|
568
|
+
}
|
|
569
|
+
case "spiSetMode": {
|
|
570
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
571
|
+
const mode = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
572
|
+
if (bus === null || mode === null)
|
|
573
|
+
return null;
|
|
574
|
+
return { operation: "spi.set_mode", bus, mode };
|
|
575
|
+
}
|
|
576
|
+
case "spiSetBitOrder": {
|
|
577
|
+
const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
578
|
+
const order = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
579
|
+
if (bus === null || order === null)
|
|
580
|
+
return null;
|
|
581
|
+
return { operation: "spi.set_bit_order", bus, order };
|
|
582
|
+
}
|
|
583
|
+
// ── UART ──
|
|
584
|
+
case "uartBegin": {
|
|
585
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
586
|
+
const baud = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
587
|
+
if (port === null || baud === null)
|
|
588
|
+
return null;
|
|
589
|
+
return { operation: "uart.begin", port, baud };
|
|
590
|
+
}
|
|
591
|
+
case "uartEnd": {
|
|
592
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
593
|
+
if (port === null)
|
|
594
|
+
return null;
|
|
595
|
+
return { operation: "uart.end", port };
|
|
596
|
+
}
|
|
597
|
+
case "uartPrint": {
|
|
598
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
599
|
+
const value = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
600
|
+
if (port === null || value === null)
|
|
601
|
+
return null;
|
|
602
|
+
return { operation: "uart.print", port, value };
|
|
603
|
+
}
|
|
604
|
+
case "uartPrintln": {
|
|
605
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
606
|
+
const value = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
607
|
+
if (port === null || value === null)
|
|
608
|
+
return null;
|
|
609
|
+
return { operation: "uart.println", port, value };
|
|
610
|
+
}
|
|
611
|
+
case "uartWrite": {
|
|
612
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
613
|
+
const data = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
614
|
+
if (port === null || data === null)
|
|
615
|
+
return null;
|
|
616
|
+
return { operation: "uart.write", port, data };
|
|
617
|
+
}
|
|
618
|
+
case "uartRead": {
|
|
619
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
620
|
+
if (port === null)
|
|
621
|
+
return null;
|
|
622
|
+
return { operation: "uart.read", port };
|
|
623
|
+
}
|
|
624
|
+
case "uartPeek": {
|
|
625
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
626
|
+
if (port === null)
|
|
627
|
+
return null;
|
|
628
|
+
return { operation: "uart.peek", port };
|
|
629
|
+
}
|
|
630
|
+
case "uartAvailable": {
|
|
631
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
632
|
+
if (port === null)
|
|
633
|
+
return null;
|
|
634
|
+
return { operation: "uart.available", port };
|
|
635
|
+
}
|
|
636
|
+
case "uartFlush": {
|
|
637
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
638
|
+
if (port === null)
|
|
639
|
+
return null;
|
|
640
|
+
return { operation: "uart.flush", port };
|
|
641
|
+
}
|
|
642
|
+
case "uartPrintf": {
|
|
643
|
+
const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
644
|
+
const format = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
645
|
+
if (port === null || format === null)
|
|
646
|
+
return null;
|
|
647
|
+
// The HAL declares `...args: any[]`; the third semantic-call arg is the
|
|
648
|
+
// `args` rest identifier. resolveSemanticArg expands it via the spread
|
|
649
|
+
// mechanism into a comma-joined string — split it back into the per-arg
|
|
650
|
+
// list the UartPrintfOp expects.
|
|
651
|
+
const spreadText = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
|
|
652
|
+
const varArgs = spreadText !== null && spreadText !== "" ? splitArgList(spreadText) : [];
|
|
653
|
+
return { operation: "uart.printf", port, format, args: varArgs };
|
|
654
|
+
}
|
|
655
|
+
// ── Pulse ──
|
|
656
|
+
case "pulseIn_": {
|
|
657
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
658
|
+
const value = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
659
|
+
const timeout = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
|
|
660
|
+
if (pin === null || value === null)
|
|
661
|
+
return null;
|
|
662
|
+
return { operation: "pulse.in", port, pin, value: (value ? 1 : 0), ...(timeout !== null ? { timeout } : {}) };
|
|
663
|
+
}
|
|
664
|
+
case "pulseInLong_": {
|
|
665
|
+
const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
666
|
+
const value = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
667
|
+
if (pin === null || value === null)
|
|
668
|
+
return null;
|
|
669
|
+
return { operation: "pulse.in_long", port, pin, value: (value ? 1 : 0) };
|
|
670
|
+
}
|
|
671
|
+
// ── Shift ──
|
|
672
|
+
case "shiftOut_": {
|
|
673
|
+
const dataPin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
674
|
+
const clockPin = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
675
|
+
const bitOrder = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
|
|
676
|
+
const value = resolveNumericArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
|
|
677
|
+
if (dataPin === null || clockPin === null || bitOrder === null || value === null)
|
|
678
|
+
return null;
|
|
679
|
+
return { operation: "shift.out", dataPin, clockPin, bitOrder, value };
|
|
680
|
+
}
|
|
681
|
+
case "shiftIn_": {
|
|
682
|
+
const dataPin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
683
|
+
const clockPin = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
|
|
684
|
+
const bitOrder = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
|
|
685
|
+
if (dataPin === null || clockPin === null || bitOrder === null)
|
|
686
|
+
return null;
|
|
687
|
+
return { operation: "shift.in", dataPin, clockPin, bitOrder };
|
|
688
|
+
}
|
|
689
|
+
// ── Board ──
|
|
690
|
+
case "boardResolve": {
|
|
691
|
+
const p = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
692
|
+
if (p === null)
|
|
693
|
+
return null;
|
|
694
|
+
return { operation: "board.resolve", path: p };
|
|
695
|
+
}
|
|
696
|
+
// ── Raw C++ passthrough ──
|
|
697
|
+
case "rawCpp": {
|
|
698
|
+
const code = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
|
|
699
|
+
if (code === null)
|
|
700
|
+
return null;
|
|
701
|
+
return { operation: "raw", code };
|
|
702
|
+
}
|
|
703
|
+
default:
|
|
704
|
+
return null;
|
|
705
|
+
}
|
|
706
|
+
}
|