@typecad/cuttlefish 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/dist/api/board-types.d.ts +1 -0
  4. package/dist/api/board-types.js +4 -0
  5. package/dist/api/capabilities.d.ts +12 -0
  6. package/dist/api/capabilities.js +1 -0
  7. package/dist/api/config.d.ts +120 -0
  8. package/dist/api/config.js +7 -0
  9. package/dist/api/index.d.ts +5 -0
  10. package/dist/api/index.js +2 -0
  11. package/dist/api/schema/builder.d.ts +14 -0
  12. package/dist/api/schema/builder.js +15 -0
  13. package/dist/api/schema/index.d.ts +2 -0
  14. package/dist/api/schema/index.js +1 -0
  15. package/dist/api/schema/types.d.ts +257 -0
  16. package/dist/api/schema/types.js +4 -0
  17. package/dist/api/shared/async-runtime-static.d.ts +8 -0
  18. package/dist/api/shared/async-runtime-static.js +201 -0
  19. package/dist/api/shared/async-types.d.ts +42 -0
  20. package/dist/api/shared/async-types.js +8 -0
  21. package/dist/api/shared/board-resolver.d.ts +12 -0
  22. package/dist/api/shared/board-resolver.js +7 -0
  23. package/dist/api/shared/cpp-type-ir.d.ts +229 -0
  24. package/dist/api/shared/cpp-type-ir.js +672 -0
  25. package/dist/api/shared/display-adapter.d.ts +12 -0
  26. package/dist/api/shared/display-adapter.js +145 -0
  27. package/dist/api/shared/display-adapters/eink-mono.d.ts +2 -0
  28. package/dist/api/shared/display-adapters/eink-mono.js +53 -0
  29. package/dist/api/shared/display-adapters/sdl.d.ts +2 -0
  30. package/dist/api/shared/display-adapters/sdl.js +452 -0
  31. package/dist/api/shared/display-adapters/ssd1309.d.ts +2 -0
  32. package/dist/api/shared/display-adapters/ssd1309.js +136 -0
  33. package/dist/api/shared/display-adapters/st7796.d.ts +2 -0
  34. package/dist/api/shared/display-adapters/st7796.js +132 -0
  35. package/dist/api/shared/display-capabilities.d.ts +45 -0
  36. package/dist/api/shared/display-capabilities.js +54 -0
  37. package/dist/api/shared/display-op-ir.d.ts +62 -0
  38. package/dist/api/shared/display-op-ir.js +19 -0
  39. package/dist/api/shared/display-profile.d.ts +265 -0
  40. package/dist/api/shared/display-profile.js +338 -0
  41. package/dist/api/shared/graphics-strategy.d.ts +29 -0
  42. package/dist/api/shared/graphics-strategy.js +11 -0
  43. package/dist/api/shared/hal-op-ir.d.ts +393 -0
  44. package/dist/api/shared/hal-op-ir.js +18 -0
  45. package/dist/api/shared/index.d.ts +26 -0
  46. package/dist/api/shared/index.js +21 -0
  47. package/dist/api/shared/ir-core.d.ts +363 -0
  48. package/dist/api/shared/ir-core.js +8 -0
  49. package/dist/api/shared/ir-declarations.d.ts +201 -0
  50. package/dist/api/shared/ir-declarations.js +26 -0
  51. package/dist/api/shared/ir.d.ts +85 -0
  52. package/dist/api/shared/ir.js +13 -0
  53. package/dist/api/shared/platform-strategy.d.ts +402 -0
  54. package/dist/api/shared/platform-strategy.js +14 -0
  55. package/dist/api/shared/polyfill-helper-registry.d.ts +11 -0
  56. package/dist/api/shared/polyfill-helper-registry.js +86 -0
  57. package/dist/api/shared/polyfill-types.d.ts +33 -0
  58. package/dist/api/shared/polyfill-types.js +76 -0
  59. package/dist/api/shared/promise-runtime.d.ts +10 -0
  60. package/dist/api/shared/promise-runtime.js +244 -0
  61. package/dist/api/shared/snprintf-types.d.ts +29 -0
  62. package/dist/api/shared/snprintf-types.js +8 -0
  63. package/dist/api/shared/string-method-registry.d.ts +53 -0
  64. package/dist/api/shared/string-method-registry.js +168 -0
  65. package/dist/api/shared/toolchain-types.d.ts +63 -0
  66. package/dist/api/shared/toolchain-types.js +71 -0
  67. package/dist/api/shared/types.d.ts +50 -0
  68. package/dist/api/shared/types.js +6 -0
  69. package/dist/ast/parse.d.ts +2 -0
  70. package/dist/ast/parse.js +4 -0
  71. package/dist/cache.d.ts +26 -0
  72. package/dist/cache.js +95 -0
  73. package/dist/cli-utils.d.ts +37 -0
  74. package/dist/cli-utils.js +250 -0
  75. package/dist/cli.d.ts +2 -0
  76. package/dist/cli.js +635 -0
  77. package/dist/config-loader.d.ts +78 -0
  78. package/dist/config-loader.js +508 -0
  79. package/dist/config-schema.d.ts +233 -0
  80. package/dist/config-schema.js +83 -0
  81. package/dist/create/board-checklist.d.ts +2 -0
  82. package/dist/create/board-checklist.js +52 -0
  83. package/dist/create/board-codegen.d.ts +9 -0
  84. package/dist/create/board-codegen.js +238 -0
  85. package/dist/create/board-generators.d.ts +12 -0
  86. package/dist/create/board-generators.js +652 -0
  87. package/dist/create/board-spec.d.ts +640 -0
  88. package/dist/create/board-spec.js +215 -0
  89. package/dist/create/eslint-rules-template.d.ts +2 -0
  90. package/dist/create/eslint-rules-template.js +672 -0
  91. package/dist/create/index.d.ts +11 -0
  92. package/dist/create/index.js +8 -0
  93. package/dist/create/init-scaffold.d.ts +27 -0
  94. package/dist/create/init-scaffold.js +150 -0
  95. package/dist/create/init-templates.d.ts +24 -0
  96. package/dist/create/init-templates.js +379 -0
  97. package/dist/create/init-wizard.d.ts +8 -0
  98. package/dist/create/init-wizard.js +168 -0
  99. package/dist/debug/breakpoint-loader.d.ts +24 -0
  100. package/dist/debug/breakpoint-loader.js +137 -0
  101. package/dist/debug/index.d.ts +3 -0
  102. package/dist/debug/index.js +7 -0
  103. package/dist/debug/preprocessor.d.ts +9 -0
  104. package/dist/debug/preprocessor.js +214 -0
  105. package/dist/debug/types.d.ts +32 -0
  106. package/dist/debug/types.js +6 -0
  107. package/dist/diagnostics/diagnostics-report.d.ts +51 -0
  108. package/dist/diagnostics/diagnostics-report.js +333 -0
  109. package/dist/diagnostics/json-schema.d.ts +138 -0
  110. package/dist/diagnostics/json-schema.js +27 -0
  111. package/dist/diagnostics/md-writer.d.ts +10 -0
  112. package/dist/diagnostics/md-writer.js +336 -0
  113. package/dist/diagnostics/mermaid-builder.d.ts +65 -0
  114. package/dist/diagnostics/mermaid-builder.js +681 -0
  115. package/dist/emit/cpp-emitter.d.ts +6 -0
  116. package/dist/emit/cpp-emitter.js +48 -0
  117. package/dist/emit/emitters/class-emitter.d.ts +2 -0
  118. package/dist/emit/emitters/class-emitter.js +523 -0
  119. package/dist/emit/emitters/emitter-context.d.ts +174 -0
  120. package/dist/emit/emitters/emitter-context.js +1 -0
  121. package/dist/emit/emitters/entrypoint-synthesizer.d.ts +2 -0
  122. package/dist/emit/emitters/entrypoint-synthesizer.js +175 -0
  123. package/dist/emit/emitters/function-emitter-impl.d.ts +19 -0
  124. package/dist/emit/emitters/function-emitter-impl.js +428 -0
  125. package/dist/emit/emitters/line-appender.d.ts +15 -0
  126. package/dist/emit/emitters/line-appender.js +344 -0
  127. package/dist/emit/emitters/namespace-emitter.d.ts +2 -0
  128. package/dist/emit/emitters/namespace-emitter.js +324 -0
  129. package/dist/emit/emitters/output-finalizer.d.ts +4 -0
  130. package/dist/emit/emitters/output-finalizer.js +267 -0
  131. package/dist/emit/emitters/setup.d.ts +3 -0
  132. package/dist/emit/emitters/setup.js +851 -0
  133. package/dist/emit/emitters/top-level-prep.d.ts +2 -0
  134. package/dist/emit/emitters/top-level-prep.js +706 -0
  135. package/dist/emit/emitters/type-decl-emitter.d.ts +2 -0
  136. package/dist/emit/emitters/type-decl-emitter.js +251 -0
  137. package/dist/emit/emitters/ui-emitter.d.ts +21 -0
  138. package/dist/emit/emitters/ui-emitter.js +564 -0
  139. package/dist/emit/enum-emitter.d.ts +1 -0
  140. package/dist/emit/enum-emitter.js +1 -0
  141. package/dist/emit/expression-renderer.d.ts +283 -0
  142. package/dist/emit/expression-renderer.js +1477 -0
  143. package/dist/emit/native-helpers-emitter.d.ts +11 -0
  144. package/dist/emit/native-helpers-emitter.js +34 -0
  145. package/dist/emit/route-hal-op.d.ts +5 -0
  146. package/dist/emit/route-hal-op.js +13 -0
  147. package/dist/emit/snprintf-helpers.d.ts +17 -0
  148. package/dist/emit/snprintf-helpers.js +462 -0
  149. package/dist/emit/statement-renderer.d.ts +189 -0
  150. package/dist/emit/statement-renderer.js +948 -0
  151. package/dist/emit/utils/async-state-machine.d.ts +42 -0
  152. package/dist/emit/utils/async-state-machine.js +343 -0
  153. package/dist/emit/utils/comment-helpers.d.ts +20 -0
  154. package/dist/emit/utils/comment-helpers.js +31 -0
  155. package/dist/emit/utils/cpp-helpers.d.ts +47 -0
  156. package/dist/emit/utils/cpp-helpers.js +85 -0
  157. package/dist/emit/utils/include-resolver.d.ts +58 -0
  158. package/dist/emit/utils/include-resolver.js +155 -0
  159. package/dist/emit/utils/index.d.ts +8 -0
  160. package/dist/emit/utils/index.js +12 -0
  161. package/dist/emit/utils/type-inference.d.ts +159 -0
  162. package/dist/emit/utils/type-inference.js +559 -0
  163. package/dist/eslint-check.d.ts +10 -0
  164. package/dist/eslint-check.js +102 -0
  165. package/dist/framework-package.d.ts +10 -0
  166. package/dist/framework-package.js +58 -0
  167. package/dist/framework-registry.d.ts +39 -0
  168. package/dist/framework-registry.js +30 -0
  169. package/dist/incremental-cache.d.ts +116 -0
  170. package/dist/incremental-cache.js +335 -0
  171. package/dist/ir/adc-range-validation.d.ts +11 -0
  172. package/dist/ir/adc-range-validation.js +250 -0
  173. package/dist/ir/ast-node-utils.d.ts +8 -0
  174. package/dist/ir/ast-node-utils.js +32 -0
  175. package/dist/ir/board-pin-utils.d.ts +13 -0
  176. package/dist/ir/board-pin-utils.js +65 -0
  177. package/dist/ir/board-resolver.d.ts +36 -0
  178. package/dist/ir/board-resolver.js +437 -0
  179. package/dist/ir/build-ir-state.d.ts +167 -0
  180. package/dist/ir/build-ir-state.js +306 -0
  181. package/dist/ir/build-ir.d.ts +2 -0
  182. package/dist/ir/build-ir.js +808 -0
  183. package/dist/ir/call-graph.d.ts +35 -0
  184. package/dist/ir/call-graph.js +194 -0
  185. package/dist/ir/compile-time-only.d.ts +2 -0
  186. package/dist/ir/compile-time-only.js +16 -0
  187. package/dist/ir/declaration-builders.d.ts +9 -0
  188. package/dist/ir/declaration-builders.js +608 -0
  189. package/dist/ir/entry-points.d.ts +30 -0
  190. package/dist/ir/entry-points.js +191 -0
  191. package/dist/ir/expression-to-ir.d.ts +5 -0
  192. package/dist/ir/expression-to-ir.js +2249 -0
  193. package/dist/ir/extract-property-chain.d.ts +10 -0
  194. package/dist/ir/extract-property-chain.js +30 -0
  195. package/dist/ir/feature-prescan.d.ts +3 -0
  196. package/dist/ir/feature-prescan.js +43 -0
  197. package/dist/ir/feature-registry.d.ts +30 -0
  198. package/dist/ir/feature-registry.js +816 -0
  199. package/dist/ir/filter.d.ts +7 -0
  200. package/dist/ir/filter.js +85 -0
  201. package/dist/ir/function-builder.d.ts +19 -0
  202. package/dist/ir/function-builder.js +670 -0
  203. package/dist/ir/hal/hal-emitter.d.ts +62 -0
  204. package/dist/ir/hal/hal-emitter.js +735 -0
  205. package/dist/ir/hal/hal-parser.d.ts +61 -0
  206. package/dist/ir/hal/hal-parser.js +473 -0
  207. package/dist/ir/hal/hal-plugins.d.ts +34 -0
  208. package/dist/ir/hal/hal-plugins.js +706 -0
  209. package/dist/ir/hal-resolver.d.ts +5 -0
  210. package/dist/ir/hal-resolver.js +5 -0
  211. package/dist/ir/heap-analysis.d.ts +8 -0
  212. package/dist/ir/heap-analysis.js +350 -0
  213. package/dist/ir/heap-array-validation.d.ts +24 -0
  214. package/dist/ir/heap-array-validation.js +29 -0
  215. package/dist/ir/identifier-collector.d.ts +18 -0
  216. package/dist/ir/identifier-collector.js +439 -0
  217. package/dist/ir/interrupt-analysis.d.ts +39 -0
  218. package/dist/ir/interrupt-analysis.js +467 -0
  219. package/dist/ir/memory-budget-validation.d.ts +10 -0
  220. package/dist/ir/memory-budget-validation.js +86 -0
  221. package/dist/ir/namespace-builder.d.ts +7 -0
  222. package/dist/ir/namespace-builder.js +152 -0
  223. package/dist/ir/ownership-analysis.d.ts +9 -0
  224. package/dist/ir/ownership-analysis.js +1207 -0
  225. package/dist/ir/peripheral-ownership.d.ts +3 -0
  226. package/dist/ir/peripheral-ownership.js +152 -0
  227. package/dist/ir/peripheral-symbols.d.ts +7 -0
  228. package/dist/ir/peripheral-symbols.js +57 -0
  229. package/dist/ir/peripheral-usage.d.ts +54 -0
  230. package/dist/ir/peripheral-usage.js +691 -0
  231. package/dist/ir/peripheral-validation.d.ts +8 -0
  232. package/dist/ir/peripheral-validation.js +77 -0
  233. package/dist/ir/pin-alias-conflict.d.ts +4 -0
  234. package/dist/ir/pin-alias-conflict.js +34 -0
  235. package/dist/ir/pin-capability-validation.d.ts +6 -0
  236. package/dist/ir/pin-capability-validation.js +413 -0
  237. package/dist/ir/pin-mode-validation.d.ts +10 -0
  238. package/dist/ir/pin-mode-validation.js +301 -0
  239. package/dist/ir/pin-safety.d.ts +11 -0
  240. package/dist/ir/pin-safety.js +58 -0
  241. package/dist/ir/program-analysis.d.ts +44 -0
  242. package/dist/ir/program-analysis.js +589 -0
  243. package/dist/ir/pulldown-validation.d.ts +7 -0
  244. package/dist/ir/pulldown-validation.js +49 -0
  245. package/dist/ir/pwm-timer-sharing.d.ts +4 -0
  246. package/dist/ir/pwm-timer-sharing.js +93 -0
  247. package/dist/ir/reachability.d.ts +68 -0
  248. package/dist/ir/reachability.js +224 -0
  249. package/dist/ir/register-decorators.d.ts +6 -0
  250. package/dist/ir/register-decorators.js +49 -0
  251. package/dist/ir/render-expr.d.ts +4 -0
  252. package/dist/ir/render-expr.js +127 -0
  253. package/dist/ir/resource-analysis.d.ts +19 -0
  254. package/dist/ir/resource-analysis.js +153 -0
  255. package/dist/ir/statement-to-ir.d.ts +23 -0
  256. package/dist/ir/statement-to-ir.js +349 -0
  257. package/dist/ir/symbol-table.d.ts +68 -0
  258. package/dist/ir/symbol-table.js +179 -0
  259. package/dist/ir/symbol-types.d.ts +56 -0
  260. package/dist/ir/symbol-types.js +107 -0
  261. package/dist/ir/timer0-pwm-timing-conflict.d.ts +4 -0
  262. package/dist/ir/timer0-pwm-timing-conflict.js +71 -0
  263. package/dist/ir/timing-validation.d.ts +7 -0
  264. package/dist/ir/timing-validation.js +95 -0
  265. package/dist/ir/transformers/array-methods.d.ts +8 -0
  266. package/dist/ir/transformers/array-methods.js +493 -0
  267. package/dist/ir/transformers/call-statement.d.ts +5 -0
  268. package/dist/ir/transformers/call-statement.js +758 -0
  269. package/dist/ir/transformers/callback-context-registry.d.ts +20 -0
  270. package/dist/ir/transformers/callback-context-registry.js +55 -0
  271. package/dist/ir/transformers/canvas-lowering.d.ts +42 -0
  272. package/dist/ir/transformers/canvas-lowering.js +249 -0
  273. package/dist/ir/transformers/control-flow.d.ts +8 -0
  274. package/dist/ir/transformers/control-flow.js +508 -0
  275. package/dist/ir/transformers/expressions.d.ts +7 -0
  276. package/dist/ir/transformers/expressions.js +406 -0
  277. package/dist/ir/transformers/hal-call-resolver.d.ts +29 -0
  278. package/dist/ir/transformers/hal-call-resolver.js +274 -0
  279. package/dist/ir/transformers/hal-emit-helpers.d.ts +14 -0
  280. package/dist/ir/transformers/hal-emit-helpers.js +63 -0
  281. package/dist/ir/transformers/namespace-methods.d.ts +20 -0
  282. package/dist/ir/transformers/namespace-methods.js +110 -0
  283. package/dist/ir/transformers/register-assignment.d.ts +5 -0
  284. package/dist/ir/transformers/register-assignment.js +56 -0
  285. package/dist/ir/transformers/ui-call-resolver.d.ts +149 -0
  286. package/dist/ir/transformers/ui-call-resolver.js +1136 -0
  287. package/dist/ir/transformers/ui-callback-lowering.d.ts +62 -0
  288. package/dist/ir/transformers/ui-callback-lowering.js +623 -0
  289. package/dist/ir/transformers/ui-mount.d.ts +20 -0
  290. package/dist/ir/transformers/ui-mount.js +35 -0
  291. package/dist/ir/transformers/ui-reactive.d.ts +68 -0
  292. package/dist/ir/transformers/ui-reactive.js +129 -0
  293. package/dist/ir/transformers/variables.d.ts +14 -0
  294. package/dist/ir/transformers/variables.js +1045 -0
  295. package/dist/ir/try-catch-validation.d.ts +26 -0
  296. package/dist/ir/try-catch-validation.js +128 -0
  297. package/dist/ir/type-resolution.d.ts +31 -0
  298. package/dist/ir/type-resolution.js +977 -0
  299. package/dist/ir/ui-element-auto-wire.d.ts +50 -0
  300. package/dist/ir/ui-element-auto-wire.js +218 -0
  301. package/dist/ir/unit-suspicion-validation.d.ts +12 -0
  302. package/dist/ir/unit-suspicion-validation.js +296 -0
  303. package/dist/ir/utils/walk-ir.d.ts +6 -0
  304. package/dist/ir/utils/walk-ir.js +162 -0
  305. package/dist/ir/validation-orchestrator.d.ts +4 -0
  306. package/dist/ir/validation-orchestrator.js +45 -0
  307. package/dist/libdef/base-class-resolver.d.ts +23 -0
  308. package/dist/libdef/base-class-resolver.js +50 -0
  309. package/dist/libdef/cpp-to-decl.d.ts +34 -0
  310. package/dist/libdef/cpp-to-decl.js +584 -0
  311. package/dist/libdef/header-parser.d.ts +53 -0
  312. package/dist/libdef/header-parser.js +269 -0
  313. package/dist/libdef/registry.d.ts +10 -0
  314. package/dist/libdef/registry.js +142 -0
  315. package/dist/mapping/peripheral-names.d.ts +23 -0
  316. package/dist/mapping/peripheral-names.js +63 -0
  317. package/dist/mapping/source-map.d.ts +46 -0
  318. package/dist/mapping/source-map.js +207 -0
  319. package/dist/orchestrator/dts-generator.d.ts +17 -0
  320. package/dist/orchestrator/dts-generator.js +83 -0
  321. package/dist/orchestrator/graph-builder.d.ts +18 -0
  322. package/dist/orchestrator/graph-builder.js +218 -0
  323. package/dist/orchestrator/semantic-facts-verifier.d.ts +38 -0
  324. package/dist/orchestrator/semantic-facts-verifier.js +121 -0
  325. package/dist/orchestrator/semantic-facts.d.ts +141 -0
  326. package/dist/orchestrator/semantic-facts.js +652 -0
  327. package/dist/orchestrator/type-checker.d.ts +39 -0
  328. package/dist/orchestrator/type-checker.js +760 -0
  329. package/dist/platform/async-runtime.d.ts +8 -0
  330. package/dist/platform/async-runtime.js +26 -0
  331. package/dist/platform/generic-strategy.d.ts +101 -0
  332. package/dist/platform/generic-strategy.js +289 -0
  333. package/dist/platform/index.d.ts +4 -0
  334. package/dist/platform/index.js +9 -0
  335. package/dist/platform/registry.d.ts +21 -0
  336. package/dist/platform/registry.js +42 -0
  337. package/dist/platform/toolchain.d.ts +4 -0
  338. package/dist/platform/toolchain.js +43 -0
  339. package/dist/preview/client.d.ts +1 -0
  340. package/dist/preview/client.js +137 -0
  341. package/dist/preview/server.d.ts +5 -0
  342. package/dist/preview/server.js +199 -0
  343. package/dist/profiler/index.d.ts +28 -0
  344. package/dist/profiler/index.js +28 -0
  345. package/dist/profiler/profiler.d.ts +95 -0
  346. package/dist/profiler/profiler.js +338 -0
  347. package/dist/profiler/types.d.ts +87 -0
  348. package/dist/profiler/types.js +12 -0
  349. package/dist/stores/display-profile-store.d.ts +16 -0
  350. package/dist/stores/display-profile-store.js +48 -0
  351. package/dist/stores/theme-store.d.ts +13 -0
  352. package/dist/stores/theme-store.js +30 -0
  353. package/dist/testing.d.ts +45 -0
  354. package/dist/testing.js +47 -0
  355. package/dist/transpile/resolution.d.ts +29 -0
  356. package/dist/transpile/resolution.js +282 -0
  357. package/dist/transpile.d.ts +3 -0
  358. package/dist/transpile.js +722 -0
  359. package/dist/types.d.ts +217 -0
  360. package/dist/types.js +1 -0
  361. package/dist/ui/ui-bridge.d.ts +4 -0
  362. package/dist/ui/ui-bridge.js +34 -0
  363. package/dist/ui-hook.d.ts +84 -0
  364. package/dist/ui-hook.js +45 -0
  365. package/dist/utils/cli.d.ts +3 -0
  366. package/dist/utils/cli.js +463 -0
  367. package/dist/utils/fs.d.ts +4 -0
  368. package/dist/utils/fs.js +23 -0
  369. package/dist/utils/logger.d.ts +2 -0
  370. package/dist/utils/logger.js +8 -0
  371. package/dist/utils/strings.d.ts +35 -0
  372. package/dist/utils/strings.js +142 -0
  373. package/dist/utils/ui.d.ts +66 -0
  374. package/dist/utils/ui.js +149 -0
  375. package/dist/watch.d.ts +35 -0
  376. package/dist/watch.js +111 -0
  377. package/package.json +127 -0
@@ -0,0 +1,93 @@
1
+ import { findBoardPinByName, formatPinReference } from './board-pin-utils.js';
2
+ function extractTimerId(role, timerField) {
3
+ // Prefer explicit timer field from board definition
4
+ if (timerField) {
5
+ return timerField;
6
+ }
7
+ if (!role) {
8
+ return undefined;
9
+ }
10
+ // Fall back to parsing AVR OC register naming convention
11
+ const match = role.match(/^OC(\d+)[A-Z]?$/i);
12
+ return match ? `timer${match[1]}` : undefined;
13
+ }
14
+ function getPwmTimerPins(boardConstants) {
15
+ if (!boardConstants) {
16
+ return [];
17
+ }
18
+ const pinsByIndex = new Map();
19
+ for (const [key, value] of boardConstants) {
20
+ const nameMatch = key.match(/^pins\.all\.(\d+)\.name$/);
21
+ if (nameMatch && typeof value === 'string') {
22
+ const pinIndex = nameMatch[1];
23
+ const numberValue = boardConstants.get(`pins.all.${pinIndex}.number`);
24
+ const aliasesValue = boardConstants.get(`pins.all.${pinIndex}.aliases`);
25
+ const aliases = typeof aliasesValue === 'string' && aliasesValue.length > 0
26
+ ? aliasesValue.split(',').map(entry => entry.trim()).filter(Boolean)
27
+ : [];
28
+ pinsByIndex.set(pinIndex, {
29
+ pinNumber: typeof numberValue === 'number' ? numberValue : Number(pinIndex),
30
+ canonicalName: value,
31
+ aliases,
32
+ timerId: '',
33
+ });
34
+ }
35
+ }
36
+ for (const [key, value] of boardConstants) {
37
+ const typeMatch = key.match(/^pins\.all\.(\d+)\.functions\.\d+\.type$/);
38
+ if (!typeMatch || value !== 'pwm') {
39
+ continue;
40
+ }
41
+ const pinIndex = typeMatch[1];
42
+ const roleKey = key.replace(/\.type$/, '.role');
43
+ const timerKey = key.replace(/\.type$/, '.timer');
44
+ const timerId = extractTimerId(boardConstants.get(roleKey), boardConstants.get(timerKey));
45
+ if (!timerId) {
46
+ continue;
47
+ }
48
+ const pin = pinsByIndex.get(pinIndex);
49
+ if (pin) {
50
+ pin.timerId = timerId;
51
+ }
52
+ }
53
+ return Array.from(pinsByIndex.values()).filter(pin => pin.timerId.length > 0);
54
+ }
55
+ export function validatePWMTimerSharing(usage, boardConstants) {
56
+ if (usage.pwmPinsUsed.size < 2 || !boardConstants) {
57
+ return [];
58
+ }
59
+ const boardName = boardConstants.get('name');
60
+ const boardLabel = typeof boardName === 'string' && boardName.length > 0
61
+ ? ` on ${boardName}`
62
+ : '';
63
+ const pins = getPwmTimerPins(boardConstants);
64
+ const pinsByTimer = new Map();
65
+ for (const pin of pins) {
66
+ if (!usage.pwmPinsUsed.has(pin.pinNumber)) {
67
+ continue;
68
+ }
69
+ const group = pinsByTimer.get(pin.timerId) ?? [];
70
+ group.push(pin);
71
+ pinsByTimer.set(pin.timerId, group);
72
+ }
73
+ const diagnostics = [];
74
+ for (const [timerId, timerPins] of pinsByTimer) {
75
+ if (timerPins.length < 2) {
76
+ continue;
77
+ }
78
+ const references = timerPins
79
+ .sort((left, right) => left.pinNumber - right.pinNumber)
80
+ .map((pin) => {
81
+ const usedNames = [pin.canonicalName, ...pin.aliases].filter(name => usage.pinsUsed.has(name));
82
+ const preferredName = usedNames[0] ?? pin.canonicalName;
83
+ return formatPinReference(preferredName, findBoardPinByName(pin.canonicalName, boardConstants));
84
+ });
85
+ diagnostics.push({
86
+ severity: 'info',
87
+ code: 'pwm-timer-sharing',
88
+ source: 'pwm-timer-sharing',
89
+ message: `${references.join(', ')} share ${timerId}${boardLabel}. Duty cycle can differ per pin, but timer-wide PWM settings are shared across that group. Prefer pins on different timer groups if you need independent PWM timing behavior.`,
90
+ });
91
+ }
92
+ return diagnostics;
93
+ }
@@ -0,0 +1,68 @@
1
+ import { ProgramIR, FunctionIR, ClassIR, EnumIR, TypeAliasIR } from "../api/index.js";
2
+ import { CallGraph } from "./call-graph.js";
3
+ import { EntryPointConfig } from "./entry-points.js";
4
+ import { TargetProfile, Diagnostic } from "../types.js";
5
+ /**
6
+ * Result of reachability analysis
7
+ */
8
+ export interface ReachabilityResult {
9
+ /** Functions that are reachable from entry points */
10
+ reachableFunctions: Set<string>;
11
+ /** Classes that are reachable from entry points */
12
+ reachableClasses: Set<string>;
13
+ /** Enums that are reachable from entry points */
14
+ reachableEnums: Set<string>;
15
+ /** Type aliases that are reachable from entry points */
16
+ reachableTypeAliases: Set<string>;
17
+ /** Top-level variable names that are reachable from entry points */
18
+ reachableVariables: Set<string>;
19
+ /** Indices of reachable top-level statements */
20
+ reachableTopLevelStatements: number[];
21
+ /** Unreachable code items */
22
+ unreachable: {
23
+ functions: FunctionIR[];
24
+ classes: ClassIR[];
25
+ enums: EnumIR[];
26
+ typeAliases: TypeAliasIR[];
27
+ };
28
+ /** Diagnostics for unreachable code */
29
+ diagnostics: Diagnostic[];
30
+ }
31
+ /**
32
+ * Options for reachability analysis (internal)
33
+ */
34
+ interface ReachabilityOptions {
35
+ /** Target platform */
36
+ target: TargetProfile;
37
+ /** Entry point configuration */
38
+ entryPointConfig?: Partial<EntryPointConfig>;
39
+ /** Keep enums even if not referenced */
40
+ keepUnusedEnums?: boolean;
41
+ /** Keep classes even if not instantiated */
42
+ keepUnusedClasses?: boolean;
43
+ /** Keep type aliases even if not used */
44
+ keepUnusedTypeAliases?: boolean;
45
+ /** Keep top-level variables even if not referenced */
46
+ keepUnusedVariables?: boolean;
47
+ /** Generate diagnostics for unreachable code */
48
+ reportUnused?: boolean;
49
+ }
50
+ /**
51
+ * Analyze reachability from entry points in a program
52
+ */
53
+ export declare function analyzeReachability(program: ProgramIR, callGraph: CallGraph, options: ReachabilityOptions): ReachabilityResult;
54
+ /**
55
+ * Get statistics about reachability
56
+ */
57
+ export declare function getReachabilityStats(program: ProgramIR, result: ReachabilityResult): {
58
+ totalFunctions: number;
59
+ reachableFunctions: number;
60
+ totalClasses: number;
61
+ reachableClasses: number;
62
+ totalEnums: number;
63
+ reachableEnums: number;
64
+ totalTypeAliases: number;
65
+ reachableTypeAliases: number;
66
+ reductionPercent: number;
67
+ };
68
+ export {};
@@ -0,0 +1,224 @@
1
+ import { getReachableSymbols } from "./call-graph.js";
2
+ import { detectEntryPoints } from "./entry-points.js";
3
+ import { resolveStrategy } from "../platform/registry.js";
4
+ /**
5
+ * Analyze reachability from entry points in a program
6
+ */
7
+ export function analyzeReachability(program, callGraph, options) {
8
+ const { target, entryPointConfig, keepUnusedEnums = false, keepUnusedClasses = false, keepUnusedTypeAliases = false, keepUnusedVariables = false, reportUnused = false, } = options;
9
+ // Detect entry points — derive from platform strategy instead of hardcoded target strings
10
+ const strategy = resolveStrategy(target);
11
+ const strategyEntryPoints = strategy.requiresLoopFunction()
12
+ ? [strategy.entrypointFunctionName(), "loop"]
13
+ : [strategy.entrypointFunctionName()];
14
+ const entryPoints = detectEntryPoints(program, entryPointConfig, strategyEntryPoints);
15
+ // Get all reachable symbols from entry points
16
+ const reachableSymbols = getReachableSymbols(callGraph, entryPoints);
17
+ // Get defined symbols
18
+ const definedFunctions = new Map();
19
+ for (const fn of program.functions) {
20
+ definedFunctions.set(fn.originalName, fn);
21
+ }
22
+ const definedClasses = new Map();
23
+ for (const cls of program.classes) {
24
+ definedClasses.set(cls.name, cls);
25
+ }
26
+ const definedEnums = new Map();
27
+ for (const enumDef of program.enums) {
28
+ definedEnums.set(enumDef.name, enumDef);
29
+ }
30
+ const definedTypeAliases = new Map();
31
+ for (const typeAlias of program.typeAliases) {
32
+ definedTypeAliases.set(typeAlias.name, typeAlias);
33
+ }
34
+ // Determine reachable items
35
+ const reachableFunctions = new Set();
36
+ const reachableClasses = new Set();
37
+ const reachableEnums = new Set();
38
+ const reachableTypeAliases = new Set();
39
+ const reachableVariables = new Set();
40
+ // Collect names of top-level var_decl statements
41
+ const definedVariables = new Set();
42
+ for (const stmt of program.topLevelStatements) {
43
+ if (stmt.kind === "var_decl") {
44
+ definedVariables.add(stmt.name);
45
+ }
46
+ }
47
+ // All top-level statements are reachable by definition
48
+ const reachableTopLevelStatements = program.topLevelStatements.map((_, index) => index);
49
+ // Check each symbol for reachability
50
+ for (const symbol of reachableSymbols) {
51
+ if (definedFunctions.has(symbol)) {
52
+ reachableFunctions.add(symbol);
53
+ }
54
+ if (definedClasses.has(symbol)) {
55
+ reachableClasses.add(symbol);
56
+ }
57
+ if (definedEnums.has(symbol)) {
58
+ reachableEnums.add(symbol);
59
+ }
60
+ if (definedTypeAliases.has(symbol)) {
61
+ reachableTypeAliases.add(symbol);
62
+ }
63
+ if (definedVariables.has(symbol)) {
64
+ reachableVariables.add(symbol);
65
+ }
66
+ }
67
+ // Mark base classes as reachable when their derived classes are reachable.
68
+ // The call graph only tracks direct references, not inheritance relationships.
69
+ let changed = true;
70
+ while (changed) {
71
+ changed = false;
72
+ for (const cls of program.classes) {
73
+ if (reachableClasses.has(cls.name) && cls.extendsClass && !reachableClasses.has(cls.extendsClass)) {
74
+ reachableClasses.add(cls.extendsClass);
75
+ changed = true;
76
+ }
77
+ }
78
+ }
79
+ // Apply keep options
80
+ if (keepUnusedEnums) {
81
+ for (const [name] of definedEnums) {
82
+ reachableEnums.add(name);
83
+ }
84
+ }
85
+ if (keepUnusedClasses) {
86
+ for (const [name] of definedClasses) {
87
+ reachableClasses.add(name);
88
+ }
89
+ }
90
+ if (keepUnusedTypeAliases) {
91
+ for (const [name] of definedTypeAliases) {
92
+ reachableTypeAliases.add(name);
93
+ }
94
+ }
95
+ if (keepUnusedVariables) {
96
+ for (const name of definedVariables) {
97
+ reachableVariables.add(name);
98
+ }
99
+ }
100
+ // Collect unreachable items
101
+ const unreachableFunctions = [];
102
+ const unreachableClasses = [];
103
+ const unreachableEnums = [];
104
+ const unreachableTypeAliases = [];
105
+ const diagnostics = [];
106
+ for (const [name, fn] of definedFunctions) {
107
+ if (!reachableFunctions.has(name)) {
108
+ unreachableFunctions.push(fn);
109
+ if (reportUnused) {
110
+ diagnostics.push({
111
+ severity: "info",
112
+ message: `Function '${name}' is unreachable and will be removed from output.`,
113
+ line: fn.sourceSpan.startLine,
114
+ column: fn.sourceSpan.startColumn,
115
+ code: "TS2CPP_UNREACHABLE_FUNCTION",
116
+ });
117
+ }
118
+ }
119
+ }
120
+ for (const [name, cls] of definedClasses) {
121
+ if (!reachableClasses.has(name)) {
122
+ unreachableClasses.push(cls);
123
+ if (reportUnused) {
124
+ diagnostics.push({
125
+ severity: "info",
126
+ message: `Class '${name}' is unreachable and will be removed from output.`,
127
+ line: cls.sourceSpan.startLine,
128
+ column: cls.sourceSpan.startColumn,
129
+ code: "TS2CPP_UNREACHABLE_CLASS",
130
+ });
131
+ }
132
+ }
133
+ }
134
+ for (const [name, enumDef] of definedEnums) {
135
+ if (!reachableEnums.has(name)) {
136
+ unreachableEnums.push(enumDef);
137
+ // NOTE: Enum reachability warnings are currently disabled because enums may be
138
+ // referenced in type annotations or used for their type information without
139
+ // appearing in the runtime dependency graph. An enum may be used to type a
140
+ // variable or parameter, making it appear "unreachable" even though it was used.
141
+ //
142
+ // Future improvement: Track enum usage in type annotations and enable this
143
+ // warning when we can accurately detect truly unused enums.
144
+ //
145
+ // if (reportUnused) {
146
+ // diagnostics.push({
147
+ // severity: "info",
148
+ // message: `Enum '${name}' is unreachable and will be removed from output.`,
149
+ // line: enumDef.sourceSpan.startLine,
150
+ // column: enumDef.sourceSpan.startColumn,
151
+ // code: "TS2CPP_UNREACHABLE_ENUM",
152
+ // });
153
+ // }
154
+ }
155
+ }
156
+ for (const [name, typeAlias] of definedTypeAliases) {
157
+ if (!reachableTypeAliases.has(name)) {
158
+ unreachableTypeAliases.push(typeAlias);
159
+ // NOTE: Type alias reachability warnings are currently disabled because TypeScript
160
+ // type aliases are compile-time only and don't always appear in the IR's dependency
161
+ // graph. A type alias may be used for type annotations that get erased during
162
+ // transpilation, making it appear "unreachable" even though it was used.
163
+ //
164
+ // Future improvement: Track type alias usage in type annotations and enable
165
+ // this warning when we can accurately detect truly unused type aliases.
166
+ //
167
+ // if (reportUnused) {
168
+ // diagnostics.push({
169
+ // severity: "info",
170
+ // message: `Type alias '${name}' is unreachable and will be removed from output.`,
171
+ // line: typeAlias.sourceSpan.startLine,
172
+ // column: typeAlias.sourceSpan.startColumn,
173
+ // code: "TS2CPP_UNREACHABLE_TYPE_ALIAS",
174
+ // });
175
+ // }
176
+ }
177
+ }
178
+ return {
179
+ reachableFunctions,
180
+ reachableClasses,
181
+ reachableEnums,
182
+ reachableTypeAliases,
183
+ reachableVariables,
184
+ reachableTopLevelStatements,
185
+ unreachable: {
186
+ functions: unreachableFunctions,
187
+ classes: unreachableClasses,
188
+ enums: unreachableEnums,
189
+ typeAliases: unreachableTypeAliases,
190
+ },
191
+ diagnostics,
192
+ };
193
+ }
194
+ /**
195
+ * Get statistics about reachability
196
+ */
197
+ export function getReachabilityStats(program, result) {
198
+ const totalFunctions = program.functions.length;
199
+ const totalClasses = program.classes.length;
200
+ const totalEnums = program.enums.length;
201
+ const totalTypeAliases = program.typeAliases.length;
202
+ const reachableFunctions = result.reachableFunctions.size;
203
+ const reachableClasses = result.reachableClasses.size;
204
+ const reachableEnums = result.reachableEnums.size;
205
+ const reachableTypeAliases = result.reachableTypeAliases.size;
206
+ const totalItems = totalFunctions + totalClasses + totalEnums + totalTypeAliases;
207
+ const reachableItems = reachableFunctions + reachableClasses + reachableEnums + reachableTypeAliases;
208
+ const totalVariables = program.topLevelStatements.filter((s) => s.kind === "var_decl").length;
209
+ const reachableVariableCount = result.reachableVariables.size;
210
+ const totalAll = totalItems + totalVariables;
211
+ const reachableAll = reachableItems + reachableVariableCount;
212
+ const reductionPercent = totalAll > 0 ? ((totalAll - reachableAll) / totalAll) * 100 : 0;
213
+ return {
214
+ totalFunctions,
215
+ reachableFunctions,
216
+ totalClasses,
217
+ reachableClasses,
218
+ totalEnums,
219
+ reachableEnums,
220
+ totalTypeAliases,
221
+ reachableTypeAliases,
222
+ reductionPercent,
223
+ };
224
+ }
@@ -0,0 +1,6 @@
1
+ import ts from "typescript";
2
+ export declare function getRegisterAddress(node: ts.ClassDeclaration): number | undefined;
3
+ export declare function getBitsRange(node: ts.PropertyDeclaration): {
4
+ hi: number;
5
+ lo: number;
6
+ } | undefined;
@@ -0,0 +1,49 @@
1
+ import ts from "typescript";
2
+ export function getRegisterAddress(node) {
3
+ const decorators = ts.canHaveDecorators?.(node)
4
+ ? ts.getDecorators?.(node)
5
+ : node.decorators;
6
+ if (!decorators)
7
+ return undefined;
8
+ for (const dec of decorators) {
9
+ if (!ts.isCallExpression(dec.expression))
10
+ continue;
11
+ const callee = dec.expression.expression;
12
+ if (!ts.isIdentifier(callee) || callee.text !== "register")
13
+ continue;
14
+ const args = dec.expression.arguments;
15
+ if (args.length < 1)
16
+ continue;
17
+ const arg = args[0];
18
+ if (ts.isNumericLiteral(arg) || ts.isBigIntLiteral?.(arg)) {
19
+ return Number(arg.text);
20
+ }
21
+ if (ts.isPrefixUnaryExpression(arg) && arg.operator === ts.SyntaxKind.MinusToken && ts.isNumericLiteral(arg.operand)) {
22
+ return -Number(arg.operand.text);
23
+ }
24
+ }
25
+ return undefined;
26
+ }
27
+ export function getBitsRange(node) {
28
+ const decorators = ts.canHaveDecorators?.(node)
29
+ ? ts.getDecorators?.(node)
30
+ : node.decorators;
31
+ if (!decorators)
32
+ return undefined;
33
+ for (const dec of decorators) {
34
+ if (!ts.isCallExpression(dec.expression))
35
+ continue;
36
+ const callee = dec.expression.expression;
37
+ if (!ts.isIdentifier(callee) || callee.text !== "bits")
38
+ continue;
39
+ const args = dec.expression.arguments;
40
+ if (args.length < 2)
41
+ continue;
42
+ const hiArg = args[0];
43
+ const loArg = args[1];
44
+ if (ts.isNumericLiteral(hiArg) && ts.isNumericLiteral(loArg)) {
45
+ return { hi: Number(hiArg.text), lo: Number(loArg.text) };
46
+ }
47
+ }
48
+ return undefined;
49
+ }
@@ -0,0 +1,4 @@
1
+ import ts from "typescript";
2
+ import { ExpressionIR } from "../api/index.js";
3
+ export declare function calleeToText(expr: ts.LeftHandSideExpression): string;
4
+ export declare function renderExprAsText(expr: ExpressionIR): string;
@@ -0,0 +1,127 @@
1
+ import ts from "typescript";
2
+ import { nestedFunctionAliases, getContext } from "./build-ir-state.js";
3
+ import { escapeCppStringLiteral } from "../utils/strings.js";
4
+ import { routeHALOp } from "../emit/route-hal-op.js";
5
+ export function calleeToText(expr) {
6
+ if (ts.isIdentifier(expr)) {
7
+ const alias = nestedFunctionAliases.get(expr.text);
8
+ return alias ?? expr.text;
9
+ }
10
+ if (ts.isPropertyAccessExpression(expr)) {
11
+ return `${calleeToText(expr.expression)}.${expr.name.text}`;
12
+ }
13
+ return expr.getText();
14
+ }
15
+ /**
16
+ * Push a diagnostic onto the current build's diagnostics sink (the same array
17
+ * returned in ProgramIR.diagnostics). No-op if no build is in progress (e.g.
18
+ * ad-hoc calls from tests), so renderExprAsText remains usable in isolation.
19
+ */
20
+ function pushDiagnostic(severity, code, message) {
21
+ const diagnostics = getContext().diagnostics;
22
+ if (!diagnostics)
23
+ return;
24
+ diagnostics.push({ severity, message, code });
25
+ }
26
+ export function renderExprAsText(expr) {
27
+ switch (expr.kind) {
28
+ case "number": {
29
+ if (expr.cppType === "float" || expr.cppType === "double" || !Number.isInteger(expr.value)) {
30
+ const str = `${expr.value}`;
31
+ return str.includes('.') || str.includes('e') || str.includes('E')
32
+ ? `${str}f`
33
+ : `${str}.0f`;
34
+ }
35
+ return `${expr.value}`;
36
+ }
37
+ case "string":
38
+ // Route through the shared `escapeCppStringLiteral` helper (the SAME one
39
+ // the template-literal / snprintf path uses) so a standalone-rendered
40
+ // string literal is escaped identically to one rendered inside a template
41
+ // literal. Previously this only escaped `"` — so a literal whose decoded
42
+ // text held a control char or backslash (e.g. a `'\n'`/`'\t'`/`'\\'`
43
+ // argument to an array/string method) emitted a RAW newline/tab/backslash
44
+ // inside the C++ string literal, producing an unterminated literal that
45
+ // corrupted lexing of the entire rest of the file. Demo #29 Finding A.
46
+ return `"${escapeCppStringLiteral(expr.value)}"`;
47
+ case "boolean":
48
+ return expr.value ? "true" : "false";
49
+ case "identifier":
50
+ return expr.value;
51
+ case "raw":
52
+ return expr.value;
53
+ case "element-access":
54
+ return `${renderExprAsText(expr.object)}[${renderExprAsText(expr.index)}]`;
55
+ case "tuple-access":
56
+ return `std::get<${expr.index}>(${renderExprAsText(expr.object)})`;
57
+ case "await":
58
+ return renderExprAsText(expr.value);
59
+ case "ternary":
60
+ return `(${renderExprAsText(expr.condition)} ? ${renderExprAsText(expr.whenTrue)} : ${renderExprAsText(expr.whenFalse)})`;
61
+ case "array": {
62
+ const elements = expr.elements.map((e) => renderExprAsText(e)).join(", ");
63
+ return `{ ${elements} }`;
64
+ }
65
+ case "object":
66
+ const fieldValues = expr.fields.map((f) => `${renderExprAsText(f.value)}`).join(", ");
67
+ return `{ ${fieldValues} }`;
68
+ case "binary":
69
+ return `${renderExprAsText(expr.left)} ${expr.operator} ${renderExprAsText(expr.right)}`;
70
+ case "unary":
71
+ return `${expr.operator}${renderExprAsText(expr.operand)}`;
72
+ case "property-access": {
73
+ const objText = renderExprAsText(expr.object);
74
+ if (expr.isEnum || expr.isNamespace || expr.isStatic) {
75
+ return `${objText}::${expr.property}`;
76
+ }
77
+ const isPointer = expr.isPointer || (expr.object.kind === "raw" && expr.object.value === "this");
78
+ const sep = isPointer ? "->" : ".";
79
+ return `${objText}${sep}${expr.property}`;
80
+ }
81
+ case "paren":
82
+ return `(${renderExprAsText(expr.inner)})`;
83
+ case "callback":
84
+ return `/* __callback__ */`;
85
+ case "lambda":
86
+ return `/* __lambda__ */`;
87
+ case "method-call": {
88
+ const argsText = expr.args.map(a => renderExprAsText(a)).join(", ");
89
+ return `${expr.callee}(${argsText})`;
90
+ }
91
+ case "template_string":
92
+ return renderExprAsText(expr.expression);
93
+ case "string_concat":
94
+ return expr.parts.map(p => renderExprAsText(p)).join(" + ");
95
+ case "hal-expr": {
96
+ const strategy = getContext().activeStrategy;
97
+ if (strategy?.resolveHALOperation || strategy?.resolveDisplayOp) {
98
+ const resolved = routeHALOp(expr.operation, strategy);
99
+ if (resolved?.expression)
100
+ return resolved.expression;
101
+ if (resolved?.code)
102
+ return resolved.code.replace(/;\s*$/, "");
103
+ }
104
+ // Unregistered HAL op: surface as a warning so the user sees it, but keep
105
+ // HAL as an extensibility point (a strategy may intentionally leave some
106
+ // ops unimplemented). The bare comment is retained as a visual marker.
107
+ pushDiagnostic("warning", "TS2CPP_UNHANDLED_HAL", `HAL operation '${expr.operation.operation}' is not registered with the platform strategy; emitting a placeholder comment.`);
108
+ return `/* unhandled hal-expr: ${expr.operation.operation} */`;
109
+ }
110
+ case "instanceof":
111
+ return `(typeid(*${renderExprAsText(expr.object)}) == typeid(${expr.className}))`;
112
+ case "spread_array":
113
+ return renderExprAsText(expr.spreadExpr);
114
+ default: {
115
+ // An ExpressionIR kind renderExprAsText doesn't know how to render is a
116
+ // transpiler bug (the renderer should cover every kind the IR builders
117
+ // can produce). Previously this silently emitted "0 /* unsupported_expr */"
118
+ // into the C++ output. Now we push an error diagnostic — the fatal-gate
119
+ // check in transpile.ts aborts the build — and throw so that callers
120
+ // running outside the build (e.g. tests) fail loudly rather than
121
+ // continuing with placeholder C++.
122
+ const kind = expr.kind ?? "<unknown>";
123
+ pushDiagnostic("error", "TS2CPP_UNSUPPORTED_EXPR", `Expression IR kind '${kind}' has no renderer and cannot be emitted to C++.`);
124
+ throw new Error(`renderExprAsText: unsupported ExpressionIR kind '${kind}'`);
125
+ }
126
+ }
127
+ }
@@ -0,0 +1,19 @@
1
+ import { ProgramIR, PlatformStrategy, Diagnostic } from "../api/index.js";
2
+ export interface ResourceUsage {
3
+ pins: Map<string, {
4
+ source: string;
5
+ peripheral?: string;
6
+ }>;
7
+ peripherals: Map<string, {
8
+ source: string;
9
+ instance: number;
10
+ }>;
11
+ }
12
+ /**
13
+ * Unified hardware resource conflict analysis.
14
+ * Detects:
15
+ * 1. Pin Multiplexing Conflicts: Same pin used for GPIO and a Peripheral (I2C, SPI, UART).
16
+ * 2. Peripheral Instance Conflicts: Multiple peripherals sharing the same pins.
17
+ * 3. Board-Specific Hardware Warnings: Logic for specific pins (e.g. "Pin 13 has a built-in LED").
18
+ */
19
+ export declare function analyzeResources(program: ProgramIR, strategy: PlatformStrategy): Diagnostic[];