@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,42 @@
1
+ /**
2
+ * Async state machine generation utilities.
3
+ * Handles conversion of async functions to cooperative state machines.
4
+ * Extracted from cpp-emitter.ts
5
+ */
6
+ import type { StatementIR } from "../../api/index.js";
7
+ import type { PlatformStrategy } from "../../api/shared/index.js";
8
+ /**
9
+ * Converts a string to PascalCase.
10
+ * Used for generating class names from function names.
11
+ *
12
+ * @param str The input string (e.g., "my_function" or "myFunction")
13
+ * @returns PascalCase string (e.g., "MyFunction")
14
+ */
15
+ export declare function toPascalCaseLocal(str: string): string;
16
+ /**
17
+ * Result of generating an async task class.
18
+ */
19
+ export interface AsyncTaskClassResult {
20
+ /** The class definition as a string */
21
+ classDef: string;
22
+ /** The instance declaration (e.g., "blinkTask blinkTask;") */
23
+ instanceDecl: string;
24
+ /** The task variable name for use in loop() */
25
+ taskVarName: string;
26
+ }
27
+ /**
28
+ * Generates a cooperative state-machine class for an async function.
29
+ *
30
+ * Handles two patterns:
31
+ * 1. Cyclic: single `while(true)` body containing `await delay()` calls.
32
+ * 2. Linear: sequential statements with `await delay()` calls.
33
+ *
34
+ * Each `await delay(ms)` call becomes a timed wait state that polls `millis()`.
35
+ *
36
+ * @param fnName The original function name
37
+ * @param fnStatements The function body statements
38
+ * @param strategy The platform strategy for rendering
39
+ * @param knownFunctionReturnTypes Map of function names to their return types
40
+ * @returns The class definition, instance declaration, and task variable name
41
+ */
42
+ export declare function generateAsyncTaskClass(fnName: string, fnStatements: StatementIR[], strategy: PlatformStrategy, knownFunctionReturnTypes: Map<string, string>, renderStatement: (stmt: StatementIR, forHeader: boolean, strategy: PlatformStrategy, pointerVarTypes?: Map<string, string>, calleeTransformer?: (callee: string) => string, knownFunctionReturnTypes?: Map<string, string>) => string): AsyncTaskClassResult;
@@ -0,0 +1,343 @@
1
+ /**
2
+ * Async state machine generation utilities.
3
+ * Handles conversion of async functions to cooperative state machines.
4
+ * Extracted from cpp-emitter.ts
5
+ */
6
+ import { escapeCppStringLiteral } from "../../utils/strings.js";
7
+ /**
8
+ * Converts a string to PascalCase.
9
+ * Used for generating class names from function names.
10
+ *
11
+ * @param str The input string (e.g., "my_function" or "myFunction")
12
+ * @returns PascalCase string (e.g., "MyFunction")
13
+ */
14
+ export function toPascalCaseLocal(str) {
15
+ return str
16
+ .split(/[_\s]+/)
17
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
18
+ .join("");
19
+ }
20
+ /**
21
+ * Generates a cooperative state-machine class for an async function.
22
+ *
23
+ * Handles two patterns:
24
+ * 1. Cyclic: single `while(true)` body containing `await delay()` calls.
25
+ * 2. Linear: sequential statements with `await delay()` calls.
26
+ *
27
+ * Each `await delay(ms)` call becomes a timed wait state that polls `millis()`.
28
+ *
29
+ * @param fnName The original function name
30
+ * @param fnStatements The function body statements
31
+ * @param strategy The platform strategy for rendering
32
+ * @param knownFunctionReturnTypes Map of function names to their return types
33
+ * @returns The class definition, instance declaration, and task variable name
34
+ */
35
+ export function generateAsyncTaskClass(fnName, fnStatements, strategy, knownFunctionReturnTypes, renderStatement) {
36
+ const className = toPascalCaseLocal(fnName) + "Task";
37
+ const instanceName = `${fnName}Task`;
38
+ // Detect whether the body is a single while-loop (cyclic) or linear statements
39
+ let bodyStatements;
40
+ let isCyclic = false;
41
+ if (fnStatements.length === 1 && fnStatements[0].kind === "while") {
42
+ isCyclic = true;
43
+ bodyStatements = fnStatements[0].body;
44
+ }
45
+ else {
46
+ bodyStatements = fnStatements;
47
+ }
48
+ // Split body into segments at each awaited call
49
+ const segments = [];
50
+ let currentPre = [];
51
+ for (const stmt of bodyStatements) {
52
+ if (stmt.kind === "call" && stmt.isAwaited) {
53
+ segments.push({ preStatements: currentPre, awaitedCallee: stmt.callee, awaitedArgs: stmt.args });
54
+ currentPre = [];
55
+ }
56
+ else {
57
+ currentPre.push(stmt);
58
+ }
59
+ }
60
+ // Terminal segment (trailing statements after the last await, or the whole body if no awaits)
61
+ segments.push({ preStatements: currentPre, awaitedArgs: [] });
62
+ const awaitCount = segments.filter((s) => s.awaitedCallee !== undefined).length;
63
+ const stateCount = awaitCount + 1; // STATE_0 … STATE_{awaitCount}; cyclic loops back, linear adds STATE_DONE
64
+ const stateNames = [];
65
+ for (let i = 0; i < stateCount; i++)
66
+ stateNames.push(`STATE_${i}`);
67
+ if (!isCyclic)
68
+ stateNames.push("STATE_DONE");
69
+ // Helper: render a non-await statement as a single C++ line
70
+ const renderStmt = (stmt) => renderStatement(stmt, false, strategy, undefined, undefined, knownFunctionReturnTypes);
71
+ // Collect edge-detection markers from segments
72
+ const edgeInfoMap = new Map();
73
+ const edgeMembers = new Set();
74
+ for (let i = 0; i < segments.length; i++) {
75
+ const seg = segments[i];
76
+ if (seg.awaitedCallee === "__EMIT__" && seg.awaitedArgs.length > 0) {
77
+ const argText = seg.awaitedArgs[0].kind === "string"
78
+ ? seg.awaitedArgs[0].value
79
+ : renderExpression(seg.awaitedArgs[0], strategy);
80
+ const info = parseEdgeMarker(argText);
81
+ if (info) {
82
+ edgeInfoMap.set(i, info);
83
+ edgeMembers.add(`_edgePrev_p${info.pin}`);
84
+ }
85
+ }
86
+ }
87
+ // Collect awaitable-tap markers (await ui.onTap()). args[0] is the node
88
+ // filter: -1 = any tap, >=0 = a specific node index. Each tap-await needs a
89
+ // per-await snapshot of __ui_tap_seq to detect the NEXT bump.
90
+ const tapInfoMap = new Map();
91
+ const tapMembers = new Map(); // member name → segment index
92
+ for (let i = 0; i < segments.length; i++) {
93
+ const seg = segments[i];
94
+ if (seg.awaitedCallee === "__UI_TAP__" && seg.awaitedArgs.length > 0) {
95
+ const nodeArg = seg.awaitedArgs[0];
96
+ const nodeIndex = nodeArg.kind === "number"
97
+ ? nodeArg.value
98
+ : -1;
99
+ const member = `_tapPrev_${i}`;
100
+ tapInfoMap.set(i, { nodeIndex });
101
+ tapMembers.set(member, i);
102
+ }
103
+ }
104
+ const caseLines = [];
105
+ for (let i = 0; i < segments.length; i++) {
106
+ const seg = segments[i];
107
+ const stateName = `STATE_${i}`;
108
+ const isTerminal = seg.awaitedCallee === undefined;
109
+ const body = [];
110
+ const edgeSetup = edgeInfoMap.get(i);
111
+ const edgePoll = i > 0 ? edgeInfoMap.get(i - 1) : undefined;
112
+ const tapSetup = tapInfoMap.get(i);
113
+ const tapPoll = i > 0 ? tapInfoMap.get(i - 1) : undefined;
114
+ if (edgePoll) {
115
+ // Poll state: check pin transition via digitalRead
116
+ const prevVar = `_edgePrev_p${edgePoll.pin}`;
117
+ const cond = edgePoll.edge === "rising"
118
+ ? `${prevVar} == LOW && _cur == HIGH`
119
+ : `${prevVar} == HIGH && _cur == LOW`;
120
+ const fullCond = edgePoll.timeout !== null
121
+ ? `(${cond}) || ${strategy.currentTimeMillis()} >= _waitUntil`
122
+ : cond;
123
+ body.push(` {`);
124
+ body.push(` int _cur = digitalRead(${edgePoll.pin});`);
125
+ body.push(` if (${fullCond}) {`);
126
+ body.push(` ${prevVar} = _cur;`);
127
+ for (const stmt of seg.preStatements)
128
+ body.push(` ${renderStmt(stmt)}`);
129
+ if (edgeSetup) {
130
+ // Next await is also edge detection — set up its pin tracking
131
+ body.push(` _edgePrev_p${edgeSetup.pin} = digitalRead(${edgeSetup.pin});`);
132
+ if (edgeSetup.timeout !== null) {
133
+ body.push(` _waitUntil = ${strategy.currentTimeMillis()} + ${edgeSetup.timeout};`);
134
+ }
135
+ body.push(` _state = STATE_${i + 1};`);
136
+ }
137
+ else if (!isTerminal) {
138
+ const ms = seg.awaitedArgs[0] ? renderExpression(seg.awaitedArgs[0], strategy) : "0";
139
+ body.push(` _waitUntil = ${strategy.currentTimeMillis()} + ${ms};`);
140
+ body.push(` _state = STATE_${i + 1};`);
141
+ }
142
+ else {
143
+ body.push(` _state = ${isCyclic ? "STATE_0" : "STATE_DONE"};`);
144
+ }
145
+ body.push(` } else {`);
146
+ body.push(` ${prevVar} = _cur;`);
147
+ body.push(` }`);
148
+ body.push(` }`);
149
+ }
150
+ else if (edgeSetup) {
151
+ // Setup state: capture initial pin state before polling
152
+ const prevVar = `_edgePrev_p${edgeSetup.pin}`;
153
+ if (i === 0) {
154
+ for (const stmt of seg.preStatements)
155
+ body.push(` ${renderStmt(stmt)}`);
156
+ body.push(` ${prevVar} = digitalRead(${edgeSetup.pin});`);
157
+ if (edgeSetup.timeout !== null) {
158
+ body.push(` _waitUntil = ${strategy.currentTimeMillis()} + ${edgeSetup.timeout};`);
159
+ }
160
+ body.push(` _state = STATE_${i + 1};`);
161
+ }
162
+ else {
163
+ body.push(` if (${strategy.currentTimeMillis()} >= _waitUntil) {`);
164
+ for (const stmt of seg.preStatements)
165
+ body.push(` ${renderStmt(stmt)}`);
166
+ body.push(` ${prevVar} = digitalRead(${edgeSetup.pin});`);
167
+ if (edgeSetup.timeout !== null) {
168
+ body.push(` _waitUntil = ${strategy.currentTimeMillis()} + ${edgeSetup.timeout};`);
169
+ }
170
+ body.push(` _state = STATE_${i + 1};`);
171
+ body.push(` }`);
172
+ }
173
+ }
174
+ else if (tapPoll) {
175
+ // Tap-poll state: a previous segment ended with `await ui.onTap()`.
176
+ // Wait until __ui_tap_seq bumps from the captured snapshot. A per-node
177
+ // await also requires __ui_tap_node to match the awaited node index.
178
+ const prevVar = `_tapPrev_${i - 1}`;
179
+ const nodeFilter = tapPoll.nodeIndex;
180
+ const cond = nodeFilter < 0
181
+ ? `__ui_tap_seq != ${prevVar}`
182
+ : `(__ui_tap_seq != ${prevVar}) && (__ui_tap_node == ${nodeFilter})`;
183
+ body.push(` if (${cond}) {`);
184
+ for (const stmt of seg.preStatements)
185
+ body.push(` ${renderStmt(stmt)}`);
186
+ // What does the NEXT await (ending this segment) look like? Re-derive
187
+ // from the maps via a fresh lookup so TS doesn't narrow edgeSetup away.
188
+ const nextEdge = edgeInfoMap.get(i) ?? null;
189
+ if (tapSetup) {
190
+ // Next await is also a tap — capture its snapshot now.
191
+ body.push(` _tapPrev_${i} = __ui_tap_seq;`);
192
+ body.push(` _state = STATE_${i + 1};`);
193
+ }
194
+ else if (nextEdge) {
195
+ body.push(` _edgePrev_p${nextEdge.pin} = digitalRead(${nextEdge.pin});`);
196
+ if (nextEdge.timeout !== null) {
197
+ body.push(` _waitUntil = ${strategy.currentTimeMillis()} + ${nextEdge.timeout};`);
198
+ }
199
+ body.push(` _state = STATE_${i + 1};`);
200
+ }
201
+ else if (!isTerminal) {
202
+ // Next await is a normal timed wait (delay) — arm its deadline.
203
+ const ms = seg.awaitedArgs[0] ? renderExpression(seg.awaitedArgs[0], strategy) : "0";
204
+ body.push(` _waitUntil = ${strategy.currentTimeMillis()} + ${ms};`);
205
+ body.push(` _state = STATE_${i + 1};`);
206
+ }
207
+ else {
208
+ body.push(` _state = ${isCyclic ? "STATE_0" : "STATE_DONE"};`);
209
+ }
210
+ body.push(` }`);
211
+ }
212
+ else if (tapSetup && !edgePoll) {
213
+ // Tap-setup state: this segment ends with `await ui.onTap()`. Capture the
214
+ // current tap counter so the poll state can detect the NEXT bump.
215
+ // (edgePoll takes precedence when the previous await was an edge.)
216
+ if (i === 0) {
217
+ for (const stmt of seg.preStatements)
218
+ body.push(` ${renderStmt(stmt)}`);
219
+ body.push(` _tapPrev_${i} = __ui_tap_seq;`);
220
+ body.push(` _state = STATE_${i + 1};`);
221
+ }
222
+ else {
223
+ body.push(` if (${strategy.currentTimeMillis()} >= _waitUntil) {`);
224
+ for (const stmt of seg.preStatements)
225
+ body.push(` ${renderStmt(stmt)}`);
226
+ body.push(` _tapPrev_${i} = __ui_tap_seq;`);
227
+ body.push(` _state = STATE_${i + 1};`);
228
+ body.push(` }`);
229
+ }
230
+ }
231
+ else {
232
+ // Normal timed-wait state
233
+ if (i === 0) {
234
+ for (const stmt of seg.preStatements)
235
+ body.push(` ${renderStmt(stmt)}`);
236
+ if (!isTerminal) {
237
+ const ms = seg.awaitedArgs[0] ? renderExpression(seg.awaitedArgs[0], strategy) : "0";
238
+ body.push(` _waitUntil = ${strategy.currentTimeMillis()} + ${ms};`);
239
+ body.push(` _state = STATE_${i + 1};`);
240
+ }
241
+ else {
242
+ body.push(` _state = ${isCyclic ? "STATE_0" : "STATE_DONE"};`);
243
+ }
244
+ }
245
+ else {
246
+ body.push(` if (${strategy.currentTimeMillis()} >= _waitUntil) {`);
247
+ for (const stmt of seg.preStatements)
248
+ body.push(` ${renderStmt(stmt)}`);
249
+ if (!isTerminal) {
250
+ const ms = seg.awaitedArgs[0] ? renderExpression(seg.awaitedArgs[0], strategy) : "0";
251
+ body.push(` _waitUntil = ${strategy.currentTimeMillis()} + ${ms};`);
252
+ body.push(` _state = STATE_${i + 1};`);
253
+ }
254
+ else {
255
+ body.push(` _state = ${isCyclic ? "STATE_0" : "STATE_DONE"};`);
256
+ }
257
+ body.push(` }`);
258
+ }
259
+ }
260
+ caseLines.push(` case ${stateName}:`, ` {`, ...body, ` }`, ` break;`);
261
+ }
262
+ if (!isCyclic)
263
+ caseLines.push(` case STATE_DONE:`, ` break;`);
264
+ const stateEnumList = stateNames.join(", ");
265
+ const isCompleteExpr = isCyclic ? "false" : "_state == STATE_DONE";
266
+ // Build constructor initializer list and edge/tap member declarations
267
+ const edgeMemberArr = Array.from(edgeMembers);
268
+ const tapMemberArr = Array.from(tapMembers.keys());
269
+ const inits = [`_state(STATE_0)`, `_waitUntil(0)`];
270
+ for (const m of edgeMemberArr)
271
+ inits.push(`${m}(LOW)`);
272
+ for (const m of tapMemberArr)
273
+ inits.push(`${m}(0)`);
274
+ const ctorInitList = inits.join(", ");
275
+ const edgeResetList = edgeMemberArr.map(m => ` ${m} = LOW;`).join("");
276
+ const tapResetList = tapMemberArr.map(m => ` ${m} = 0;`).join("");
277
+ const edgeMemberDecls = edgeMemberArr.map(m => ` int ${m};`);
278
+ // __ui_tap_seq is uint32_t; the snapshot must match to detect bumps correctly.
279
+ const tapMemberDecls = tapMemberArr.map(m => ` uint32_t ${m};`);
280
+ const classDef = [
281
+ `// Async state machine for ${fnName}`,
282
+ `class ${className} {`,
283
+ `public:`,
284
+ ` enum State { ${stateEnumList} };`,
285
+ ` ${className}() : ${ctorInitList} {}`,
286
+ ` void run() {`,
287
+ ` switch (_state) {`,
288
+ ...caseLines,
289
+ ` }`,
290
+ ` }`,
291
+ ` bool isComplete() const { return ${isCompleteExpr}; }`,
292
+ ` void reset() { _state = STATE_0; _waitUntil = 0;${edgeResetList}${tapResetList} }`,
293
+ `private:`,
294
+ ` State _state;`,
295
+ ` unsigned long _waitUntil;`,
296
+ ...edgeMemberDecls,
297
+ ...tapMemberDecls,
298
+ `};`,
299
+ ].join("\n");
300
+ return { classDef, instanceDecl: `${className} ${instanceName};`, taskVarName: instanceName };
301
+ }
302
+ /**
303
+ * Renders an expression to a string (simplified version for async state machine).
304
+ * This is a minimal implementation - full rendering should use ExpressionRenderer.
305
+ */
306
+ function renderExpression(expr, strategy) {
307
+ switch (expr.kind) {
308
+ case "number": {
309
+ if (expr.cppType === "float" || expr.cppType === "double" || !Number.isInteger(expr.value)) {
310
+ const str = `${expr.value}`;
311
+ return str.includes('.') || str.includes('e') || str.includes('E')
312
+ ? `${str}f`
313
+ : `${str}.0f`;
314
+ }
315
+ return `${expr.value}`;
316
+ }
317
+ case "string":
318
+ // Shared escaper — see render-expr.ts / expression-renderer.ts (demo #29
319
+ // Finding A family). The prior quote-only escape emitted a raw control
320
+ // char inside the C++ string literal for any `\n`/`\t`/`\\` value.
321
+ return `"${escapeCppStringLiteral(expr.value)}"`;
322
+ case "boolean":
323
+ return expr.value ? "true" : "false";
324
+ case "identifier":
325
+ return expr.value;
326
+ case "raw":
327
+ return expr.value;
328
+ case "hal-expr":
329
+ return `/* hal-expr: ${expr.operation.operation} */`;
330
+ default:
331
+ return "/* complex expr */";
332
+ }
333
+ }
334
+ function parseEdgeMarker(argText) {
335
+ const match = argText.match(/^__EDGE_(RISING|FALLING)__([a-zA-Z0-9_]+)__T(.*)$/);
336
+ if (!match)
337
+ return null;
338
+ const edge = match[1] === "RISING" ? "rising" : "falling";
339
+ const pin = match[2];
340
+ const timeoutStr = match[3];
341
+ const timeout = !isNaN(Number(timeoutStr)) && Number(timeoutStr) > 0 ? Number(timeoutStr) : null;
342
+ return { pin, edge, timeout };
343
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Comment handling utilities for C++ code emission.
3
+ * Extracted from cpp-emitter.ts
4
+ */
5
+ /**
6
+ * Normalizes a comment string into an array of trimmed lines.
7
+ * Removes empty lines and trailing whitespace.
8
+ *
9
+ * @param comment The comment string (may contain newlines)
10
+ * @returns Array of normalized comment lines
11
+ */
12
+ export declare function normalizeComment(comment: string): string[];
13
+ /**
14
+ * Emits comment lines with proper indentation.
15
+ *
16
+ * @param comments Optional array of comment strings to emit
17
+ * @param indent The indentation string to prepend to each line
18
+ * @param appendLine Function to call for each output line
19
+ */
20
+ export declare function emitCommentLines(comments: string[] | undefined, indent: string, appendLine: (line: string) => void): void;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Comment handling utilities for C++ code emission.
3
+ * Extracted from cpp-emitter.ts
4
+ */
5
+ /**
6
+ * Normalizes a comment string into an array of trimmed lines.
7
+ * Removes empty lines and trailing whitespace.
8
+ *
9
+ * @param comment The comment string (may contain newlines)
10
+ * @returns Array of normalized comment lines
11
+ */
12
+ export function normalizeComment(comment) {
13
+ return comment
14
+ .split(/\r?\n/)
15
+ .map((line) => line.trimEnd())
16
+ .filter((line) => line.length > 0);
17
+ }
18
+ /**
19
+ * Emits comment lines with proper indentation.
20
+ *
21
+ * @param comments Optional array of comment strings to emit
22
+ * @param indent The indentation string to prepend to each line
23
+ * @param appendLine Function to call for each output line
24
+ */
25
+ export function emitCommentLines(comments, indent, appendLine) {
26
+ for (const comment of comments ?? []) {
27
+ for (const line of normalizeComment(comment)) {
28
+ appendLine(`${indent}${line}`);
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,47 @@
1
+ export declare function accessorGetterName(prop: string): string;
2
+ export declare function accessorSetterName(prop: string): string;
3
+ /**
4
+ * Matches a C++ INTEGRAL scalar type (the enum↔integral storage boundary in
5
+ * SUPPORT_MATRIX §1.7). Used by the enum-storage cast sites to decide whether
6
+ * a value/target is on the integral side of an `enum class` boundary that
7
+ * needs a `static_cast`. Covers the signed/unsigned `char`/`short`/`int`/
8
+ * `long` spellings, the fixed-width `<cstdint>` aliases, `size_t`, and `bool`
9
+ * (bool participates: `Cell c = someBool` is the same boundary). Anchored so
10
+ * it does not match container/pointer spellings (`std::vector<...>` etc.).
11
+ *
12
+ * Single source of truth — emit sites route through this instead of each
13
+ * keeping their own inline regex (the prior `isNumericTarget` regex in
14
+ * statement-renderer was one such divergent copy). Demo #32 Finding A.
15
+ */
16
+ export declare const INTEGRAL_CPP_TYPE_RE: RegExp;
17
+ /**
18
+ * Resolve the actual numeric value of every member in a numeric enum, applying
19
+ * the TS/C++ auto-increment rule: an explicit value sets the counter, members
20
+ * without one get the current counter then increment. Mirrors the per-member
21
+ * logic the three emit sites use when emitting `= <value>`.
22
+ */
23
+ export declare function resolveEnumValues(members: ReadonlyArray<{
24
+ value?: number | string;
25
+ }>): number[];
26
+ /**
27
+ * Compute the narrowest C++ underlying type for a numeric `enum class`, given
28
+ * the resolved member values. Returns the `: <type>` suffix string (or `""`
29
+ * for the default `int`).
30
+ *
31
+ * The transpiler knows the full, closed value range of every enum at emit
32
+ * time — something g++ cannot recover. Picking the narrowest type halves
33
+ * storage for small enums on AVR (`enum class X` defaults to `int` = 2 bytes;
34
+ * `enum class X : uint8_t` = 1 byte), which matters for state-machine fields,
35
+ * opcodes, and pin-role arrays common on small-RAM targets.
36
+ *
37
+ * Narrowing is strictly safe: the values provably fit, and `enum class`
38
+ * underlying-type specification is standard C++11. Widening to `: long` still
39
+ * applies when a value exceeds the default-int range on targets where
40
+ * `needsLargeEnumUnderlying` is true (AVR's 16-bit `int`).
41
+ *
42
+ * @param values The resolved numeric values of all enum members.
43
+ * @param needsLargeEnumUnderlying Whether the target's `int` is smaller than
44
+ * 32 bits (true on AVR). When true, values outside `[-32768, 32767]` widen
45
+ * to `: long`. When false (32-bit int), no widening is needed.
46
+ */
47
+ export declare function narrowestEnumUnderlying(values: readonly number[], needsLargeEnumUnderlying: boolean): string;
@@ -0,0 +1,85 @@
1
+ export function accessorGetterName(prop) {
2
+ return `get${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
3
+ }
4
+ export function accessorSetterName(prop) {
5
+ return `set${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
6
+ }
7
+ /**
8
+ * Matches a C++ INTEGRAL scalar type (the enum↔integral storage boundary in
9
+ * SUPPORT_MATRIX §1.7). Used by the enum-storage cast sites to decide whether
10
+ * a value/target is on the integral side of an `enum class` boundary that
11
+ * needs a `static_cast`. Covers the signed/unsigned `char`/`short`/`int`/
12
+ * `long` spellings, the fixed-width `<cstdint>` aliases, `size_t`, and `bool`
13
+ * (bool participates: `Cell c = someBool` is the same boundary). Anchored so
14
+ * it does not match container/pointer spellings (`std::vector<...>` etc.).
15
+ *
16
+ * Single source of truth — emit sites route through this instead of each
17
+ * keeping their own inline regex (the prior `isNumericTarget` regex in
18
+ * statement-renderer was one such divergent copy). Demo #32 Finding A.
19
+ */
20
+ export const INTEGRAL_CPP_TYPE_RE = /^(?:unsigned\s+|signed\s+)?(?:bool|char|short|int|long(?:\s+long)?|float|double|u?int(?:8|16|32|64)_t|size_t)$/;
21
+ /**
22
+ * Resolve the actual numeric value of every member in a numeric enum, applying
23
+ * the TS/C++ auto-increment rule: an explicit value sets the counter, members
24
+ * without one get the current counter then increment. Mirrors the per-member
25
+ * logic the three emit sites use when emitting `= <value>`.
26
+ */
27
+ export function resolveEnumValues(members) {
28
+ const values = [];
29
+ let autoValue = 0;
30
+ for (const m of members) {
31
+ if (typeof m.value === "number") {
32
+ values.push(m.value);
33
+ autoValue = m.value + 1;
34
+ }
35
+ else {
36
+ // String-valued member (mixed enum) or auto-increment numeric.
37
+ values.push(autoValue);
38
+ autoValue++;
39
+ }
40
+ }
41
+ return values;
42
+ }
43
+ /**
44
+ * Compute the narrowest C++ underlying type for a numeric `enum class`, given
45
+ * the resolved member values. Returns the `: <type>` suffix string (or `""`
46
+ * for the default `int`).
47
+ *
48
+ * The transpiler knows the full, closed value range of every enum at emit
49
+ * time — something g++ cannot recover. Picking the narrowest type halves
50
+ * storage for small enums on AVR (`enum class X` defaults to `int` = 2 bytes;
51
+ * `enum class X : uint8_t` = 1 byte), which matters for state-machine fields,
52
+ * opcodes, and pin-role arrays common on small-RAM targets.
53
+ *
54
+ * Narrowing is strictly safe: the values provably fit, and `enum class`
55
+ * underlying-type specification is standard C++11. Widening to `: long` still
56
+ * applies when a value exceeds the default-int range on targets where
57
+ * `needsLargeEnumUnderlying` is true (AVR's 16-bit `int`).
58
+ *
59
+ * @param values The resolved numeric values of all enum members.
60
+ * @param needsLargeEnumUnderlying Whether the target's `int` is smaller than
61
+ * 32 bits (true on AVR). When true, values outside `[-32768, 32767]` widen
62
+ * to `: long`. When false (32-bit int), no widening is needed.
63
+ */
64
+ export function narrowestEnumUnderlying(values, needsLargeEnumUnderlying) {
65
+ if (values.length === 0)
66
+ return "";
67
+ let min = Infinity;
68
+ let max = -Infinity;
69
+ for (const v of values) {
70
+ if (v < min)
71
+ min = v;
72
+ if (v > max)
73
+ max = v;
74
+ }
75
+ // Widen to long first if any value overflows the target's default int range.
76
+ if (needsLargeEnumUnderlying && (max > 32767 || min < -32768)) {
77
+ return " : long";
78
+ }
79
+ // Narrow to the smallest type that fits the full [min, max] range.
80
+ if (min >= 0 && max <= 255)
81
+ return " : uint8_t";
82
+ if (min >= -128 && max <= 127)
83
+ return " : int8_t";
84
+ return "";
85
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Include resolution utilities for C++ code emission.
3
+ * Handles import resolution, SDK detection, and header normalization.
4
+ * Extracted from cpp-emitter.ts
5
+ */
6
+ import type { ResolvedNpmPackage } from "../../transpile/resolution.js";
7
+ /**
8
+ * Checks if a module specifier resolves to a TypeCAD SDK path.
9
+ * Cuttlefish SDK files (code/core/*, code/board-*, @typecad/* packages) are
10
+ * type-level only and should produce no C++ output or #include directives.
11
+ *
12
+ * @param moduleSpecifier The import specifier (e.g., "@typecad/hal" or "./pins")
13
+ * @param fromFile The file path from which the import originates
14
+ * @returns true if this is a TypeCAD SDK import
15
+ */
16
+ export declare function isCuttlefishSDKImport(moduleSpecifier: string, fromFile: string): boolean;
17
+ /**
18
+ * Normalizes an include path to proper C++ include format.
19
+ *
20
+ * @param include The include path (e.g., "Arduino.h" or "<vector>")
21
+ * @returns Properly formatted include (e.g., "<Arduino.h>" or "<vector>")
22
+ */
23
+ export declare function normalizeInclude(include: string): string;
24
+ /**
25
+ * Deduplicates an array while preserving order.
26
+ *
27
+ * @param items The array to deduplicate
28
+ * @returns A new array with duplicates removed
29
+ */
30
+ export declare function dedupe<T>(items: T[]): T[];
31
+ /**
32
+ * Result of resolving a transpiled module include.
33
+ */
34
+ interface TranspiledIncludeResult {
35
+ /** The include path (e.g., "\"./pins.h\"") or empty string if not transpiled */
36
+ include: string;
37
+ /** Whether this import was resolved as a transpiled npm package */
38
+ isTranspiled: boolean;
39
+ }
40
+ /**
41
+ * Resolves an import to a local header file if it's from a transpiled npm package.
42
+ *
43
+ * @param moduleSpecifier The import specifier
44
+ * @param npmPackages Map of source paths to npm package info
45
+ * @param fromFilePath The file path from which the import originates
46
+ * @returns Information about the resolved include
47
+ */
48
+ export declare function resolveTranspiledModuleInclude(moduleSpecifier: string, npmPackages: Map<string, ResolvedNpmPackage> | undefined, fromFilePath: string): TranspiledIncludeResult;
49
+ /**
50
+ * Applies a symbol map to a callee string.
51
+ * Transforms root identifiers according to the mapping.
52
+ *
53
+ * @param callee The original callee (e.g., "console.log" or "myFunc")
54
+ * @param symbolMap Map of original names to transformed names
55
+ * @returns The transformed callee
56
+ */
57
+ export declare function applySymbolMap(callee: string, symbolMap: Record<string, string>): string;
58
+ export {};