@typecad/cuttlefish 1.0.0-alpha.13 → 1.0.0-alpha.15

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.
Files changed (343) hide show
  1. package/README.md +82 -79
  2. package/assets/editor-extensions/typecad-debug/README.md +141 -0
  3. package/assets/editor-extensions/typecad-debug/out/extension.js +347 -0
  4. package/assets/editor-extensions/typecad-debug/out/extension.js.map +1 -0
  5. package/assets/editor-extensions/typecad-debug/package.json +76 -0
  6. package/assets/editor-extensions/typecad-ui/LICENSE +27 -0
  7. package/assets/editor-extensions/typecad-ui/README.md +52 -0
  8. package/assets/editor-extensions/typecad-ui/file-icon-dark.png +0 -0
  9. package/assets/editor-extensions/typecad-ui/file-icon-light.png +0 -0
  10. package/assets/editor-extensions/typecad-ui/icon.png +0 -0
  11. package/assets/editor-extensions/typecad-ui/language-configuration.json +43 -0
  12. package/assets/editor-extensions/typecad-ui/package.json +54 -0
  13. package/assets/editor-extensions/typecad-ui/snippets/typecad-ui.json +80 -0
  14. package/assets/editor-extensions/typecad-ui/syntaxes/markdown-ui.json +45 -0
  15. package/assets/editor-extensions/typecad-ui/syntaxes/typecad-ui.tmLanguage.json +1269 -0
  16. package/dist/api/config.d.ts +30 -27
  17. package/dist/api/schema/types.d.ts +20 -3
  18. package/dist/api/shared/async-runtime-static.d.ts +1 -1
  19. package/dist/api/shared/async-runtime-static.js +5 -5
  20. package/dist/api/shared/async-types.d.ts +3 -2
  21. package/dist/api/shared/board-catalog.d.ts +2 -0
  22. package/dist/api/shared/board-catalog.js +6 -0
  23. package/dist/api/shared/board-resolver.d.ts +4 -7
  24. package/dist/api/shared/board-resolver.js +2 -1
  25. package/dist/api/shared/coop-scheduler.d.ts +1 -1
  26. package/dist/api/shared/coop-scheduler.js +1 -1
  27. package/dist/api/shared/cpp-type-ir.d.ts +1 -1
  28. package/dist/api/shared/cpp-type-ir.js +1 -1
  29. package/dist/api/shared/display-profile.d.ts +1 -1
  30. package/dist/api/shared/display-profile.js +3 -5
  31. package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
  32. package/dist/api/shared/framework-manifest-registry.js +0 -1
  33. package/dist/api/shared/framework-manifest.d.ts +65 -507
  34. package/dist/api/shared/framework-manifest.js +6 -11
  35. package/dist/api/shared/hal-op-ir.d.ts +294 -685
  36. package/dist/api/shared/hal-op-ir.js +31 -65
  37. package/dist/api/shared/index.d.ts +0 -4
  38. package/dist/api/shared/index.js +1 -7
  39. package/dist/api/shared/ir-core.d.ts +6 -0
  40. package/dist/api/shared/ir-declarations.d.ts +4 -0
  41. package/dist/api/shared/ir.d.ts +1 -3
  42. package/dist/api/shared/platform-strategy.d.ts +14 -37
  43. package/dist/api/shared/polyfill-helper-registry.js +0 -5
  44. package/dist/api/shared/polyfill-types.js +0 -27
  45. package/dist/api/shared/promise-runtime.js +3 -3
  46. package/dist/api/shared/spdx-licenses.d.ts +12 -10
  47. package/dist/api/shared/spdx-licenses.js +1 -1
  48. package/dist/api/shared/toolchain-types.d.ts +1 -1
  49. package/dist/api/shared/toolchain-types.js +3 -3
  50. package/dist/api/shared/types.d.ts +0 -3
  51. package/dist/api/shared/validate-framework-manifest.js +13 -33
  52. package/dist/board-catalog/dts-reader.d.ts +220 -0
  53. package/dist/board-catalog/dts-reader.js +1052 -0
  54. package/dist/board-catalog/index.d.ts +11 -0
  55. package/dist/board-catalog/index.js +12 -0
  56. package/dist/board-catalog/pinconfig.d.ts +48 -0
  57. package/dist/board-catalog/pinconfig.js +263 -0
  58. package/dist/board-catalog/sdk.d.ts +82 -0
  59. package/dist/board-catalog/sdk.js +180 -0
  60. package/dist/board-catalog/store.d.ts +196 -0
  61. package/dist/board-catalog/store.js +363 -0
  62. package/dist/board-catalog/types.d.ts +233 -0
  63. package/dist/board-catalog/types.js +7 -0
  64. package/dist/board-catalog/walker.d.ts +112 -0
  65. package/dist/board-catalog/walker.js +1101 -0
  66. package/dist/cli-utils.d.ts +2 -2
  67. package/dist/cli-utils.js +5 -5
  68. package/dist/cli.js +227 -244
  69. package/dist/config-loader.d.ts +14 -19
  70. package/dist/config-loader.js +242 -78
  71. package/dist/config-schema.d.ts +19 -227
  72. package/dist/config-schema.js +9 -8
  73. package/dist/contract/board-generator.d.ts +4 -4
  74. package/dist/contract/board-generator.js +16 -5
  75. package/dist/contract/contract-parser.d.ts +36 -127
  76. package/dist/contract/contract-parser.js +76 -0
  77. package/dist/contract/index.d.ts +1 -1
  78. package/dist/contract/index.js +70 -21
  79. package/dist/create/active-board-catalog.d.ts +9 -0
  80. package/dist/create/active-board-catalog.js +94 -0
  81. package/dist/create/board-catalog.generated.d.ts +96 -0
  82. package/dist/create/board-catalog.generated.js +128737 -0
  83. package/dist/create/board-search.d.ts +23 -0
  84. package/dist/create/board-search.js +88 -0
  85. package/dist/create/editor-integration.d.ts +32 -0
  86. package/dist/create/editor-integration.js +257 -0
  87. package/dist/create/eslint-rules-template.d.ts +2 -2
  88. package/dist/create/framework-catalog.d.ts +48 -8
  89. package/dist/create/framework-catalog.js +58 -44
  90. package/dist/create/index.d.ts +8 -13
  91. package/dist/create/index.js +5 -9
  92. package/dist/create/mcu-target.d.ts +39 -0
  93. package/dist/create/mcu-target.js +80 -0
  94. package/dist/create/pack-targets.d.ts +19 -0
  95. package/dist/create/pack-targets.js +56 -0
  96. package/dist/create/{init-scaffold.d.ts → scaffold.d.ts} +8 -11
  97. package/dist/create/{init-scaffold.js → scaffold.js} +28 -87
  98. package/dist/create/templates.d.ts +51 -0
  99. package/dist/create/{init-templates.js → templates.js} +135 -116
  100. package/dist/create/wizard.d.ts +19 -0
  101. package/dist/create/wizard.js +314 -0
  102. package/dist/debug/preprocessor.d.ts +5 -0
  103. package/dist/debug/preprocessor.js +31 -7
  104. package/dist/diagnostics/diagnostics-report.d.ts +1 -1
  105. package/dist/diagnostics/diagnostics-report.js +3 -11
  106. package/dist/diagnostics/json-schema.d.ts +1 -1
  107. package/dist/diagnostics/md-writer.js +2 -2
  108. package/dist/diagnostics/mermaid-builder.d.ts +1 -1
  109. package/dist/diagnostics/mermaid-builder.js +1 -1
  110. package/dist/emit/cpp-emitter.js +4 -1
  111. package/dist/emit/emitters/class-emitter.js +32 -4
  112. package/dist/emit/emitters/emitter-context.d.ts +11 -0
  113. package/dist/emit/emitters/entrypoint-synthesizer.js +1 -1
  114. package/dist/emit/emitters/function-emitter-impl.js +33 -17
  115. package/dist/emit/emitters/output-finalizer.d.ts +7 -0
  116. package/dist/emit/emitters/output-finalizer.js +31 -23
  117. package/dist/emit/emitters/setup.js +147 -63
  118. package/dist/emit/emitters/top-level-prep.js +1 -1
  119. package/dist/emit/emitters/type-decl-emitter.js +13 -8
  120. package/dist/emit/emitters/ui-emitter.js +1 -1
  121. package/dist/emit/expression-renderer.d.ts +3 -3
  122. package/dist/emit/expression-renderer.js +17 -7
  123. package/dist/emit/route-hal-op.js +17 -48
  124. package/dist/emit/snprintf-helpers.d.ts +1 -3
  125. package/dist/emit/snprintf-helpers.js +1 -39
  126. package/dist/emit/statement-renderer.d.ts +0 -4
  127. package/dist/emit/statement-renderer.js +54 -45
  128. package/dist/emit/utils/async-state-machine.d.ts +16 -9
  129. package/dist/emit/utils/async-state-machine.js +56 -54
  130. package/dist/emit/utils/comment-helpers.d.ts +0 -8
  131. package/dist/emit/utils/comment-helpers.js +1 -1
  132. package/dist/emit/utils/cpp-helpers.d.ts +2 -2
  133. package/dist/emit/utils/cpp-helpers.js +2 -2
  134. package/dist/emit/utils/hal-op-cpp-type.js +4 -6
  135. package/dist/emit/utils/index.d.ts +3 -3
  136. package/dist/emit/utils/index.js +3 -3
  137. package/dist/emit/utils/type-inference.d.ts +1 -29
  138. package/dist/emit/utils/type-inference.js +0 -75
  139. package/dist/framework-package.d.ts +3 -0
  140. package/dist/framework-package.js +23 -6
  141. package/dist/framework-registry.d.ts +5 -5
  142. package/dist/frameworks/native/graphics/terminal-preview.d.ts +5 -0
  143. package/dist/frameworks/native/graphics/terminal-preview.js +33 -0
  144. package/dist/frameworks/native/index.d.ts +3 -0
  145. package/dist/frameworks/native/index.js +15 -0
  146. package/dist/frameworks/native/native-compile.d.ts +17 -0
  147. package/dist/frameworks/native/native-compile.js +170 -0
  148. package/dist/frameworks/native/native-config.d.ts +41 -0
  149. package/dist/frameworks/native/native-config.js +7 -0
  150. package/dist/frameworks/native/strategy.d.ts +97 -0
  151. package/dist/frameworks/native/strategy.js +664 -0
  152. package/dist/ir/board-resolver.d.ts +18 -23
  153. package/dist/ir/board-resolver.js +43 -401
  154. package/dist/ir/build-ir-state.d.ts +3 -0
  155. package/dist/ir/build-ir-state.js +42 -0
  156. package/dist/ir/build-ir.d.ts +1 -1
  157. package/dist/ir/build-ir.js +64 -45
  158. package/dist/ir/declaration-builders.js +1 -0
  159. package/dist/ir/expression-to-ir.js +17 -10
  160. package/dist/ir/hal/hal-emitter.d.ts +0 -2
  161. package/dist/ir/hal/hal-emitter.js +92 -41
  162. package/dist/ir/hal/hal-parser.d.ts +5 -5
  163. package/dist/ir/hal/hal-parser.js +128 -36
  164. package/dist/ir/hal/hal-plugins.d.ts +0 -1
  165. package/dist/ir/hal/hal-plugins.js +425 -716
  166. package/dist/ir/heap-analysis.js +2 -41
  167. package/dist/ir/identifier-collector.js +32 -20
  168. package/dist/ir/network-validation.js +7 -11
  169. package/dist/ir/ownership-analysis.js +75 -13
  170. package/dist/ir/peripheral-usage.d.ts +8 -2
  171. package/dist/ir/peripheral-usage.js +78 -149
  172. package/dist/ir/peripheral-validation.js +23 -3
  173. package/dist/ir/pin-capability-validation.d.ts +12 -0
  174. package/dist/ir/pin-capability-validation.js +61 -97
  175. package/dist/ir/pin-mode-validation.js +5 -5
  176. package/dist/ir/program-analysis.d.ts +8 -15
  177. package/dist/ir/program-analysis.js +140 -323
  178. package/dist/ir/pulldown-validation.js +11 -4
  179. package/dist/ir/resource-analysis.js +15 -3
  180. package/dist/ir/statement-to-ir.js +0 -6
  181. package/dist/ir/timing-validation.js +1 -1
  182. package/dist/ir/transformers/array-methods.js +11 -5
  183. package/dist/ir/transformers/call-statement.js +20 -87
  184. package/dist/ir/transformers/callback-context-registry.d.ts +1 -1
  185. package/dist/ir/transformers/callback-context-registry.js +8 -16
  186. package/dist/ir/transformers/control-flow.js +0 -13
  187. package/dist/ir/transformers/expressions.js +10 -9
  188. package/dist/ir/transformers/hal-call-resolver.d.ts +2 -2
  189. package/dist/ir/transformers/hal-call-resolver.js +24 -10
  190. package/dist/ir/transformers/hal-emit-helpers.d.ts +2 -2
  191. package/dist/ir/transformers/hal-emit-helpers.js +2 -2
  192. package/dist/ir/transformers/namespace-methods.js +1 -1
  193. package/dist/ir/transformers/ui-callback-lowering.d.ts +0 -2
  194. package/dist/ir/transformers/ui-callback-lowering.js +0 -24
  195. package/dist/ir/transformers/variables.js +338 -42
  196. package/dist/ir/try-catch-validation.js +4 -3
  197. package/dist/ir/type-resolution.js +15 -4
  198. package/dist/ir/validation-orchestrator.js +0 -9
  199. package/dist/libdef/cpp-to-decl.d.ts +0 -9
  200. package/dist/libdef/cpp-to-decl.js +0 -72
  201. package/dist/libdef/registry.d.ts +0 -1
  202. package/dist/libdef/registry.js +1 -24
  203. package/dist/library/catalog.d.ts +35 -0
  204. package/dist/library/catalog.js +67 -0
  205. package/dist/library/cli.d.ts +2 -0
  206. package/dist/library/cli.js +168 -0
  207. package/dist/library/init.d.ts +25 -0
  208. package/dist/library/init.js +397 -0
  209. package/dist/library/install.d.ts +9 -0
  210. package/dist/library/install.js +80 -0
  211. package/dist/library/registry-search.d.ts +34 -0
  212. package/dist/library/registry-search.js +50 -0
  213. package/dist/library/validate.d.ts +17 -0
  214. package/dist/library/validate.js +175 -0
  215. package/dist/library-packages.d.ts +95 -0
  216. package/dist/library-packages.js +275 -0
  217. package/dist/mapping/peripheral-names.js +9 -4
  218. package/dist/mapping/source-map.d.ts +3 -4
  219. package/dist/mapping/source-map.js +12 -18
  220. package/dist/orchestrator/graph-builder.d.ts +3 -3
  221. package/dist/orchestrator/graph-builder.js +29 -12
  222. package/dist/orchestrator/type-checker.d.ts +3 -3
  223. package/dist/orchestrator/type-checker.js +3 -3
  224. package/dist/platform/async-runtime.js +1 -1
  225. package/dist/platform/coop-scheduler-runtime.js +2 -2
  226. package/dist/platform/generic-debug-codegen.d.ts +36 -0
  227. package/dist/platform/generic-debug-codegen.js +185 -0
  228. package/dist/platform/generic-strategy.d.ts +3 -4
  229. package/dist/platform/generic-strategy.js +5 -80
  230. package/dist/platform/index.js +1 -1
  231. package/dist/platform/registry.d.ts +2 -2
  232. package/dist/platform/registry.js +2 -2
  233. package/dist/preview/client.js +17 -3
  234. package/dist/safety/asil-decorators.d.ts +32 -0
  235. package/dist/safety/asil-decorators.js +32 -0
  236. package/dist/safety/authoring.d.ts +85 -0
  237. package/dist/safety/authoring.js +61 -0
  238. package/dist/safety/engine.d.ts +3 -0
  239. package/dist/safety/engine.js +83 -0
  240. package/dist/safety/hal/ops.d.ts +48 -0
  241. package/dist/safety/hal/ops.js +46 -0
  242. package/dist/safety/iso26262/analyze.d.ts +13 -0
  243. package/dist/safety/iso26262/analyze.js +29 -0
  244. package/dist/safety/iso26262/asil.d.ts +10 -0
  245. package/dist/safety/iso26262/asil.js +22 -0
  246. package/dist/safety/iso26262/collect.d.ts +14 -0
  247. package/dist/safety/iso26262/collect.js +137 -0
  248. package/dist/safety/iso26262/goto-checker.d.ts +10 -0
  249. package/dist/safety/iso26262/goto-checker.js +72 -0
  250. package/dist/safety/iso26262/heap-checker.d.ts +7 -0
  251. package/dist/safety/iso26262/heap-checker.js +57 -0
  252. package/dist/safety/iso26262/init-checker.d.ts +13 -0
  253. package/dist/safety/iso26262/init-checker.js +127 -0
  254. package/dist/safety/iso26262/loop-checker.d.ts +7 -0
  255. package/dist/safety/iso26262/loop-checker.js +86 -0
  256. package/dist/safety/iso26262/recursion-checker.d.ts +9 -0
  257. package/dist/safety/iso26262/recursion-checker.js +134 -0
  258. package/dist/safety/iso26262/sidecar-writer.d.ts +25 -0
  259. package/dist/safety/iso26262/sidecar-writer.js +13 -0
  260. package/dist/safety/passes/pinMode-intercept.d.ts +3 -0
  261. package/dist/safety/passes/pinMode-intercept.js +60 -0
  262. package/dist/safety/runtime/mode-table.d.ts +5 -0
  263. package/dist/safety/runtime/mode-table.js +55 -0
  264. package/dist/safety/runtime/polyfills.d.ts +6 -0
  265. package/dist/safety/runtime/polyfills.js +12 -0
  266. package/dist/safety/runtime/result-struct.d.ts +11 -0
  267. package/dist/safety/runtime/result-struct.js +98 -0
  268. package/dist/safety/runtime/safe-int.d.ts +33 -0
  269. package/dist/safety/runtime/safe-int.js +170 -0
  270. package/dist/safety/runtime/safe-traits.d.ts +4 -0
  271. package/dist/safety/runtime/safe-traits.js +95 -0
  272. package/dist/safety/runtime/safe-variable.d.ts +39 -0
  273. package/dist/safety/runtime/safe-variable.js +226 -0
  274. package/dist/safety/runtime/vote.d.ts +8 -0
  275. package/dist/safety/runtime/vote.js +92 -0
  276. package/dist/safety/runtime/write-verify.d.ts +8 -0
  277. package/dist/safety/runtime/write-verify.js +71 -0
  278. package/dist/safety/safe-int-types.d.ts +45 -0
  279. package/dist/safety/safe-int-types.js +25 -0
  280. package/dist/safety/safe-variable-types.d.ts +29 -0
  281. package/dist/safety/safe-variable-types.js +19 -0
  282. package/dist/safety/safety-bridge.d.ts +5 -6
  283. package/dist/safety/safety-bridge.js +15 -28
  284. package/dist/safety/sidecar-bridge.d.ts +1 -3
  285. package/dist/safety/sidecar-bridge.js +3 -20
  286. package/dist/safety/specifiers.d.ts +6 -0
  287. package/dist/safety/specifiers.js +14 -0
  288. package/dist/safety-hook.d.ts +8 -7
  289. package/dist/safety-hook.js +12 -13
  290. package/dist/testing.d.ts +5 -6
  291. package/dist/testing.js +5 -5
  292. package/dist/transpile/resolution.d.ts +1 -1
  293. package/dist/transpile/resolution.js +18 -9
  294. package/dist/transpile/test-pins.d.ts +18 -0
  295. package/dist/transpile/test-pins.js +142 -0
  296. package/dist/transpile.d.ts +1 -2
  297. package/dist/transpile.js +90 -29
  298. package/dist/types.d.ts +45 -26
  299. package/dist/ui-hook.d.ts +1 -1
  300. package/dist/utils/cli.d.ts +2 -2
  301. package/dist/utils/cli.js +160 -157
  302. package/dist/utils/fs.d.ts +3 -4
  303. package/dist/utils/fs.js +4 -5
  304. package/dist/utils/strings.d.ts +0 -1
  305. package/dist/utils/strings.js +0 -8
  306. package/dist/utils/ui.d.ts +5 -2
  307. package/dist/utils/ui.js +13 -3
  308. package/package.json +158 -149
  309. package/dist/add-preset.d.ts +0 -4
  310. package/dist/add-preset.js +0 -74
  311. package/dist/api/shared/async-symbol-detector.d.ts +0 -11
  312. package/dist/api/shared/async-symbol-detector.js +0 -140
  313. package/dist/api/shared/native-display-op-resolver.d.ts +0 -10
  314. package/dist/api/shared/native-display-op-resolver.js +0 -64
  315. package/dist/create/board-checklist.d.ts +0 -2
  316. package/dist/create/board-checklist.js +0 -52
  317. package/dist/create/board-codegen.d.ts +0 -9
  318. package/dist/create/board-codegen.js +0 -238
  319. package/dist/create/board-generators.d.ts +0 -12
  320. package/dist/create/board-generators.js +0 -651
  321. package/dist/create/board-spec.d.ts +0 -637
  322. package/dist/create/board-spec.js +0 -214
  323. package/dist/create/init-templates.d.ts +0 -28
  324. package/dist/create/init-wizard.d.ts +0 -8
  325. package/dist/create/init-wizard.js +0 -182
  326. package/dist/install/framework-catalog.d.ts +0 -53
  327. package/dist/install/framework-catalog.js +0 -107
  328. package/dist/install/handle-install.d.ts +0 -35
  329. package/dist/install/handle-install.js +0 -177
  330. package/dist/install/index.d.ts +0 -4
  331. package/dist/install/index.js +0 -3
  332. package/dist/ir/pin-state-tracking.d.ts +0 -58
  333. package/dist/ir/pin-state-tracking.js +0 -182
  334. package/dist/ir/pwm-timer-sharing.d.ts +0 -4
  335. package/dist/ir/pwm-timer-sharing.js +0 -94
  336. package/dist/ir/timer0-pwm-timing-conflict.d.ts +0 -4
  337. package/dist/ir/timer0-pwm-timing-conflict.js +0 -72
  338. package/dist/libdef/component-decls.d.ts +0 -2
  339. package/dist/libdef/component-decls.js +0 -6
  340. package/dist/libdef/component-discovery.d.ts +0 -43
  341. package/dist/libdef/component-discovery.js +0 -83
  342. package/dist/theme-tokens.d.ts +0 -22
  343. package/dist/theme-tokens.js +0 -172
@@ -1,9 +1,8 @@
1
1
  import ts from "typescript";
2
- import { getCurrentBoardConstants, halInstances, getContext } from "../build-ir-state.js";
2
+ import { getContext } from "../build-ir-state.js";
3
3
  import { resolveExpressionText } from "./hal-emitter.js";
4
4
  import { renderExprAsText } from "../render-expr.js";
5
5
  import { hasSafetyHook, requireSafetyHook } from "../../safety-hook.js";
6
- import { notePinSetMode, notePinToggle, notePinWrite, notePinAnalogOutput, resolveTrackedRead } from "../pin-state-tracking.js";
7
6
  /**
8
7
  * Split a comma-joined argument list back into individual arguments, respecting
9
8
  * nesting (parens/brackets/braces) and string literals so a comma inside one of
@@ -76,6 +75,15 @@ function resolveI2cBufferArg(args, idx, instance, paramNames, callArgTexts, para
76
75
  return { kind: "buffer", data };
77
76
  }
78
77
  /** Resolve a single argument from a semantic call's AST node list. */
78
+ /** Normalize an inline-override text from an instance field: strip the
79
+ * quotes of a stored string literal and reject unresolved source text
80
+ * (`this->_x`, expressions) — only clean identifiers/tokens pass. */
81
+ function cleanOverrideText(v) {
82
+ if (typeof v !== "string")
83
+ return undefined;
84
+ const t = v.replace(/^["']+|["']+$/g, "").trim();
85
+ return t !== "" && /^[A-Za-z0-9_.:-]+$/.test(t) ? t : undefined;
86
+ }
79
87
  export function resolveSemanticArg(args, idx, instance, paramNames, callArgTexts, paramDefaults) {
80
88
  const arg = args[idx];
81
89
  if (!arg)
@@ -114,12 +122,17 @@ function dropUndefined(value) {
114
122
  return value === "undefined" ? null : value;
115
123
  }
116
124
  /** Quote a resolved string value unless it is already a quoted literal or a
117
- * plain identifier / member-access expression (i.e. a runtime variable). */
125
+ * plain single identifier (i.e. a runtime variable reference). Dotted text
126
+ * is NOT passed through: every consumer of this helper feeds a C++ string
127
+ * parameter (fs paths, preference keys, BLE names, URLs), and a dotted form
128
+ * like `a.txt` is far more likely a field-tracked literal that lost its
129
+ * quotes than a valid member-expression argument — emitting it bare is a
130
+ * compile error ('a' was not declared). */
118
131
  function quoteNonIdentifier(value) {
119
132
  const t = value.trim();
120
133
  if (/^".*"$/.test(t))
121
134
  return t;
122
- if (/^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(t))
135
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))
123
136
  return t;
124
137
  return JSON.stringify(t);
125
138
  }
@@ -327,13 +340,11 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
327
340
  // Try literal resolution first (compile-time 0/1/true/false)
328
341
  const numValue = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
329
342
  if (numValue !== null) {
330
- notePinWrite(pin, numValue);
331
343
  return { operation: "gpio.write", port, pin, value: (numValue ? 1 : 0) };
332
344
  }
333
345
  // Fall back to runtime expression (e.g. a variable, negated expression)
334
346
  const exprValue = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
335
347
  if (exprValue !== null) {
336
- notePinWrite(pin, null);
337
348
  return { operation: "gpio.write", port, pin, value: exprValue };
338
349
  }
339
350
  return null;
@@ -342,225 +353,38 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
342
353
  const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
343
354
  if (pin === null)
344
355
  return null;
345
- const tracked = resolveTrackedRead(pin);
346
- if (tracked !== null) {
347
- return { operation: "gpio.read", port, pin, trackedValue: tracked };
348
- }
349
356
  return { operation: "gpio.read", port, pin };
350
357
  }
351
- case "gpioToggle": {
352
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
353
- if (pin === null)
354
- return null;
355
- notePinToggle(pin);
356
- return { operation: "gpio.toggle", port, pin };
357
- }
358
- case "gpioSetMode": {
359
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
360
- const mode = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
361
- if (pin === null || mode === null)
362
- return null;
363
- notePinSetMode(pin, mode);
364
- return { operation: "gpio.set_mode", port, pin, mode };
365
- }
366
- // ── PWM ──
367
- case "pwmWrite": {
368
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
369
- const duty = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
370
- if (pin === null || duty === null)
371
- return null;
372
- notePinAnalogOutput(pin);
373
- return { operation: "pwm.write", port, pin, duty };
374
- }
375
- // ── RMT ──
376
- // rmtTxInit/rmtRxInit are POSITIONAL semantic primitives (the ergonomic
377
- // opts-object form lives in hal/rmt.ts's RmtChannel class, which
378
- // destructures opts and forwards positionally). The resolver dispatches on
379
- // the literal callee name, so rmt.ts must call these by their real names
380
- // (no `as _rmtTxInit` aliasing — that breaks the switch).
381
- // rmtTxInit(pin, resolutionHz, bit0Hi, bit0Lo, bit1Hi, bit1Lo, msbFirst, queueDepth)
382
- case "rmtTxInit": {
383
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
384
- const resolutionHz = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
385
- const bit0Hi = resolveNumericOrExpression(args, 2, instance, paramNames, callArgTexts, paramDefaults);
386
- const bit0Lo = resolveNumericOrExpression(args, 3, instance, paramNames, callArgTexts, paramDefaults);
387
- const bit1Hi = resolveNumericOrExpression(args, 4, instance, paramNames, callArgTexts, paramDefaults);
388
- const bit1Lo = resolveNumericOrExpression(args, 5, instance, paramNames, callArgTexts, paramDefaults);
389
- const msbFirst = resolveSemanticArg(args, 6, instance, paramNames, callArgTexts, paramDefaults);
390
- const queueDepth = resolveNumericOrExpression(args, 7, instance, paramNames, callArgTexts, paramDefaults);
391
- if (pin === null || resolutionHz === null)
392
- return null;
393
- const op = { operation: "rmt.tx_init", port, pin, resolutionHz, bit0Hi, bit0Lo, bit1Hi, bit1Lo };
394
- if (queueDepth !== null)
395
- op.queueDepth = queueDepth;
396
- if (msbFirst !== null)
397
- op.msbFirst = msbFirst;
398
- return op;
399
- }
400
- case "rmtTxWriteBytes": {
401
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
402
- // bytes is an array literal — resolveSemanticArg renders it positionally as "1, 2, 3".
403
- const bytes = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
404
- if (pin === null || bytes === null)
405
- return null;
406
- return { operation: "rmt.tx_write_bytes", port, pin, bytes };
407
- }
408
- case "rmtTxWriteSymbols": {
409
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
410
- const symbols = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
411
- if (pin === null || symbols === null)
412
- return null;
413
- return { operation: "rmt.tx_write_symbols", port, pin, symbols };
414
- }
415
- case "rmtTxWaitDone": {
416
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
417
- const timeoutMs = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
418
- if (pin === null)
419
- return null;
420
- const op = { operation: "rmt.tx_wait_done", port, pin };
421
- if (timeoutMs !== null)
422
- op.timeoutMs = timeoutMs;
423
- return op;
424
- }
425
- case "rmtTxDeinit": {
426
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
427
- if (pin === null)
428
- return null;
429
- return { operation: "rmt.tx_deinit", port, pin };
430
- }
431
- case "rmtRxInit": {
432
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
433
- const resolutionHz = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
434
- if (pin === null || resolutionHz === null)
435
- return null;
436
- return { operation: "rmt.rx_init", port, pin, resolutionHz };
437
- }
438
- case "rmtRxOnReceived": {
439
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
440
- const handler = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
441
- if (pin === null || handler === null)
442
- return null;
443
- return { operation: "rmt.rx_on_received", port, pin, handler };
444
- }
445
- case "rmtRxStart": {
446
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
447
- if (pin === null)
448
- return null;
449
- return { operation: "rmt.rx_start", port, pin };
450
- }
451
- case "rmtRxStop": {
452
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
453
- if (pin === null)
454
- return null;
455
- return { operation: "rmt.rx_stop", port, pin };
456
- }
457
- case "rmtRxRead": {
458
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
459
- const maxCount = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
460
- if (pin === null || maxCount === null)
461
- return null;
462
- return { operation: "rmt.rx_read", port, pin, maxCount };
463
- }
464
- case "rmtRxDeinit": {
465
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
466
- if (pin === null)
467
- return null;
468
- return { operation: "rmt.rx_deinit", port, pin };
469
- }
470
- // ── ADC ──
471
- case "adcRead": {
472
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
473
- if (pin === null)
474
- return null;
475
- return { operation: "adc.read", port, pin };
476
- }
477
- case "adcSetReference": {
478
- const ref = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
479
- if (ref === null)
480
- return null;
481
- const numRef = Number(ref);
482
- return { operation: "adc.set_reference", reference: isNaN(numRef) ? ref : numRef };
483
- }
484
- case "adcReadVoltage": {
485
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
486
- if (pin === null)
487
- return null;
488
- const op = { operation: "adc.read_voltage", port, pin };
489
- const bc = getCurrentBoardConstants();
490
- if (bc) {
491
- // Check if ADC has a non-default reference set
492
- const adcInst = halInstances.get("ADC");
493
- const ref = adcInst?.fieldValues.get("_reference");
494
- const refKey = ref && ref !== "DEFAULT" ? ref : null;
495
- const vRefPath = refKey
496
- ? `peripherals.adc.0.referenceVoltages.${refKey}`
497
- : `peripherals.adc.0.referenceVoltage`;
498
- const vRef = bc.get(vRefPath);
499
- const maxValue = bc.get("peripherals.adc.0.maxValue");
500
- if (vRef !== undefined)
501
- op.vRef = Number(vRef);
502
- if (maxValue !== undefined)
503
- op.maxValue = Number(maxValue);
358
+ case "gpioToggle":
359
+ {
360
+ const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
361
+ if (pin === null)
362
+ return null;
363
+ return { operation: "gpio.toggle", port, pin };
504
364
  }
505
- return op;
506
- }
507
- // ── DAC ──
508
- case "dacWrite": {
509
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
510
- const value = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
511
- if (pin === null || value === null)
512
- return null;
513
- return { operation: "dac.write", port, pin, value };
514
- }
515
- // ── Watchdog timer ──
516
- case "wdtEnable": {
517
- const timeout = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
518
- if (timeout === null)
519
- return null;
520
- return { operation: "wdt.enable", timeout };
521
- }
522
- case "wdtReset":
523
- return { operation: "wdt.reset" };
365
+ ;
524
366
  case "wdtDisable":
525
367
  return { operation: "wdt.disable" };
526
- // ── Power ──
527
- case "powerDeepSleep": {
528
- const ms = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
529
- if (ms === null)
530
- return null;
531
- return { operation: "power.deep_sleep", ms };
532
- }
533
- case "powerLightSleep":
534
- return { operation: "power.light_sleep" };
535
- case "powerSetCpuFrequency": {
536
- const mhz = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
537
- if (mhz === null)
538
- return null;
539
- return { operation: "power.set_cpu_frequency", mhz };
540
- }
541
- case "powerDeepSleepPin": {
542
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
543
- const level = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
544
- if (pin === null || level === null)
545
- return null;
546
- return { operation: "power.deep_sleep_pin", pin, level };
547
- }
548
- // ── WiFi ──
549
- // Optional string args (password, dns) resolve to the text "undefined"
550
- // when omitted at the call site (no default in the HAL signature). Treat
551
- // that as absent so the backend emits its own default ("").
552
- case "wifiConnect": {
553
- const ssid = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
554
- const password = dropUndefined(resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults));
555
- const timeoutMs = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults) ?? 15000;
368
+ case "wifiJoin": {
369
+ const R = resolveSemanticArg;
370
+ const N = resolveNumericArg;
371
+ const ssid = R(args, 0, instance, paramNames, callArgTexts, paramDefaults);
372
+ const psk = dropUndefined(R(args, 1, instance, paramNames, callArgTexts, paramDefaults));
373
+ const security = N(args, 2, instance, paramNames, callArgTexts, paramDefaults) ?? (psk !== null ? 1 : 0);
374
+ const channel = N(args, 3, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
375
+ const band = N(args, 4, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
376
+ const timeoutMs = N(args, 5, instance, paramNames, callArgTexts, paramDefaults) ?? 15000;
377
+ const ps = N(args, 6, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
378
+ const ipAddr = dropUndefined(R(args, 7, instance, paramNames, callArgTexts, paramDefaults));
379
+ const gateway = dropUndefined(R(args, 8, instance, paramNames, callArgTexts, paramDefaults));
380
+ const netmask = dropUndefined(R(args, 9, instance, paramNames, callArgTexts, paramDefaults));
556
381
  if (ssid === null)
557
382
  return null;
558
383
  return {
559
- operation: "wifi.connect",
560
- ssid,
561
- ...(password !== null ? { password } : {}),
562
- timeoutMs,
563
- blocking: true,
384
+ operation: "wifi.join", ssid,
385
+ ...(psk !== null ? { psk } : {}),
386
+ security, channel, band, timeoutMs, ps,
387
+ ...(ipAddr !== null && gateway !== null && netmask !== null ? { ipAddr, gateway, netmask } : {}),
564
388
  };
565
389
  }
566
390
  case "wifiConnectStart": {
@@ -572,8 +396,7 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
572
396
  }
573
397
  case "wifiDisconnect":
574
398
  return { operation: "wifi.disconnect" };
575
- case "wifiStatus":
576
- return { operation: "wifi.status" };
399
+ ;
577
400
  case "wifiIsConnected":
578
401
  return { operation: "wifi.is_connected" };
579
402
  case "wifiLocalIp":
@@ -582,39 +405,6 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
582
405
  return { operation: "wifi.rssi" };
583
406
  case "wifiMac":
584
407
  return { operation: "wifi.mac" };
585
- case "wifiSetHostname": {
586
- const name = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
587
- if (name === null)
588
- return null;
589
- return { operation: "wifi.set_hostname", name };
590
- }
591
- case "wifiSetStaticIp": {
592
- const ip = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
593
- const gateway = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
594
- const subnet = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
595
- const dns = dropUndefined(resolveSemanticArg(args, 3, instance, paramNames, callArgTexts, paramDefaults));
596
- if (ip === null || gateway === null || subnet === null)
597
- return null;
598
- return { operation: "wifi.set_static_ip", ip, gateway, subnet, ...(dns !== null ? { dns } : {}) };
599
- }
600
- case "wifiSetAutoReconnect": {
601
- const enabled = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
602
- if (enabled === null)
603
- return null;
604
- return { operation: "wifi.set_auto_reconnect", enabled: enabled === "true" };
605
- }
606
- case "wifiSetPowerSave": {
607
- const mode = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
608
- if (mode === null)
609
- return null;
610
- return { operation: "wifi.set_power_save", mode };
611
- }
612
- case "wifiSetTxPower": {
613
- const dbm = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
614
- if (dbm === null)
615
- return null;
616
- return { operation: "wifi.set_tx_power", dbm };
617
- }
618
408
  case "wifiOnEvent": {
619
409
  const event = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
620
410
  const handler = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
@@ -641,32 +431,10 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
641
431
  }
642
432
  case "wifiApStop":
643
433
  return { operation: "wifi.ap_stop" };
644
- case "wifiApClientCount":
645
- return { operation: "wifi.ap_client_count" };
646
- case "wifiApIp":
647
- return { operation: "wifi.ap_ip" };
648
- case "wifiApSetChannel": {
649
- const channel = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
650
- if (channel === null)
651
- return null;
652
- return { operation: "wifi.ap_set_channel", channel };
653
- }
654
- case "wifiApSetHidden": {
655
- const hidden = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
656
- if (hidden === null)
657
- return null;
658
- return { operation: "wifi.ap_set_hidden", hidden };
659
- }
660
- case "wifiApSetMaxClients": {
661
- const maxClients = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
662
- if (maxClients === null)
663
- return null;
664
- return { operation: "wifi.ap_set_max_clients", maxClients };
665
- }
434
+ ;
435
+ ;
666
436
  case "wifiScan":
667
437
  return { operation: "wifi.scan" };
668
- case "wifiScanStart":
669
- return { operation: "wifi.scan_start" };
670
438
  case "wifiScanCount":
671
439
  return { operation: "wifi.scan_count" };
672
440
  case "wifiScanSsid": {
@@ -687,31 +455,15 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
687
455
  return null;
688
456
  return { operation: "wifi.scan_encryption", index };
689
457
  }
690
- case "wifiScanChannel": {
691
- const index = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
692
- if (index === null)
693
- return null;
694
- return { operation: "wifi.scan_channel", index };
695
- }
696
- case "wifiSaveCredentials": {
697
- const ssid = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
698
- const password = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
699
- if (ssid === null || password === null)
700
- return null;
701
- return { operation: "wifi.save_credentials", ssid, password };
702
- }
703
- case "wifiConnectSaved": {
704
- const timeoutMs = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults) ?? 15000;
705
- return { operation: "wifi.connect_saved", timeoutMs };
706
- }
707
- case "wifiClearCredentials":
708
- return { operation: "wifi.clear_credentials" };
709
- case "wifiWaitConnected": {
710
- const timeoutMs = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults) ?? 15000;
711
- return { operation: "wifi.wait_connected", timeoutMs };
712
- }
713
- case "wifiWaitDisconnected":
714
- return { operation: "wifi.wait_disconnected" };
458
+ case "wifiScanChannel":
459
+ {
460
+ const index = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
461
+ if (index === null)
462
+ return null;
463
+ return { operation: "wifi.scan_channel", index };
464
+ }
465
+ ;
466
+ ;
715
467
  // ── HTTP ──
716
468
  case "httpBegin": {
717
469
  const method = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
@@ -724,8 +476,6 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
724
476
  // lowering emits valid C++.
725
477
  return { operation: "http.begin", method, url: quoteNonIdentifier(url) };
726
478
  }
727
- case "httpReset":
728
- return { operation: "http.reset" };
729
479
  case "httpSetHeader": {
730
480
  const name = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
731
481
  const value = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
@@ -752,8 +502,12 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
752
502
  return null;
753
503
  return { operation: "http.set_body", data, json: json === "true" };
754
504
  }
755
- case "httpSetInsecure":
756
- return { operation: "http.set_insecure" };
505
+ case "httpSetInsecure": {
506
+ const insecure = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
507
+ if (insecure === null)
508
+ return null;
509
+ return { operation: "http.set_insecure", insecure: insecure === "true" };
510
+ }
757
511
  case "httpSetCaCert": {
758
512
  const pem = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
759
513
  if (pem === null)
@@ -762,8 +516,6 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
762
516
  }
763
517
  case "httpSend":
764
518
  return { operation: "http.send", blocking: true };
765
- case "httpSendStart":
766
- return { operation: "http.send_start" };
767
519
  case "httpStatus":
768
520
  return { operation: "http.status" };
769
521
  case "httpOk":
@@ -810,8 +562,10 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
810
562
  // this index.
811
563
  const uuid = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
812
564
  const type = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
813
- const perms = resolveNumericOrExpression(args, 3, instance, paramNames, callArgTexts, paramDefaults);
814
- const svcIndex = resolveNumericOrExpression(args, 4, instance, paramNames, callArgTexts, paramDefaults);
565
+ // Perms arrive as token text ("BlePerm.Read | BlePerm.Notify")
566
+ // resolveBlePermExpr maps the member names to the bitmask.
567
+ const perms = resolveSemanticArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
568
+ const svcIndex = resolveNumericArg(args, 4, instance, paramNames, callArgTexts, paramDefaults);
815
569
  if (uuid === null || type === null)
816
570
  return null;
817
571
  // Resolve BleValueType.X → the enum's string value (e.g. Int16 → 'int16').
@@ -833,14 +587,14 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
833
587
  };
834
588
  }
835
589
  case "bleOnRead": {
836
- const index = resolveNumericOrExpression(args, 0, instance, paramNames, callArgTexts, paramDefaults);
590
+ const index = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
837
591
  const handler = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
838
592
  if (handler === null)
839
593
  return null;
840
594
  return { operation: "ble.on_read", index: index ?? 0, handler };
841
595
  }
842
596
  case "bleOnWrite": {
843
- const index = resolveNumericOrExpression(args, 0, instance, paramNames, callArgTexts, paramDefaults);
597
+ const index = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
844
598
  const handler = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
845
599
  if (handler === null)
846
600
  return null;
@@ -859,8 +613,8 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
859
613
  return { operation: "ble.on_disconnect", handler };
860
614
  }
861
615
  case "bleNotify": {
862
- const index = resolveNumericOrExpression(args, 0, instance, paramNames, callArgTexts, paramDefaults);
863
- const value = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
616
+ const index = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
617
+ const value = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
864
618
  if (value === null)
865
619
  return null;
866
620
  return { operation: "ble.notify", index: index ?? 0, value };
@@ -869,174 +623,134 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
869
623
  return { operation: "ble.is_connected" };
870
624
  case "bleClientCount":
871
625
  return { operation: "ble.client_count" };
872
- case "bleStatus":
873
- return { operation: "ble.status" };
874
- case "bleSetName": {
875
- const name = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
876
- if (name === null)
877
- return null;
878
- return { operation: "ble.set_name", name: quoteNonIdentifier(name) };
879
- }
880
- case "bleUntilConnected": {
881
- const timeoutMs = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
882
- return { operation: "ble.until_connected", timeoutMs, blocking: true };
883
- }
884
- case "bleUntilConnectedStart":
885
- return { operation: "ble.until_connected_start" };
886
- case "bleSetTxPower": {
887
- const dbm = resolveNumericOrExpression(args, 0, instance, paramNames, callArgTexts, paramDefaults);
888
- if (dbm === null)
889
- return null;
890
- return { operation: "ble.set_tx_power", dbm };
891
- }
892
- // ── Preferences (NVS key/value store) ──
893
- case "preferencesBegin": {
626
+ case "preferencesClear": {
894
627
  const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
895
- const ro = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
896
628
  if (ns === null)
897
629
  return null;
898
- return { operation: "preferences.begin", namespace: quoteNonIdentifier(ns), readOnly: ro === "true" };
630
+ return { operation: "preferences.clear", ns: quoteNonIdentifier(ns) };
899
631
  }
900
- case "preferencesEnd":
901
- return { operation: "preferences.end" };
902
- case "preferencesClear":
903
- return { operation: "preferences.clear" };
904
632
  case "preferencesRemove": {
905
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
633
+ const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
634
+ if (ns === null)
635
+ return null;
636
+ const key = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
906
637
  if (key === null)
907
638
  return null;
908
- return { operation: "preferences.remove", key: quoteNonIdentifier(key) };
639
+ return { operation: "preferences.remove", ns: quoteNonIdentifier(ns), key: quoteNonIdentifier(key) };
909
640
  }
910
641
  case "preferencesPutInt": {
911
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
912
- const value = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
642
+ const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
643
+ if (ns === null)
644
+ return null;
645
+ const key = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
646
+ const value = resolveNumericOrExpression(args, 2, instance, paramNames, callArgTexts, paramDefaults);
913
647
  if (key === null || value === null)
914
648
  return null;
915
- return { operation: "preferences.put_int", key: quoteNonIdentifier(key), value };
649
+ return { operation: "preferences.put_int", ns: quoteNonIdentifier(ns), key: quoteNonIdentifier(key), value };
916
650
  }
917
651
  case "preferencesGetInt": {
918
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
919
- const def = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
920
- if (key === null)
921
- return null;
922
- return { operation: "preferences.get_int", key: quoteNonIdentifier(key), defaultValue: def };
923
- }
924
- case "preferencesPutUInt": {
925
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
926
- const value = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
927
- if (key === null || value === null)
652
+ const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
653
+ if (ns === null)
928
654
  return null;
929
- return { operation: "preferences.put_uint", key: quoteNonIdentifier(key), value };
930
- }
931
- case "preferencesGetUInt": {
932
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
933
- const def = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
655
+ const key = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
656
+ const def = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
934
657
  if (key === null)
935
658
  return null;
936
- return { operation: "preferences.get_uint", key: quoteNonIdentifier(key), defaultValue: def };
659
+ return { operation: "preferences.get_int", ns: quoteNonIdentifier(ns), key: quoteNonIdentifier(key), defaultValue: def };
937
660
  }
938
661
  case "preferencesPutBool": {
939
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
940
- const value = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
662
+ const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
663
+ if (ns === null)
664
+ return null;
665
+ const key = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
666
+ const value = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
941
667
  if (key === null || value === null)
942
668
  return null;
943
- return { operation: "preferences.put_bool", key: quoteNonIdentifier(key), value: value === "true" };
669
+ return { operation: "preferences.put_bool", ns: quoteNonIdentifier(ns), key: quoteNonIdentifier(key), value: value === "true" };
944
670
  }
945
671
  case "preferencesGetBool": {
946
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
947
- const def = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
672
+ const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
673
+ if (ns === null)
674
+ return null;
675
+ const key = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
676
+ const def = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
948
677
  if (key === null)
949
678
  return null;
950
- return { operation: "preferences.get_bool", key: quoteNonIdentifier(key), defaultValue: def === "true" };
679
+ return { operation: "preferences.get_bool", ns: quoteNonIdentifier(ns), key: quoteNonIdentifier(key), defaultValue: def === "true" };
951
680
  }
952
681
  case "preferencesPutFloat": {
953
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
954
- const value = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
682
+ const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
683
+ if (ns === null)
684
+ return null;
685
+ const key = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
686
+ const value = resolveNumericOrExpression(args, 2, instance, paramNames, callArgTexts, paramDefaults);
955
687
  if (key === null || value === null)
956
688
  return null;
957
- return { operation: "preferences.put_float", key: quoteNonIdentifier(key), value };
689
+ return { operation: "preferences.put_float", ns: quoteNonIdentifier(ns), key: quoteNonIdentifier(key), value };
958
690
  }
959
691
  case "preferencesGetFloat": {
960
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
961
- const def = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
692
+ const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
693
+ if (ns === null)
694
+ return null;
695
+ const key = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
696
+ const def = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
962
697
  if (key === null)
963
698
  return null;
964
- return { operation: "preferences.get_float", key: quoteNonIdentifier(key), defaultValue: def };
699
+ return { operation: "preferences.get_float", ns: quoteNonIdentifier(ns), key: quoteNonIdentifier(key), defaultValue: def };
965
700
  }
966
701
  case "preferencesPutString": {
967
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
968
- const value = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
702
+ const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
703
+ if (ns === null)
704
+ return null;
705
+ const key = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
706
+ const value = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
969
707
  if (key === null || value === null)
970
708
  return null;
971
- return { operation: "preferences.put_string", key: quoteNonIdentifier(key), value: quoteNonIdentifier(value) };
709
+ return { operation: "preferences.put_string", ns: quoteNonIdentifier(ns), key: quoteNonIdentifier(key), value: quoteNonIdentifier(value) };
972
710
  }
973
711
  case "preferencesGetString": {
974
- const key = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
975
- const def = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults) ?? '""';
712
+ const ns = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
713
+ if (ns === null)
714
+ return null;
715
+ const key = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
716
+ const def = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults) ?? '""';
976
717
  if (key === null)
977
718
  return null;
978
- return { operation: "preferences.get_string", key: quoteNonIdentifier(key), defaultValue: quoteNonIdentifier(def) };
719
+ return { operation: "preferences.get_string", ns: quoteNonIdentifier(ns), key: quoteNonIdentifier(key), defaultValue: quoteNonIdentifier(def) };
979
720
  }
980
- // ── FS (filesystem) ──
981
- case "fsBegin":
982
- return { operation: "fs.begin" };
721
+ // ── FS (littlefs on the storage partition — lazy mount, no session) ──
983
722
  case "fsReadText": {
984
723
  const path = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
985
724
  if (path === null)
986
725
  return null;
987
- return { operation: "fs.read_text", path };
726
+ return { operation: "fs.read_text", path: quoteNonIdentifier(path) };
988
727
  }
989
728
  case "fsWriteText": {
990
729
  const path = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
991
730
  const content = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
992
731
  if (path === null || content === null)
993
732
  return null;
994
- return { operation: "fs.write_text", path, content };
733
+ return { operation: "fs.write_text", path: quoteNonIdentifier(path), content: quoteNonIdentifier(content) };
995
734
  }
996
735
  case "fsExists": {
997
736
  const path = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
998
737
  if (path === null)
999
738
  return null;
1000
- return { operation: "fs.exists", path };
739
+ return { operation: "fs.exists", path: quoteNonIdentifier(path) };
1001
740
  }
1002
741
  case "fsRemove": {
1003
742
  const path = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1004
743
  if (path === null)
1005
744
  return null;
1006
- return { operation: "fs.remove", path };
745
+ return { operation: "fs.remove", path: quoteNonIdentifier(path) };
1007
746
  }
1008
- // ── mDNS ──
1009
- case "mdnsStart": {
1010
- const hostname = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1011
- if (hostname === null)
1012
- return null;
1013
- return { operation: "mdns.start", hostname };
1014
- }
1015
- case "mdnsSetHostname": {
1016
- const name = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1017
- if (name === null)
1018
- return null;
1019
- return { operation: "mdns.set_hostname", name };
1020
- }
1021
- case "mdnsAddService": {
1022
- const instanceName = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1023
- const proto = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1024
- const port = resolveNumericOrExpression(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1025
- if (instanceName === null || proto === null || port === null)
1026
- return null;
1027
- return { operation: "mdns.add_service", instance: instanceName, proto, port };
1028
- }
1029
- case "mdnsAnnounce":
1030
- return { operation: "mdns.announce" };
1031
- case "mdnsStop":
1032
- return { operation: "mdns.stop" };
1033
747
  // ── MQTT ──
1034
748
  case "mqttConnect": {
1035
- const brokerUri = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
749
+ const uri = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1036
750
  const clientId = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1037
- if (brokerUri === null || clientId === null)
751
+ if (uri === null || clientId === null)
1038
752
  return null;
1039
- return { operation: "mqtt.connect", brokerUri, clientId };
753
+ return { operation: "mqtt.connect", brokerUri: quoteNonIdentifier(uri), clientId: quoteNonIdentifier(clientId) };
1040
754
  }
1041
755
  case "mqttOnMessage": {
1042
756
  const handler = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
@@ -1048,400 +762,395 @@ export function tryResolveSemanticCall(fnName, args, instance, paramNames, callA
1048
762
  const topic = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1049
763
  if (topic === null)
1050
764
  return null;
1051
- return { operation: "mqtt.subscribe", topic };
765
+ return { operation: "mqtt.subscribe", topic: quoteNonIdentifier(topic) };
1052
766
  }
1053
767
  case "mqttPublish": {
1054
768
  const topic = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1055
769
  const data = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1056
770
  if (topic === null || data === null)
1057
771
  return null;
1058
- return { operation: "mqtt.publish", topic, data };
772
+ return { operation: "mqtt.publish", topic: quoteNonIdentifier(topic), data: quoteNonIdentifier(data) };
1059
773
  }
1060
774
  case "mqttConnected":
1061
775
  return { operation: "mqtt.connected" };
1062
776
  case "mqttDisconnect":
1063
777
  return { operation: "mqtt.disconnect" };
1064
- // ── OTA ──
1065
- case "otaFromUrl": {
1066
- const url = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1067
- if (url === null)
1068
- return null;
1069
- return { operation: "ota.from_url", url };
1070
- }
1071
- case "otaBegin":
1072
- return { operation: "ota.begin" };
1073
- case "otaWrite": {
1074
- const chunk = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1075
- if (chunk === null)
1076
- return null;
1077
- return { operation: "ota.write", chunk };
1078
- }
1079
- case "otaApply":
1080
- return { operation: "ota.apply" };
1081
- // ── Temperature (die temp) ──
1082
- case "tempRead":
1083
- return { operation: "temp.read" };
1084
- // ── Hardware timer (GPTimer) ──
1085
- case "hwtimerSetFrequency": {
1086
- const inst = resolveNumericOrExpression(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1087
- const hz = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1088
- if (inst === null || hz === null)
1089
- return null;
1090
- return { operation: "hwtimer.set_frequency", instance: inst, hz };
1091
- }
1092
- case "hwtimerOnOverflow": {
1093
- const inst = resolveNumericOrExpression(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1094
- const handler = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1095
- if (inst === null || handler === null)
778
+ case "interruptDetach":
779
+ {
780
+ const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
781
+ if (pin === null)
782
+ return null;
783
+ return { operation: "interrupt.detach", port, pin };
784
+ }
785
+ ;
786
+ ;
787
+ // ── USB CDC-ACM serial ──
788
+ case "usbBegin": {
789
+ const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
790
+ if (port === null)
1096
791
  return null;
1097
- return { operation: "hwtimer.on_overflow", instance: inst, handler };
792
+ return { operation: "usb.begin", port };
1098
793
  }
1099
- case "hwtimerStart": {
1100
- const inst = resolveNumericOrExpression(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1101
- if (inst === null)
794
+ case "usbWaitReady": {
795
+ const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
796
+ const timeoutMs = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults) ?? 0;
797
+ if (port === null)
1102
798
  return null;
1103
- return { operation: "hwtimer.start", instance: inst };
799
+ return { operation: "usb.wait_ready", port, timeoutMs };
1104
800
  }
1105
- case "hwtimerStop": {
1106
- const inst = resolveNumericOrExpression(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1107
- if (inst === null)
801
+ case "usbEnd": {
802
+ const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
803
+ if (port === null)
1108
804
  return null;
1109
- return { operation: "hwtimer.stop", instance: inst };
805
+ return { operation: "usb.end", port };
1110
806
  }
1111
- // ── Capacitive touch pins ──
1112
- case "capacitiveRead": {
1113
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1114
- if (pin === null)
807
+ case "usbPrint": {
808
+ const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
809
+ const value = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
810
+ if (port === null || value === null)
1115
811
  return null;
1116
- return { operation: "capacitive.read", port, pin };
812
+ return { operation: "usb.print", port, value };
1117
813
  }
1118
- // ── Interrupts ──
1119
- case "interruptAttach": {
1120
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1121
- const handler = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1122
- const mode = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1123
- if (pin === null || handler === null || mode === null)
814
+ case "usbPrintln": {
815
+ const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
816
+ const value = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
817
+ if (port === null || value === null)
1124
818
  return null;
1125
- return { operation: "interrupt.attach", port, pin, handler, mode };
819
+ return { operation: "usb.println", port, value };
1126
820
  }
1127
- case "interruptDetach": {
1128
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1129
- if (pin === null)
821
+ case "usbRead": {
822
+ const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
823
+ if (port === null)
1130
824
  return null;
1131
- return { operation: "interrupt.detach", port, pin };
825
+ return { operation: "usb.read", port };
1132
826
  }
1133
- // ── Tone ──
1134
- case "tonePlay": {
1135
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1136
- const frequency = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1137
- const duration = resolveNumericOrExpression(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1138
- if (pin === null || frequency === null)
827
+ case "usbAvailable": {
828
+ const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
829
+ if (port === null)
1139
830
  return null;
1140
- notePinAnalogOutput(pin);
1141
- return { operation: "tone.play", port, pin, frequency, ...(duration !== null ? { duration } : {}) };
831
+ return { operation: "usb.available", port };
1142
832
  }
1143
- case "toneStop": {
1144
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1145
- if (pin === null)
833
+ case "usbConnected": {
834
+ const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
835
+ if (port === null)
1146
836
  return null;
1147
- return { operation: "tone.stop", port, pin };
837
+ return { operation: "usb.connected", port };
1148
838
  }
1149
- // ── Timing ──
1150
- case "delayMs": {
1151
- const ms = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1152
- if (ms === null)
839
+ // ── Board ──
840
+ case "boardResolve": {
841
+ const p = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
842
+ if (p === null)
1153
843
  return null;
1154
- return { operation: "timing.delay", ms };
844
+ return { operation: "board.resolve", path: p };
1155
845
  }
1156
- case "delayMicro": {
1157
- const us = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1158
- if (us === null)
846
+ // ── Raw C++ passthrough ──
847
+ case "rawCpp": {
848
+ const code = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
849
+ if (code === null)
1159
850
  return null;
1160
- return { operation: "timing.delay_microseconds", us };
851
+ return { operation: "raw", code };
1161
852
  }
1162
- case "getMillis":
1163
- return { operation: "timing.millis" };
1164
- case "getMicros":
1165
- return { operation: "timing.micros" };
1166
- case "getFreeHeap":
1167
- return { operation: "timing.free_heap" };
1168
- // ── I2C ──
1169
- case "i2cBegin": {
1170
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1171
- const address = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1172
- if (bus === null)
853
+ case "gpioConfigure": {
854
+ const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
855
+ const flags = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
856
+ if (pin === null || flags === null)
1173
857
  return null;
1174
- return { operation: "i2c.begin", bus, ...(address !== null ? { address } : {}) };
858
+ return { operation: "gpio.configure", pin, flags };
1175
859
  }
1176
- case "i2cEnd": {
1177
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1178
- if (bus === null)
860
+ case "gpioReadCfg": {
861
+ const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
862
+ const flags = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
863
+ if (pin === null || flags === null)
1179
864
  return null;
1180
- return { operation: "i2c.end", bus };
865
+ return { operation: "gpio.read_cfg", pin, flags };
1181
866
  }
1182
- case "i2cSetClock": {
1183
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1184
- const hz = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1185
- if (bus === null || hz === null)
867
+ case "gpioShiftOut": {
868
+ const dataPin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
869
+ const clockPin = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
870
+ const value = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
871
+ const msbFirstRaw = resolveSemanticArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
872
+ if (dataPin === null || clockPin === null || value === null || msbFirstRaw === null)
1186
873
  return null;
1187
- return { operation: "i2c.set_clock", bus, hz };
874
+ return { operation: "gpio.shift_out", dataPin, clockPin, value, msbFirst: msbFirstRaw !== "false" };
1188
875
  }
1189
- case "i2cBeginTx": {
1190
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1191
- const address = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1192
- if (bus === null || address === null)
876
+ case "gpioShiftIn": {
877
+ const dataPin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
878
+ const clockPin = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
879
+ const msbFirstRaw = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
880
+ if (dataPin === null || clockPin === null || msbFirstRaw === null)
1193
881
  return null;
1194
- return { operation: "i2c.begin_transmission", bus, address };
882
+ return { operation: "gpio.shift_in", dataPin, clockPin, msbFirst: msbFirstRaw !== "false" };
1195
883
  }
1196
- case "i2cWrite": {
1197
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1198
- if (bus === null)
1199
- return null;
1200
- const resolved = resolveI2cBufferArg(args, 1, instance, paramNames, callArgTexts, paramDefaults, callArgs);
1201
- if (!resolved)
1202
- return null;
1203
- if (resolved.kind === "bytes") {
1204
- return { operation: "i2c.write_bytes", bus, bytes: resolved.bytes };
884
+ case "pwmSetPulse":
885
+ case "pwmSetDuty":
886
+ case "pwmSetPeriod": {
887
+ const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
888
+ const periodNs = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
889
+ if (pin === null || periodNs === null)
890
+ return null;
891
+ // Inline routing overrides (the escape hatch): read the CONSTRUCTION
892
+ // fields off the instance the inlined method-body args arrive as
893
+ // unresolved text (quoted literals, `this->_x`), while fieldValues
894
+ // carry what the constructor actually assigned.
895
+ const pwmPulse = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
896
+ const pwmDuty = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
897
+ const controllerOverride = cleanOverrideText(instance.fieldValues.get("_controller"));
898
+ const pwmCh = Number(instance.fieldValues.get("_channel"));
899
+ const channelOverride = Number.isFinite(pwmCh) && pwmCh >= 0 ? pwmCh : undefined;
900
+ const routing = {
901
+ ...(controllerOverride !== undefined ? { controllerOverride } : {}),
902
+ ...(channelOverride !== undefined ? { channelOverride } : {}),
903
+ };
904
+ if (fnName === "pwmSetPulse") {
905
+ if (pwmPulse === null || typeof pwmPulse !== "number")
906
+ return null;
907
+ return { operation: "pwm.set_pulse", pin, periodNs, pulseNs: pwmPulse, ...routing };
1205
908
  }
1206
- return { operation: "i2c.write", bus, data: resolved.data };
1207
- }
1208
- case "i2cWriteBuffer": {
1209
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1210
- if (bus === null)
1211
- return null;
1212
- const resolved = resolveI2cBufferArg(args, 1, instance, paramNames, callArgTexts, paramDefaults, callArgs);
1213
- if (!resolved)
1214
- return null;
1215
- if (resolved.kind === "bytes") {
1216
- return { operation: "i2c.write_bytes", bus, bytes: resolved.bytes };
909
+ if (fnName === "pwmSetDuty") {
910
+ if (pwmDuty === null)
911
+ return null;
912
+ return { operation: "pwm.set_duty", pin, periodNs, duty: pwmDuty, ...routing };
1217
913
  }
1218
- return { operation: "i2c.write_buffer", bus, data: resolved.data };
914
+ return { operation: "pwm.set_period", pin, periodNs, ...routing };
1219
915
  }
1220
- case "i2cReadBuffer": {
1221
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1222
- const count = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1223
- if (bus === null || count === null)
1224
- return null;
1225
- return { operation: "i2c.read_buffer", bus, count, buffer: "__HAL_READ_BUF__" };
916
+ case "adcReadRaw":
917
+ case "adcReadMv": {
918
+ const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
919
+ const gain = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
920
+ const reference = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
921
+ if (pin === null || gain === null || reference === null)
922
+ return null;
923
+ // Inline routing overrides (the escape hatch): read the CONSTRUCTION
924
+ // fields off the instance — inlined method-body args arrive as
925
+ // unresolved text, fieldValues carry what the constructor assigned.
926
+ const adcCh = Number(instance.fieldValues.get("_channel"));
927
+ const channelOverride = Number.isFinite(adcCh) && adcCh >= 0 ? adcCh : undefined;
928
+ const deviceOverride = cleanOverrideText(instance.fieldValues.get("_device"));
929
+ const pinctrlOverride = cleanOverrideText(instance.fieldValues.get("_pinctrl"));
930
+ return {
931
+ operation: fnName === "adcReadRaw" ? "adc.read_raw" : "adc.read_mv",
932
+ pin,
933
+ gain,
934
+ reference,
935
+ ...(channelOverride !== undefined ? { channelOverride } : {}),
936
+ ...(deviceOverride !== undefined ? { deviceOverride } : {}),
937
+ ...(pinctrlOverride !== undefined ? { pinctrlOverride } : {}),
938
+ };
1226
939
  }
1227
- case "i2cEndTx": {
1228
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1229
- const stop = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1230
- if (bus === null || stop === null)
940
+ case "interruptAttachFlags": {
941
+ const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
942
+ const handler = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
943
+ const intFlags = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
944
+ if (pin === null || handler === null || intFlags === null)
1231
945
  return null;
1232
- return { operation: "i2c.end_transmission", bus, stop: stop !== "false" };
946
+ return { operation: "interrupt.attach_flags", pin, handler, intFlags };
1233
947
  }
1234
- case "i2cRequestFrom": {
1235
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1236
- const address = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1237
- const quantity = resolveNumericOrExpression(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1238
- if (bus === null || address === null || quantity === null)
948
+ case "timeSleep": {
949
+ const ms = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
950
+ if (ms === null)
1239
951
  return null;
1240
- // stop is optional; default to true (Arduino sends a STOP by default).
1241
- const stopRaw = resolveSemanticArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
1242
- const stop = stopRaw === null ? true : stopRaw !== "false";
1243
- return { operation: "i2c.request_from", bus, address, quantity, stop };
952
+ return { operation: "timing.sleep", ms };
1244
953
  }
1245
- case "i2cAvailable": {
1246
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1247
- if (bus === null)
954
+ case "timeNow":
955
+ return { operation: "timing.now" };
956
+ case "timeNowUs":
957
+ return { operation: "timing.now_us" };
958
+ case "timeBusyWaitUs": {
959
+ const us = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
960
+ if (us === null)
1248
961
  return null;
1249
- return { operation: "i2c.available", bus };
962
+ return { operation: "timing.busy_wait_us", us };
1250
963
  }
1251
- case "i2cRead": {
964
+ case "i2cRegWrite": {
1252
965
  const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1253
- if (bus === null)
966
+ const address = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
967
+ const hz = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
968
+ const reg = resolveNumericArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
969
+ const value = resolveNumericArg(args, 4, instance, paramNames, callArgTexts, paramDefaults);
970
+ if (bus === null || address === null || hz === null || reg === null || value === null)
1254
971
  return null;
1255
- return { operation: "i2c.read", bus };
972
+ return { operation: "i2c.reg_write", bus, address, hz, reg, value };
1256
973
  }
1257
- // ── SPI ──
1258
- case "spiBegin": {
974
+ case "i2cRegRead": {
1259
975
  const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1260
- if (bus === null)
976
+ const address = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
977
+ const hz = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
978
+ const reg = resolveNumericArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
979
+ if (bus === null || address === null || hz === null || reg === null)
1261
980
  return null;
1262
- return { operation: "spi.begin", bus };
981
+ return { operation: "i2c.reg_read", bus, address, hz, reg };
1263
982
  }
1264
- case "spiEnd": {
983
+ case "i2cRegUpdate": {
1265
984
  const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1266
- if (bus === null)
985
+ const address = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
986
+ const hz = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
987
+ const reg = resolveNumericArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
988
+ const mask = resolveNumericArg(args, 4, instance, paramNames, callArgTexts, paramDefaults);
989
+ const value = resolveNumericArg(args, 5, instance, paramNames, callArgTexts, paramDefaults);
990
+ if (bus === null || address === null || hz === null || reg === null || mask === null || value === null)
1267
991
  return null;
1268
- return { operation: "spi.end", bus };
992
+ return { operation: "i2c.reg_update", bus, address, hz, reg, mask, value };
1269
993
  }
1270
- case "spiTransfer": {
994
+ case "i2cDevWrite": {
1271
995
  const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1272
- const data = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1273
- if (bus === null || data === null)
996
+ const address = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
997
+ const hz = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
998
+ const data = resolveI2cBufferArg(args, 3, instance, paramNames, callArgTexts, paramDefaults, callArgs);
999
+ if (bus === null || address === null || hz === null || data === null)
1274
1000
  return null;
1275
- return { operation: "spi.transfer", bus, data };
1001
+ if (data.kind === "bytes") {
1002
+ return { operation: "i2c.dev_write", bus, address, hz, bytes: data.bytes };
1003
+ }
1004
+ return { operation: "i2c.dev_write", bus, address, hz, bytes: [data.data] };
1276
1005
  }
1277
- case "spiBeginTx": {
1278
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1279
- const settings = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1280
- if (bus === null || settings === null)
1006
+ case "dacWriteValue": {
1007
+ const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1008
+ const value = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1009
+ const resolution = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1010
+ if (pin === null || value === null || resolution === null)
1281
1011
  return null;
1282
- return { operation: "spi.begin_transaction", bus, settings };
1012
+ return { operation: "dac.write_value", pin, value, resolution };
1283
1013
  }
1284
- case "spiEndTx": {
1285
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1286
- if (bus === null)
1014
+ case "wdtSetup": {
1015
+ const timeoutMs = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1016
+ if (timeoutMs === null)
1287
1017
  return null;
1288
- return { operation: "spi.end_transaction", bus };
1018
+ return { operation: "wdt.setup", timeoutMs };
1289
1019
  }
1290
- case "spiCsLow": {
1291
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1292
- if (pin === null)
1020
+ case "wdtFeed":
1021
+ return { operation: "wdt.feed" };
1022
+ case "counterOnAlarm": {
1023
+ const inst = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1024
+ const handler = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1025
+ if (inst === null || handler === null)
1293
1026
  return null;
1294
- return { operation: "spi.cs_low", port, pin };
1027
+ return { operation: "counter.on_alarm", instance: inst, handler };
1295
1028
  }
1296
- case "spiCsHigh": {
1297
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1298
- if (pin === null)
1029
+ case "counterStart": {
1030
+ const inst = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1031
+ const hz = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1032
+ if (inst === null || hz === null)
1299
1033
  return null;
1300
- return { operation: "spi.cs_high", port, pin };
1034
+ return { operation: "counter.start", instance: inst, hz };
1301
1035
  }
1302
- case "spiSetMode": {
1303
- const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1304
- const mode = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1305
- if (bus === null || mode === null)
1036
+ case "counterStop": {
1037
+ const inst = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1038
+ if (inst === null)
1306
1039
  return null;
1307
- return { operation: "spi.set_mode", bus, mode };
1040
+ return { operation: "counter.stop", instance: inst };
1308
1041
  }
1309
- case "spiSetBitOrder": {
1042
+ case "spiTransceiveDt": {
1310
1043
  const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1311
- const order = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1312
- if (bus === null || order === null)
1313
- return null;
1314
- return { operation: "spi.set_bit_order", bus, order };
1044
+ const cs = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1045
+ const hz = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1046
+ const mode = resolveNumericArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
1047
+ const txData = resolveI2cBufferArg(args, 4, instance, paramNames, callArgTexts, paramDefaults, callArgs);
1048
+ let rx = resolveSemanticArg(args, 5, instance, paramNames, callArgTexts, paramDefaults);
1049
+ if (bus === null || cs === null || hz === null || mode === null || txData === null || rx === null)
1050
+ return null;
1051
+ // The class body's `rx ?? new Uint8Array(0)` arrives nullish-lowered as
1052
+ // `X != CUTTLEFISH_UNDEFINED ? X : new Uint8Array(0)` — the caller's
1053
+ // buffer identifier is the X branch ('' = write-only when omitted).
1054
+ if (rx.includes(" != CUTTLEFISH_UNDEFINED ? ")) {
1055
+ // Take the taken branch and strip the nullish wrapper's parens.
1056
+ rx = rx.split(" != CUTTLEFISH_UNDEFINED ? ")[0].replace(/^\(+/, "").trim();
1057
+ if (rx === "undefined" || rx === "null")
1058
+ rx = "";
1059
+ }
1060
+ const tx = txData.kind === "bytes" ? txData.bytes : [txData.data];
1061
+ return { operation: "spi.transceive", bus, cs, hz, mode, tx, rx };
1315
1062
  }
1316
- case "spiReadBuffer": {
1063
+ case "spiWriteDt": {
1317
1064
  const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1318
- const count = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1319
- if (bus === null || count === null)
1065
+ const cs = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1066
+ const hz = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1067
+ const mode = resolveNumericArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
1068
+ const txData = resolveI2cBufferArg(args, 4, instance, paramNames, callArgTexts, paramDefaults, callArgs);
1069
+ if (bus === null || cs === null || hz === null || mode === null || txData === null)
1320
1070
  return null;
1321
- // The buffer arg (args[2]) is only a placeholder for type resolution;
1322
- // the real target is the caller's variable, rewritten from
1323
- // __HAL_READ_BUF__ by replaceHalReadBufferPlaceholder.
1324
- return { operation: "spi.read_buffer", bus, count, buffer: "__HAL_READ_BUF__" };
1071
+ const tx = txData.kind === "bytes" ? txData.bytes : [txData.data];
1072
+ return { operation: "spi.dev_write", bus, cs, hz, mode, tx };
1325
1073
  }
1326
- // ── UART ──
1327
- case "uartBegin": {
1328
- const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1329
- const baud = resolveNumericOrExpression(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1330
- if (port === null || baud === null)
1331
- return null;
1332
- return { operation: "uart.begin", port, baud };
1333
- }
1334
- case "uartEnd": {
1335
- const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1336
- if (port === null)
1337
- return null;
1338
- return { operation: "uart.end", port };
1339
- }
1340
- case "uartPrint": {
1341
- const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1342
- const value = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1343
- if (port === null || value === null)
1344
- return null;
1345
- return { operation: "uart.print", port, value };
1346
- }
1347
- case "uartPrintln": {
1348
- const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1349
- const value = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1350
- if (port === null || value === null)
1351
- return null;
1352
- return { operation: "uart.println", port, value };
1353
- }
1354
- case "uartWrite": {
1355
- const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1356
- const data = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1357
- if (port === null || data === null)
1074
+ case "spiReadReg": {
1075
+ const bus = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1076
+ const cs = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1077
+ const hz = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1078
+ const mode = resolveNumericArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
1079
+ const reg = resolveNumericArg(args, 4, instance, paramNames, callArgTexts, paramDefaults);
1080
+ if (bus === null || cs === null || hz === null || mode === null || reg === null)
1358
1081
  return null;
1359
- return { operation: "uart.write", port, data };
1082
+ return { operation: "spi.reg_read", bus, cs, hz, mode, reg };
1360
1083
  }
1361
- case "uartRead": {
1084
+ case "uartPollWrite": {
1362
1085
  const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1363
- if (port === null)
1086
+ const baud = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1087
+ const data = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1088
+ if (port === null || baud === null || data === null)
1364
1089
  return null;
1365
- return { operation: "uart.read", port };
1090
+ return { operation: "uart.poll_write", port, baud, data };
1366
1091
  }
1367
- case "uartPeek": {
1092
+ case "uartRxAvailable": {
1368
1093
  const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1369
- if (port === null)
1094
+ const ring = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1095
+ if (port === null || ring === null)
1370
1096
  return null;
1371
- return { operation: "uart.peek", port };
1097
+ return { operation: "uart.rx_available", port, ring };
1372
1098
  }
1373
- case "uartAvailable": {
1099
+ case "uartRxPeek": {
1374
1100
  const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1375
- if (port === null)
1101
+ const ring = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1102
+ if (port === null || ring === null)
1376
1103
  return null;
1377
- return { operation: "uart.available", port };
1104
+ return { operation: "uart.rx_peek", port, ring };
1378
1105
  }
1379
- case "uartFlush": {
1106
+ case "uartRxRead": {
1380
1107
  const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1381
- if (port === null)
1382
- return null;
1383
- return { operation: "uart.flush", port };
1384
- }
1385
- case "uartPrintf": {
1386
- const port = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1387
- const format = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1388
- if (port === null || format === null)
1389
- return null;
1390
- // The HAL declares `...args: any[]`; the third semantic-call arg is the
1391
- // `args` rest identifier. resolveSemanticArg expands it via the spread
1392
- // mechanism into a comma-joined string — split it back into the per-arg
1393
- // list the UartPrintfOp expects.
1394
- const spreadText = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1395
- const varArgs = spreadText !== null && spreadText !== "" ? splitArgList(spreadText) : [];
1396
- return { operation: "uart.printf", port, format, args: varArgs };
1397
- }
1398
- // ── Pulse ──
1399
- case "pulseIn_": {
1400
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1401
- const value = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1402
- const timeout = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1403
- if (pin === null || value === null)
1404
- return null;
1405
- return { operation: "pulse.in", port, pin, value: (value ? 1 : 0), ...(timeout !== null ? { timeout } : {}) };
1406
- }
1407
- case "pulseInLong_": {
1408
- const pin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1409
- const value = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1410
- if (pin === null || value === null)
1108
+ const ring = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1109
+ if (port === null || ring === null)
1411
1110
  return null;
1412
- return { operation: "pulse.in_long", port, pin, value: (value ? 1 : 0) };
1111
+ return { operation: "uart.rx_read", port, ring };
1413
1112
  }
1414
- // ── Shift ──
1415
- case "shiftOut_": {
1416
- const dataPin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1417
- const clockPin = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1418
- const bitOrder = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1419
- const value = resolveNumericArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
1420
- if (dataPin === null || clockPin === null || bitOrder === null || value === null)
1421
- return null;
1422
- return { operation: "shift.out", dataPin, clockPin, bitOrder, value };
1423
- }
1424
- case "shiftIn_": {
1425
- const dataPin = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1426
- const clockPin = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1427
- const bitOrder = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1428
- if (dataPin === null || clockPin === null || bitOrder === null)
1113
+ case "threadStart": {
1114
+ const inst = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1115
+ const stackBytes = resolveNumericArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1116
+ // The class computes `opts?.priority ?? 5` only stackKb is captured at
1117
+ // instance creation, so apply the constructor's default here.
1118
+ const priority = resolveNumericArg(args, 2, instance, paramNames, callArgTexts, paramDefaults) ?? 5;
1119
+ const handler = resolveSemanticArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
1120
+ if (inst === null || stackBytes === null || handler === null)
1429
1121
  return null;
1430
- return { operation: "shift.in", dataPin, clockPin, bitOrder };
1122
+ return { operation: "thread.start", instance: inst, stackBytes, priority, handler };
1431
1123
  }
1432
- // ── Board ──
1433
- case "boardResolve": {
1434
- const p = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1435
- if (p === null)
1436
- return null;
1437
- return { operation: "board.resolve", path: p };
1438
- }
1439
- // ── Raw C++ passthrough ──
1440
- case "rawCpp": {
1441
- const code = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1442
- if (code === null)
1124
+ case "threadJoin": {
1125
+ const inst = resolveNumericArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1126
+ if (inst === null)
1443
1127
  return null;
1444
- return { operation: "raw", code };
1128
+ return { operation: "thread.join", instance: inst };
1129
+ }
1130
+ case "sensorFetch": {
1131
+ const part = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1132
+ const bus = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1133
+ const port = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1134
+ const busKind = resolveSemanticArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
1135
+ const spiHz = resolveNumericArg(args, 4, instance, paramNames, callArgTexts, paramDefaults);
1136
+ const spiMode = resolveSemanticArg(args, 5, instance, paramNames, callArgTexts, paramDefaults);
1137
+ const alertPin = resolveSemanticArg(args, 6, instance, paramNames, callArgTexts, paramDefaults);
1138
+ if (part === null || bus === null || port === null || busKind === null || spiHz === null || spiMode === null || alertPin === null)
1139
+ return null;
1140
+ return { operation: "sensor.fetch", part, bus, port, busKind, spiHz, spiMode, alertPin };
1141
+ }
1142
+ case "sensorGet": {
1143
+ const part = resolveSemanticArg(args, 0, instance, paramNames, callArgTexts, paramDefaults);
1144
+ const bus = resolveSemanticArg(args, 1, instance, paramNames, callArgTexts, paramDefaults);
1145
+ const port = resolveSemanticArg(args, 2, instance, paramNames, callArgTexts, paramDefaults);
1146
+ const busKind = resolveSemanticArg(args, 3, instance, paramNames, callArgTexts, paramDefaults);
1147
+ const spiHz = resolveNumericArg(args, 4, instance, paramNames, callArgTexts, paramDefaults);
1148
+ const spiMode = resolveSemanticArg(args, 5, instance, paramNames, callArgTexts, paramDefaults);
1149
+ const alertPin = resolveSemanticArg(args, 6, instance, paramNames, callArgTexts, paramDefaults);
1150
+ const chan = resolveSemanticArg(args, 7, instance, paramNames, callArgTexts, paramDefaults);
1151
+ if (part === null || bus === null || port === null || busKind === null || spiHz === null || spiMode === null || alertPin === null || chan === null)
1152
+ return null;
1153
+ return { operation: "sensor.get", part, bus, port, busKind, spiHz, spiMode, alertPin, chan };
1445
1154
  }
1446
1155
  default:
1447
1156
  return null;