@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.
- package/README.md +82 -79
- package/assets/editor-extensions/typecad-debug/README.md +141 -0
- package/assets/editor-extensions/typecad-debug/out/extension.js +347 -0
- package/assets/editor-extensions/typecad-debug/out/extension.js.map +1 -0
- package/assets/editor-extensions/typecad-debug/package.json +76 -0
- package/assets/editor-extensions/typecad-ui/LICENSE +27 -0
- package/assets/editor-extensions/typecad-ui/README.md +52 -0
- package/assets/editor-extensions/typecad-ui/file-icon-dark.png +0 -0
- package/assets/editor-extensions/typecad-ui/file-icon-light.png +0 -0
- package/assets/editor-extensions/typecad-ui/icon.png +0 -0
- package/assets/editor-extensions/typecad-ui/language-configuration.json +43 -0
- package/assets/editor-extensions/typecad-ui/package.json +54 -0
- package/assets/editor-extensions/typecad-ui/snippets/typecad-ui.json +80 -0
- package/assets/editor-extensions/typecad-ui/syntaxes/markdown-ui.json +45 -0
- package/assets/editor-extensions/typecad-ui/syntaxes/typecad-ui.tmLanguage.json +1269 -0
- package/dist/api/config.d.ts +30 -27
- package/dist/api/schema/types.d.ts +20 -3
- package/dist/api/shared/async-runtime-static.d.ts +1 -1
- package/dist/api/shared/async-runtime-static.js +5 -5
- package/dist/api/shared/async-types.d.ts +3 -2
- package/dist/api/shared/board-catalog.d.ts +2 -0
- package/dist/api/shared/board-catalog.js +6 -0
- package/dist/api/shared/board-resolver.d.ts +4 -7
- package/dist/api/shared/board-resolver.js +2 -1
- package/dist/api/shared/coop-scheduler.d.ts +1 -1
- package/dist/api/shared/coop-scheduler.js +1 -1
- package/dist/api/shared/cpp-type-ir.d.ts +1 -1
- package/dist/api/shared/cpp-type-ir.js +1 -1
- package/dist/api/shared/display-profile.d.ts +1 -1
- package/dist/api/shared/display-profile.js +3 -5
- package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
- package/dist/api/shared/framework-manifest-registry.js +0 -1
- package/dist/api/shared/framework-manifest.d.ts +65 -507
- package/dist/api/shared/framework-manifest.js +6 -11
- package/dist/api/shared/hal-op-ir.d.ts +294 -685
- package/dist/api/shared/hal-op-ir.js +31 -65
- package/dist/api/shared/index.d.ts +0 -4
- package/dist/api/shared/index.js +1 -7
- package/dist/api/shared/ir-core.d.ts +6 -0
- package/dist/api/shared/ir-declarations.d.ts +4 -0
- package/dist/api/shared/ir.d.ts +1 -3
- package/dist/api/shared/platform-strategy.d.ts +14 -37
- package/dist/api/shared/polyfill-helper-registry.js +0 -5
- package/dist/api/shared/polyfill-types.js +0 -27
- package/dist/api/shared/promise-runtime.js +3 -3
- package/dist/api/shared/spdx-licenses.d.ts +12 -10
- package/dist/api/shared/spdx-licenses.js +1 -1
- package/dist/api/shared/toolchain-types.d.ts +1 -1
- package/dist/api/shared/toolchain-types.js +3 -3
- package/dist/api/shared/types.d.ts +0 -3
- package/dist/api/shared/validate-framework-manifest.js +13 -33
- package/dist/board-catalog/dts-reader.d.ts +220 -0
- package/dist/board-catalog/dts-reader.js +1052 -0
- package/dist/board-catalog/index.d.ts +11 -0
- package/dist/board-catalog/index.js +12 -0
- package/dist/board-catalog/pinconfig.d.ts +48 -0
- package/dist/board-catalog/pinconfig.js +263 -0
- package/dist/board-catalog/sdk.d.ts +82 -0
- package/dist/board-catalog/sdk.js +180 -0
- package/dist/board-catalog/store.d.ts +196 -0
- package/dist/board-catalog/store.js +363 -0
- package/dist/board-catalog/types.d.ts +233 -0
- package/dist/board-catalog/types.js +7 -0
- package/dist/board-catalog/walker.d.ts +112 -0
- package/dist/board-catalog/walker.js +1101 -0
- package/dist/cli-utils.d.ts +2 -2
- package/dist/cli-utils.js +5 -5
- package/dist/cli.js +227 -244
- package/dist/config-loader.d.ts +14 -19
- package/dist/config-loader.js +242 -78
- package/dist/config-schema.d.ts +19 -227
- package/dist/config-schema.js +9 -8
- package/dist/contract/board-generator.d.ts +4 -4
- package/dist/contract/board-generator.js +16 -5
- package/dist/contract/contract-parser.d.ts +36 -127
- package/dist/contract/contract-parser.js +76 -0
- package/dist/contract/index.d.ts +1 -1
- package/dist/contract/index.js +70 -21
- package/dist/create/active-board-catalog.d.ts +9 -0
- package/dist/create/active-board-catalog.js +94 -0
- package/dist/create/board-catalog.generated.d.ts +96 -0
- package/dist/create/board-catalog.generated.js +128737 -0
- package/dist/create/board-search.d.ts +23 -0
- package/dist/create/board-search.js +88 -0
- package/dist/create/editor-integration.d.ts +32 -0
- package/dist/create/editor-integration.js +257 -0
- package/dist/create/eslint-rules-template.d.ts +2 -2
- package/dist/create/framework-catalog.d.ts +48 -8
- package/dist/create/framework-catalog.js +58 -44
- package/dist/create/index.d.ts +8 -13
- package/dist/create/index.js +5 -9
- package/dist/create/mcu-target.d.ts +39 -0
- package/dist/create/mcu-target.js +80 -0
- package/dist/create/pack-targets.d.ts +19 -0
- package/dist/create/pack-targets.js +56 -0
- package/dist/create/{init-scaffold.d.ts → scaffold.d.ts} +8 -11
- package/dist/create/{init-scaffold.js → scaffold.js} +28 -87
- package/dist/create/templates.d.ts +51 -0
- package/dist/create/{init-templates.js → templates.js} +135 -116
- package/dist/create/wizard.d.ts +19 -0
- package/dist/create/wizard.js +314 -0
- package/dist/debug/preprocessor.d.ts +5 -0
- package/dist/debug/preprocessor.js +31 -7
- package/dist/diagnostics/diagnostics-report.d.ts +1 -1
- package/dist/diagnostics/diagnostics-report.js +3 -11
- package/dist/diagnostics/json-schema.d.ts +1 -1
- package/dist/diagnostics/md-writer.js +2 -2
- package/dist/diagnostics/mermaid-builder.d.ts +1 -1
- package/dist/diagnostics/mermaid-builder.js +1 -1
- package/dist/emit/cpp-emitter.js +4 -1
- package/dist/emit/emitters/class-emitter.js +32 -4
- package/dist/emit/emitters/emitter-context.d.ts +11 -0
- package/dist/emit/emitters/entrypoint-synthesizer.js +1 -1
- package/dist/emit/emitters/function-emitter-impl.js +33 -17
- package/dist/emit/emitters/output-finalizer.d.ts +7 -0
- package/dist/emit/emitters/output-finalizer.js +31 -23
- package/dist/emit/emitters/setup.js +147 -63
- package/dist/emit/emitters/top-level-prep.js +1 -1
- package/dist/emit/emitters/type-decl-emitter.js +13 -8
- package/dist/emit/emitters/ui-emitter.js +1 -1
- package/dist/emit/expression-renderer.d.ts +3 -3
- package/dist/emit/expression-renderer.js +17 -7
- package/dist/emit/route-hal-op.js +17 -48
- package/dist/emit/snprintf-helpers.d.ts +1 -3
- package/dist/emit/snprintf-helpers.js +1 -39
- package/dist/emit/statement-renderer.d.ts +0 -4
- package/dist/emit/statement-renderer.js +54 -45
- package/dist/emit/utils/async-state-machine.d.ts +16 -9
- package/dist/emit/utils/async-state-machine.js +56 -54
- package/dist/emit/utils/comment-helpers.d.ts +0 -8
- package/dist/emit/utils/comment-helpers.js +1 -1
- package/dist/emit/utils/cpp-helpers.d.ts +2 -2
- package/dist/emit/utils/cpp-helpers.js +2 -2
- package/dist/emit/utils/hal-op-cpp-type.js +4 -6
- package/dist/emit/utils/index.d.ts +3 -3
- package/dist/emit/utils/index.js +3 -3
- package/dist/emit/utils/type-inference.d.ts +1 -29
- package/dist/emit/utils/type-inference.js +0 -75
- package/dist/framework-package.d.ts +3 -0
- package/dist/framework-package.js +23 -6
- package/dist/framework-registry.d.ts +5 -5
- package/dist/frameworks/native/graphics/terminal-preview.d.ts +5 -0
- package/dist/frameworks/native/graphics/terminal-preview.js +33 -0
- package/dist/frameworks/native/index.d.ts +3 -0
- package/dist/frameworks/native/index.js +15 -0
- package/dist/frameworks/native/native-compile.d.ts +17 -0
- package/dist/frameworks/native/native-compile.js +170 -0
- package/dist/frameworks/native/native-config.d.ts +41 -0
- package/dist/frameworks/native/native-config.js +7 -0
- package/dist/frameworks/native/strategy.d.ts +97 -0
- package/dist/frameworks/native/strategy.js +664 -0
- package/dist/ir/board-resolver.d.ts +18 -23
- package/dist/ir/board-resolver.js +43 -401
- package/dist/ir/build-ir-state.d.ts +3 -0
- package/dist/ir/build-ir-state.js +42 -0
- package/dist/ir/build-ir.d.ts +1 -1
- package/dist/ir/build-ir.js +64 -45
- package/dist/ir/declaration-builders.js +1 -0
- package/dist/ir/expression-to-ir.js +17 -10
- package/dist/ir/hal/hal-emitter.d.ts +0 -2
- package/dist/ir/hal/hal-emitter.js +92 -41
- package/dist/ir/hal/hal-parser.d.ts +5 -5
- package/dist/ir/hal/hal-parser.js +128 -36
- package/dist/ir/hal/hal-plugins.d.ts +0 -1
- package/dist/ir/hal/hal-plugins.js +425 -716
- package/dist/ir/heap-analysis.js +2 -41
- package/dist/ir/identifier-collector.js +32 -20
- package/dist/ir/network-validation.js +7 -11
- package/dist/ir/ownership-analysis.js +75 -13
- package/dist/ir/peripheral-usage.d.ts +8 -2
- package/dist/ir/peripheral-usage.js +78 -149
- package/dist/ir/peripheral-validation.js +23 -3
- package/dist/ir/pin-capability-validation.d.ts +12 -0
- package/dist/ir/pin-capability-validation.js +61 -97
- package/dist/ir/pin-mode-validation.js +5 -5
- package/dist/ir/program-analysis.d.ts +8 -15
- package/dist/ir/program-analysis.js +140 -323
- package/dist/ir/pulldown-validation.js +11 -4
- package/dist/ir/resource-analysis.js +15 -3
- package/dist/ir/statement-to-ir.js +0 -6
- package/dist/ir/timing-validation.js +1 -1
- package/dist/ir/transformers/array-methods.js +11 -5
- package/dist/ir/transformers/call-statement.js +20 -87
- package/dist/ir/transformers/callback-context-registry.d.ts +1 -1
- package/dist/ir/transformers/callback-context-registry.js +8 -16
- package/dist/ir/transformers/control-flow.js +0 -13
- package/dist/ir/transformers/expressions.js +10 -9
- package/dist/ir/transformers/hal-call-resolver.d.ts +2 -2
- package/dist/ir/transformers/hal-call-resolver.js +24 -10
- package/dist/ir/transformers/hal-emit-helpers.d.ts +2 -2
- package/dist/ir/transformers/hal-emit-helpers.js +2 -2
- package/dist/ir/transformers/namespace-methods.js +1 -1
- package/dist/ir/transformers/ui-callback-lowering.d.ts +0 -2
- package/dist/ir/transformers/ui-callback-lowering.js +0 -24
- package/dist/ir/transformers/variables.js +338 -42
- package/dist/ir/try-catch-validation.js +4 -3
- package/dist/ir/type-resolution.js +15 -4
- package/dist/ir/validation-orchestrator.js +0 -9
- package/dist/libdef/cpp-to-decl.d.ts +0 -9
- package/dist/libdef/cpp-to-decl.js +0 -72
- package/dist/libdef/registry.d.ts +0 -1
- package/dist/libdef/registry.js +1 -24
- package/dist/library/catalog.d.ts +35 -0
- package/dist/library/catalog.js +67 -0
- package/dist/library/cli.d.ts +2 -0
- package/dist/library/cli.js +168 -0
- package/dist/library/init.d.ts +25 -0
- package/dist/library/init.js +397 -0
- package/dist/library/install.d.ts +9 -0
- package/dist/library/install.js +80 -0
- package/dist/library/registry-search.d.ts +34 -0
- package/dist/library/registry-search.js +50 -0
- package/dist/library/validate.d.ts +17 -0
- package/dist/library/validate.js +175 -0
- package/dist/library-packages.d.ts +95 -0
- package/dist/library-packages.js +275 -0
- package/dist/mapping/peripheral-names.js +9 -4
- package/dist/mapping/source-map.d.ts +3 -4
- package/dist/mapping/source-map.js +12 -18
- package/dist/orchestrator/graph-builder.d.ts +3 -3
- package/dist/orchestrator/graph-builder.js +29 -12
- package/dist/orchestrator/type-checker.d.ts +3 -3
- package/dist/orchestrator/type-checker.js +3 -3
- package/dist/platform/async-runtime.js +1 -1
- package/dist/platform/coop-scheduler-runtime.js +2 -2
- package/dist/platform/generic-debug-codegen.d.ts +36 -0
- package/dist/platform/generic-debug-codegen.js +185 -0
- package/dist/platform/generic-strategy.d.ts +3 -4
- package/dist/platform/generic-strategy.js +5 -80
- package/dist/platform/index.js +1 -1
- package/dist/platform/registry.d.ts +2 -2
- package/dist/platform/registry.js +2 -2
- package/dist/preview/client.js +17 -3
- package/dist/safety/asil-decorators.d.ts +32 -0
- package/dist/safety/asil-decorators.js +32 -0
- package/dist/safety/authoring.d.ts +85 -0
- package/dist/safety/authoring.js +61 -0
- package/dist/safety/engine.d.ts +3 -0
- package/dist/safety/engine.js +83 -0
- package/dist/safety/hal/ops.d.ts +48 -0
- package/dist/safety/hal/ops.js +46 -0
- package/dist/safety/iso26262/analyze.d.ts +13 -0
- package/dist/safety/iso26262/analyze.js +29 -0
- package/dist/safety/iso26262/asil.d.ts +10 -0
- package/dist/safety/iso26262/asil.js +22 -0
- package/dist/safety/iso26262/collect.d.ts +14 -0
- package/dist/safety/iso26262/collect.js +137 -0
- package/dist/safety/iso26262/goto-checker.d.ts +10 -0
- package/dist/safety/iso26262/goto-checker.js +72 -0
- package/dist/safety/iso26262/heap-checker.d.ts +7 -0
- package/dist/safety/iso26262/heap-checker.js +57 -0
- package/dist/safety/iso26262/init-checker.d.ts +13 -0
- package/dist/safety/iso26262/init-checker.js +127 -0
- package/dist/safety/iso26262/loop-checker.d.ts +7 -0
- package/dist/safety/iso26262/loop-checker.js +86 -0
- package/dist/safety/iso26262/recursion-checker.d.ts +9 -0
- package/dist/safety/iso26262/recursion-checker.js +134 -0
- package/dist/safety/iso26262/sidecar-writer.d.ts +25 -0
- package/dist/safety/iso26262/sidecar-writer.js +13 -0
- package/dist/safety/passes/pinMode-intercept.d.ts +3 -0
- package/dist/safety/passes/pinMode-intercept.js +60 -0
- package/dist/safety/runtime/mode-table.d.ts +5 -0
- package/dist/safety/runtime/mode-table.js +55 -0
- package/dist/safety/runtime/polyfills.d.ts +6 -0
- package/dist/safety/runtime/polyfills.js +12 -0
- package/dist/safety/runtime/result-struct.d.ts +11 -0
- package/dist/safety/runtime/result-struct.js +98 -0
- package/dist/safety/runtime/safe-int.d.ts +33 -0
- package/dist/safety/runtime/safe-int.js +170 -0
- package/dist/safety/runtime/safe-traits.d.ts +4 -0
- package/dist/safety/runtime/safe-traits.js +95 -0
- package/dist/safety/runtime/safe-variable.d.ts +39 -0
- package/dist/safety/runtime/safe-variable.js +226 -0
- package/dist/safety/runtime/vote.d.ts +8 -0
- package/dist/safety/runtime/vote.js +92 -0
- package/dist/safety/runtime/write-verify.d.ts +8 -0
- package/dist/safety/runtime/write-verify.js +71 -0
- package/dist/safety/safe-int-types.d.ts +45 -0
- package/dist/safety/safe-int-types.js +25 -0
- package/dist/safety/safe-variable-types.d.ts +29 -0
- package/dist/safety/safe-variable-types.js +19 -0
- package/dist/safety/safety-bridge.d.ts +5 -6
- package/dist/safety/safety-bridge.js +15 -28
- package/dist/safety/sidecar-bridge.d.ts +1 -3
- package/dist/safety/sidecar-bridge.js +3 -20
- package/dist/safety/specifiers.d.ts +6 -0
- package/dist/safety/specifiers.js +14 -0
- package/dist/safety-hook.d.ts +8 -7
- package/dist/safety-hook.js +12 -13
- package/dist/testing.d.ts +5 -6
- package/dist/testing.js +5 -5
- package/dist/transpile/resolution.d.ts +1 -1
- package/dist/transpile/resolution.js +18 -9
- package/dist/transpile/test-pins.d.ts +18 -0
- package/dist/transpile/test-pins.js +142 -0
- package/dist/transpile.d.ts +1 -2
- package/dist/transpile.js +90 -29
- package/dist/types.d.ts +45 -26
- package/dist/ui-hook.d.ts +1 -1
- package/dist/utils/cli.d.ts +2 -2
- package/dist/utils/cli.js +160 -157
- package/dist/utils/fs.d.ts +3 -4
- package/dist/utils/fs.js +4 -5
- package/dist/utils/strings.d.ts +0 -1
- package/dist/utils/strings.js +0 -8
- package/dist/utils/ui.d.ts +5 -2
- package/dist/utils/ui.js +13 -3
- package/package.json +158 -149
- package/dist/add-preset.d.ts +0 -4
- package/dist/add-preset.js +0 -74
- package/dist/api/shared/async-symbol-detector.d.ts +0 -11
- package/dist/api/shared/async-symbol-detector.js +0 -140
- package/dist/api/shared/native-display-op-resolver.d.ts +0 -10
- package/dist/api/shared/native-display-op-resolver.js +0 -64
- package/dist/create/board-checklist.d.ts +0 -2
- package/dist/create/board-checklist.js +0 -52
- package/dist/create/board-codegen.d.ts +0 -9
- package/dist/create/board-codegen.js +0 -238
- package/dist/create/board-generators.d.ts +0 -12
- package/dist/create/board-generators.js +0 -651
- package/dist/create/board-spec.d.ts +0 -637
- package/dist/create/board-spec.js +0 -214
- package/dist/create/init-templates.d.ts +0 -28
- package/dist/create/init-wizard.d.ts +0 -8
- package/dist/create/init-wizard.js +0 -182
- package/dist/install/framework-catalog.d.ts +0 -53
- package/dist/install/framework-catalog.js +0 -107
- package/dist/install/handle-install.d.ts +0 -35
- package/dist/install/handle-install.js +0 -177
- package/dist/install/index.d.ts +0 -4
- package/dist/install/index.js +0 -3
- package/dist/ir/pin-state-tracking.d.ts +0 -58
- package/dist/ir/pin-state-tracking.js +0 -182
- package/dist/ir/pwm-timer-sharing.d.ts +0 -4
- package/dist/ir/pwm-timer-sharing.js +0 -94
- package/dist/ir/timer0-pwm-timing-conflict.d.ts +0 -4
- package/dist/ir/timer0-pwm-timing-conflict.js +0 -72
- package/dist/libdef/component-decls.d.ts +0 -2
- package/dist/libdef/component-decls.js +0 -6
- package/dist/libdef/component-discovery.d.ts +0 -43
- package/dist/libdef/component-discovery.js +0 -83
- package/dist/theme-tokens.d.ts +0 -22
- package/dist/theme-tokens.js +0 -172
|
@@ -3,6 +3,8 @@ import ts from "typescript";
|
|
|
3
3
|
import { readText } from "../utils/fs.js";
|
|
4
4
|
import { detectNativeCppModule, getNpmPackageInfoForFile, isInNodeModules, resolveImport, isCuttlefishSDKPath, } from "../transpile/resolution.js";
|
|
5
5
|
import { requireUIHook } from "../ui-hook.js";
|
|
6
|
+
import { isSafetyImportSpecifier } from "../safety/specifiers.js";
|
|
7
|
+
import { registerCuttlefishLibraryFromSpecifier } from "../library-packages.js";
|
|
6
8
|
/**
|
|
7
9
|
* Sort files in dependency order using Kahn's algorithm.
|
|
8
10
|
* Dependencies come before dependents so that include ordering is correct
|
|
@@ -65,10 +67,10 @@ export function topologicalSortFiles(files, dependencies) {
|
|
|
65
67
|
* Also detects native C++ modules (.d.ts + .cpp pairs).
|
|
66
68
|
* Files are returned in dependency order (dependencies before dependents).
|
|
67
69
|
*
|
|
68
|
-
* @param
|
|
69
|
-
*
|
|
70
|
+
* @param boardTarget When provided, `@typecad/board` imports fall back to
|
|
71
|
+
* this package specifier (legacy; generated boards win).
|
|
70
72
|
*/
|
|
71
|
-
export async function collectTranspileGraph(entryFile,
|
|
73
|
+
export async function collectTranspileGraph(entryFile, boardTarget, imageDecodeOpts) {
|
|
72
74
|
const ordered = [];
|
|
73
75
|
const pending = [path.resolve(entryFile)];
|
|
74
76
|
const visited = new Set();
|
|
@@ -125,11 +127,19 @@ export async function collectTranspileGraph(entryFile, boardPackage, imageDecode
|
|
|
125
127
|
}
|
|
126
128
|
if (!moduleSpecifier)
|
|
127
129
|
continue;
|
|
128
|
-
|
|
130
|
+
// Cuttlefish library package: an import whose package ships a
|
|
131
|
+
// cuttlefish.library.json contributes native shims + build fragments
|
|
132
|
+
// instead of transpiling — its own TypeScript types are the contract.
|
|
133
|
+
// Must precede the @typecad/* skips: scoped libraries would otherwise
|
|
134
|
+
// be dropped as "SDK packages" here (the .ui script loop skips ALL
|
|
135
|
+
// @typecad/* specifiers, unlike the selective main-loop skip list).
|
|
136
|
+
if (registerCuttlefishLibraryFromSpecifier(filePath, moduleSpecifier))
|
|
137
|
+
continue;
|
|
138
|
+
if (moduleSpecifier === "@typecad/expect" || moduleSpecifier === "@typecad/ui" || isSafetyImportSpecifier(moduleSpecifier))
|
|
129
139
|
continue;
|
|
130
140
|
if (moduleSpecifier.startsWith("@typecad/"))
|
|
131
141
|
continue;
|
|
132
|
-
const resolved = resolveImport(filePath, moduleSpecifier,
|
|
142
|
+
const resolved = resolveImport(filePath, moduleSpecifier, boardTarget);
|
|
133
143
|
if (!resolved)
|
|
134
144
|
continue;
|
|
135
145
|
if (resolved.uiModule)
|
|
@@ -158,21 +168,28 @@ export async function collectTranspileGraph(entryFile, boardPackage, imageDecode
|
|
|
158
168
|
nativeModules.set(moduleSpecifier, nativeModule);
|
|
159
169
|
continue; // Don't try to resolve as TypeScript
|
|
160
170
|
}
|
|
171
|
+
// Cuttlefish library package: an import whose package ships a
|
|
172
|
+
// cuttlefish.library.json contributes native shims + build fragments
|
|
173
|
+
// instead of transpiling — its own TypeScript types are the contract.
|
|
174
|
+
// Checked before the @typecad/* skips so scoped libraries register.
|
|
175
|
+
if (registerCuttlefishLibraryFromSpecifier(filePath, moduleSpecifier)) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
161
178
|
// Skip @typecad/expect — it provides type-level stubs only.
|
|
162
179
|
// The AST preprocessor rewrites all expect calls before transpilation.
|
|
163
180
|
if (moduleSpecifier === "@typecad/expect") {
|
|
164
181
|
continue;
|
|
165
182
|
}
|
|
166
|
-
// Skip @typecad/ui and
|
|
167
|
-
// authoring stubs only. Their calls (ui.mount/signal/bind,
|
|
168
|
-
// are intercepted at IR-build time and lowered to IR; the
|
|
169
|
-
// themselves must NOT be emitted as C++
|
|
183
|
+
// Skip @typecad/ui and the safety authoring surface — they provide
|
|
184
|
+
// compile-time authoring stubs only. Their calls (ui.mount/signal/bind,
|
|
185
|
+
// safe.read) are intercepted at IR-build time and lowered to IR; the
|
|
186
|
+
// modules themselves must NOT be emitted as C++ (they would synthesize
|
|
170
187
|
// bogus _ui_t / _safe_t structs). All runtime definitions the user code
|
|
171
188
|
// needs (enums, structs, shims) are provided by the safety polyfill.
|
|
172
|
-
if (moduleSpecifier === "@typecad/ui" || moduleSpecifier
|
|
189
|
+
if (moduleSpecifier === "@typecad/ui" || isSafetyImportSpecifier(moduleSpecifier)) {
|
|
173
190
|
continue;
|
|
174
191
|
}
|
|
175
|
-
// Skip @typecad/board,
|
|
192
|
+
// Skip @typecad/board (virtual), the legacy board/mcu package prefixes, @typecad/hal,
|
|
176
193
|
// and @typecad/framework-* — these packages ship src/ for HAL metadata
|
|
177
194
|
// introspection (hal-parser.ts, board-resolver.ts) but their source
|
|
178
195
|
// must NOT be transpiled to C++. The HAL resolver loads class/method
|
|
@@ -189,7 +206,7 @@ export async function collectTranspileGraph(entryFile, boardPackage, imageDecode
|
|
|
189
206
|
|| moduleSpecifier.startsWith("@typecad/framework-")) {
|
|
190
207
|
continue;
|
|
191
208
|
}
|
|
192
|
-
const resolved = resolveImport(filePath, moduleSpecifier,
|
|
209
|
+
const resolved = resolveImport(filePath, moduleSpecifier, boardTarget);
|
|
193
210
|
// .ui.html modules: load into the UI registry, record the path, and don't
|
|
194
211
|
// push onto `pending` (they are never parsed as TypeScript).
|
|
195
212
|
if (resolved?.uiModule) {
|
|
@@ -22,11 +22,11 @@ export interface TypeCheckResult {
|
|
|
22
22
|
* Returns early if any errors are found.
|
|
23
23
|
*
|
|
24
24
|
* @param files List of TypeScript files to type-check
|
|
25
|
-
* @param
|
|
26
|
-
* @param entryFile Entrypoint
|
|
25
|
+
* @param _boardTarget Optional board package for resolving @typecad/board imports
|
|
26
|
+
* @param entryFile Entrypoint source/main file
|
|
27
27
|
* @returns TypeCheckResult with success status and any error messages
|
|
28
28
|
*/
|
|
29
|
-
export declare function typeCheckFiles(files: string[],
|
|
29
|
+
export declare function typeCheckFiles(files: string[], _boardTarget?: string, entryFile?: string): TypeCheckResult;
|
|
30
30
|
/**
|
|
31
31
|
* Run semantic gates against the user files of a type-checked program.
|
|
32
32
|
*
|
|
@@ -10,11 +10,11 @@ import { requireUIHook, hasUIHook } from "../ui-hook.js";
|
|
|
10
10
|
* Returns early if any errors are found.
|
|
11
11
|
*
|
|
12
12
|
* @param files List of TypeScript files to type-check
|
|
13
|
-
* @param
|
|
14
|
-
* @param entryFile Entrypoint
|
|
13
|
+
* @param _boardTarget Optional board package for resolving @typecad/board imports
|
|
14
|
+
* @param entryFile Entrypoint source/main file
|
|
15
15
|
* @returns TypeCheckResult with success status and any error messages
|
|
16
16
|
*/
|
|
17
|
-
export function typeCheckFiles(files,
|
|
17
|
+
export function typeCheckFiles(files, _boardTarget, entryFile) {
|
|
18
18
|
// Find the nearest tsconfig.json by walking up from the entry file (preferred)
|
|
19
19
|
// or the first file in the graph. Using the entry file ensures we pick up the
|
|
20
20
|
// user's tsconfig (with path mappings) rather than a dependency's tsconfig.
|
|
@@ -16,7 +16,7 @@ export function buildAsyncRuntimePolyfill(program, ctx, target, queueCapacity, s
|
|
|
16
16
|
// instead of a millis() token the generic target never defines). When the
|
|
17
17
|
// expression uses std::chrono, the polyfill must carry <chrono> itself —
|
|
18
18
|
// the generic strategy's forcedIncludes are empty by design.
|
|
19
|
-
const now = strategy?.currentTimeMillis?.() ?? "
|
|
19
|
+
const now = strategy?.currentTimeMillis?.() ?? "__tc_now_ms()";
|
|
20
20
|
const requiredIncludes = ["<functional>", "<vector>", "<utility>", "<string>"];
|
|
21
21
|
if (now.includes("std::chrono"))
|
|
22
22
|
requiredIncludes.push("<chrono>");
|
|
@@ -14,14 +14,14 @@ import { generateCoopScheduler } from "../api/shared/index.js";
|
|
|
14
14
|
* links on minimal-libc targets (Zephyr) where the std::function Promise
|
|
15
15
|
* runtime does not.
|
|
16
16
|
*/
|
|
17
|
-
export function buildCoopSchedulerPolyfill(_program, config, currentTimeExpr = "
|
|
17
|
+
export function buildCoopSchedulerPolyfill(_program, config, currentTimeExpr = "__tc_now_ms()") {
|
|
18
18
|
if (!config.enablePriority && !config.enableTimeBudget)
|
|
19
19
|
return null;
|
|
20
20
|
return {
|
|
21
21
|
kind: "polyfill",
|
|
22
22
|
id: "coop_scheduler",
|
|
23
23
|
domain: "embedded",
|
|
24
|
-
// STL-free: only needs a 32-bit unsigned time source (
|
|
24
|
+
// STL-free: only needs a 32-bit unsigned time source (__tc_now_ms() /
|
|
25
25
|
// k_uptime_get_32()) and fixed-width types, both available everywhere.
|
|
26
26
|
requiredIncludes: [],
|
|
27
27
|
forwardDeclarations: [],
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface CapturedVariable {
|
|
2
|
+
name: string;
|
|
3
|
+
isFunction?: boolean;
|
|
4
|
+
/** Coarse C++ type category (inferred by the preprocessor without a checker). */
|
|
5
|
+
cppType?: 'bool' | 'int' | 'long' | 'float' | 'string' | 'unknown';
|
|
6
|
+
}
|
|
7
|
+
export interface LogMessagePart {
|
|
8
|
+
type: 'text' | 'variable';
|
|
9
|
+
value: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Generate the debug-mode banner. The host console needs no setup, but the
|
|
13
|
+
* printf/getchar calls below need <cstdio>: include() registers it on the
|
|
14
|
+
* program (the generic strategy's forcedIncludes is deliberately empty), and
|
|
15
|
+
* the strategy-side usesCstdio gates (e.g. native) also pick the banner up
|
|
16
|
+
* from the rawCpp text.
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateGenericInitCode(): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Generate generic/native code for a breakpoint.
|
|
21
|
+
*
|
|
22
|
+
* The halt reads stdin until ENTER; any 's' typed before it marks this
|
|
23
|
+
* breakpoint skipped for the rest of the run. The flag is a C++ static local
|
|
24
|
+
* inside the emitted block (safe here — unlike TS-injected declarations, the
|
|
25
|
+
* rawCpp text bypasses the TS parser entirely), so the skip persists across
|
|
26
|
+
* loop() iterations. EOF on stdin exits the halt instead of spinning.
|
|
27
|
+
*
|
|
28
|
+
* When `breakpointId` is set the whole block is guarded by that flag; the
|
|
29
|
+
* preprocessor assigns ids to every halting breakpoint.
|
|
30
|
+
*/
|
|
31
|
+
export declare function generateGenericBreakpointCode(fileName: string, lineNum: number, originalLine: string, variables: CapturedVariable[], normalizedCondition: string | undefined, breakpointId?: number): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Generate generic/native code for a logpoint (logs a message without
|
|
34
|
+
* halting). Each part is its own printf, then a newline.
|
|
35
|
+
*/
|
|
36
|
+
export declare function generateGenericLogpointCode(fileName: string, lineNum: number, parts: LogMessagePart[], variables: CapturedVariable[]): string[];
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Generic/native debug code generator — printf-based debug output
|
|
3
|
+
//
|
|
4
|
+
// The debug preprocessor injects these lines into the user's TypeScript, so
|
|
5
|
+
// every injected line must be TS-parseable AND lower faithfully. Raw C++ in
|
|
6
|
+
// an injected line does not survive: the TS parser reads `std::cout << ...`
|
|
7
|
+
// as a label plus garbage, and the emitted C++ was `std: :` noise that could
|
|
8
|
+
// never compile. Every line therefore rides the rawCpp() passthrough — the
|
|
9
|
+
// call lowers to __EMIT__ and its string argument is emitted as verbatim
|
|
10
|
+
// C++ — so the generator can author arbitrary C++ (printf, static_cast,
|
|
11
|
+
// the static skip flag) without the TS parser ever seeing it.
|
|
12
|
+
//
|
|
13
|
+
// printf/getchar need <cstdio>: program-analysis marks usesCstdio from
|
|
14
|
+
// __EMIT__ string arguments, and the native/generic forcedIncludes gate
|
|
15
|
+
// <cstdio> on that flag.
|
|
16
|
+
//
|
|
17
|
+
// Used by GenericStrategy's generateDebug* overrides (the debug preprocessor
|
|
18
|
+
// falls back to GenericStrategy for every framework whose strategy does not
|
|
19
|
+
// define its own codegen — e.g. @typecad/framework-native). The Zephyr
|
|
20
|
+
// counterpart is framework-zephyr/src/debug-codegen.ts (printk + a shim-side
|
|
21
|
+
// halt). Dispatched by cuttlefish/src/debug/preprocessor.ts.
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
import { escapeCppStringLiteral } from "../utils/strings.js";
|
|
24
|
+
/**
|
|
25
|
+
* Wrap a C++ text fragment as an injectable TS statement. The rawCpp() call
|
|
26
|
+
* lowers to __EMIT__, whose string argument the emitter writes out verbatim
|
|
27
|
+
* (a trailing `;` is added by the emitter when the fragment lacks one).
|
|
28
|
+
* JSON.stringify produces a valid single-line TS double-quoted literal for
|
|
29
|
+
* any fragment, newlines included.
|
|
30
|
+
*/
|
|
31
|
+
function raw(cpp) {
|
|
32
|
+
return `rawCpp(${JSON.stringify(cpp)});`;
|
|
33
|
+
}
|
|
34
|
+
/** printf a string literal. */
|
|
35
|
+
function printLiteral(text, indent) {
|
|
36
|
+
return raw(`${indent}printf("%s", "${escapeCppStringLiteral(text)}");`);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Generate the debug-mode banner. The host console needs no setup, but the
|
|
40
|
+
* printf/getchar calls below need <cstdio>: include() registers it on the
|
|
41
|
+
* program (the generic strategy's forcedIncludes is deliberately empty), and
|
|
42
|
+
* the strategy-side usesCstdio gates (e.g. native) also pick the banner up
|
|
43
|
+
* from the rawCpp text.
|
|
44
|
+
*/
|
|
45
|
+
export function generateGenericInitCode() {
|
|
46
|
+
return [
|
|
47
|
+
'// === DEBUG: host console (printf) ===',
|
|
48
|
+
"include('<cstdio>');",
|
|
49
|
+
raw('printf("[TypeCAD] Debug Mode Active\\n");'),
|
|
50
|
+
'// === END DEBUG INIT ===',
|
|
51
|
+
'',
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generate generic/native code for a breakpoint.
|
|
56
|
+
*
|
|
57
|
+
* The halt reads stdin until ENTER; any 's' typed before it marks this
|
|
58
|
+
* breakpoint skipped for the rest of the run. The flag is a C++ static local
|
|
59
|
+
* inside the emitted block (safe here — unlike TS-injected declarations, the
|
|
60
|
+
* rawCpp text bypasses the TS parser entirely), so the skip persists across
|
|
61
|
+
* loop() iterations. EOF on stdin exits the halt instead of spinning.
|
|
62
|
+
*
|
|
63
|
+
* When `breakpointId` is set the whole block is guarded by that flag; the
|
|
64
|
+
* preprocessor assigns ids to every halting breakpoint.
|
|
65
|
+
*/
|
|
66
|
+
export function generateGenericBreakpointCode(fileName, lineNum, originalLine, variables, normalizedCondition, breakpointId) {
|
|
67
|
+
const lines = [];
|
|
68
|
+
const indent = ' ' + (normalizedCondition ? ' ' : '');
|
|
69
|
+
lines.push(` // === BREAKPOINT: ${fileName}:${lineNum} ===`);
|
|
70
|
+
if (normalizedCondition) {
|
|
71
|
+
lines.push(` if (${normalizedCondition}) {`);
|
|
72
|
+
}
|
|
73
|
+
// The whole breakpoint is one rawCpp block: a braced C++ compound
|
|
74
|
+
// statement. The emitter only appends a `;` when the fragment lacks one,
|
|
75
|
+
// so a block ending in `}` is written out verbatim.
|
|
76
|
+
const flag = breakpointId !== undefined ? `__tc_bp${breakpointId}_skipped` : undefined;
|
|
77
|
+
const b = ['{'];
|
|
78
|
+
const inner = flag ? ' ' : '';
|
|
79
|
+
if (flag) {
|
|
80
|
+
b.push(` static bool ${flag} = false;`);
|
|
81
|
+
b.push(` if (!${flag}) {`);
|
|
82
|
+
}
|
|
83
|
+
b.push(`${inner}printf("----------------------------------------\\n");`);
|
|
84
|
+
const headerText = normalizedCondition
|
|
85
|
+
? `[BREAK] ${fileName}:${lineNum} (condition: ${escapeCppStringLiteral(normalizedCondition)})`
|
|
86
|
+
: `[BREAK] ${fileName}:${lineNum}`;
|
|
87
|
+
b.push(`${inner}printf("%s\\n", "${escapeCppStringLiteral(headerText)}");`);
|
|
88
|
+
b.push(`${inner}printf(" %s\\n", "${escapeCppStringLiteral(originalLine)}");`);
|
|
89
|
+
if (variables.length > 0) {
|
|
90
|
+
b.push(`${inner}printf(" Variables:\\n");`);
|
|
91
|
+
for (const v of variables) {
|
|
92
|
+
if (v.isFunction) {
|
|
93
|
+
b.push(`${inner}printf(" - %s = [function]\\n", "${escapeCppStringLiteral(v.name)}");`);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
const { spec, arg } = formatSpecFor(v.name, v.cppType);
|
|
97
|
+
b.push(`${inner}printf(" - %s = ${spec}\\n", "${escapeCppStringLiteral(v.name)}", ${arg});`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
b.push(`${inner}printf(" (no variables in scope)\\n");`);
|
|
103
|
+
}
|
|
104
|
+
b.push(`${inner}printf(" [ENTER: continue | s: skip this breakpoint]\\n");`);
|
|
105
|
+
b.push(`${inner}int __tc_c;`);
|
|
106
|
+
if (flag) {
|
|
107
|
+
b.push(`${inner}do {`);
|
|
108
|
+
b.push(`${inner} __tc_c = getchar();`);
|
|
109
|
+
b.push(`${inner} if (__tc_c == 's') { ${flag} = true; }`);
|
|
110
|
+
b.push(`${inner}} while (__tc_c != '\\n' && __tc_c != EOF);`);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
b.push(`${inner}do {`);
|
|
114
|
+
b.push(`${inner} __tc_c = getchar();`);
|
|
115
|
+
b.push(`${inner}} while (__tc_c != '\\n' && __tc_c != EOF);`);
|
|
116
|
+
}
|
|
117
|
+
if (flag) {
|
|
118
|
+
b.push(' }');
|
|
119
|
+
}
|
|
120
|
+
b.push('}');
|
|
121
|
+
lines.push(indent + raw(b.join('\n')));
|
|
122
|
+
if (normalizedCondition) {
|
|
123
|
+
lines.push(` }`);
|
|
124
|
+
}
|
|
125
|
+
lines.push(` // === END BREAKPOINT ===`);
|
|
126
|
+
return lines;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Generate generic/native code for a logpoint (logs a message without
|
|
130
|
+
* halting). Each part is its own printf, then a newline.
|
|
131
|
+
*/
|
|
132
|
+
export function generateGenericLogpointCode(fileName, lineNum, parts, variables) {
|
|
133
|
+
const lines = [];
|
|
134
|
+
lines.push(` // === LOGPOINT: ${fileName}:${lineNum} ===`);
|
|
135
|
+
lines.push(raw(` printf("%s", "${escapeCppStringLiteral(`[LOG ${fileName}:${lineNum}] `)}");`));
|
|
136
|
+
for (const part of parts) {
|
|
137
|
+
if (part.type === 'text') {
|
|
138
|
+
lines.push(raw(` printf("%s", "${escapeCppStringLiteral(part.value)}");`));
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
// Variable part: only printable if it is a non-function value in scope.
|
|
142
|
+
const match = variables.find((v) => v.name === part.value && !v.isFunction);
|
|
143
|
+
if (match) {
|
|
144
|
+
const { spec, arg } = formatSpecFor(match.name, match.cppType);
|
|
145
|
+
lines.push(raw(` printf("${spec}", ${arg});`));
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
lines.push(raw(` printf("%s", "{${escapeCppStringLiteral(part.value)}}"); // variable not in scope`));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
lines.push(raw(` printf("\\n");`));
|
|
153
|
+
lines.push(` // === END LOGPOINT ===`);
|
|
154
|
+
return lines;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Pick a printf format specifier + argument expression for a debug variable.
|
|
158
|
+
*
|
|
159
|
+
* The debug preprocessor has no TypeChecker, so `cppType` is a coarse
|
|
160
|
+
* category inferred from AST shape. Native/generic mappings:
|
|
161
|
+
* - bool → %d via static_cast<int>
|
|
162
|
+
* - int/long → %lld via static_cast<long long> (native `number` is long
|
|
163
|
+
* long; int32_t widens into the same cast)
|
|
164
|
+
* - float → %g via static_cast<double> (float literal widens)
|
|
165
|
+
* - string → %s via .c_str() (native strings are std::string)
|
|
166
|
+
* - unknown → %g via static_cast<double>, the documented fallback that
|
|
167
|
+
* compiles for any numeric/bool variable.
|
|
168
|
+
*/
|
|
169
|
+
function formatSpecFor(varName, cppType) {
|
|
170
|
+
switch (cppType) {
|
|
171
|
+
case 'bool':
|
|
172
|
+
return { spec: '%d', arg: `static_cast<int>(${varName})` };
|
|
173
|
+
case 'int':
|
|
174
|
+
case 'long':
|
|
175
|
+
return { spec: '%lld', arg: `static_cast<long long>(${varName})` };
|
|
176
|
+
case 'float':
|
|
177
|
+
return { spec: '%g', arg: `static_cast<double>(${varName})` };
|
|
178
|
+
case 'string':
|
|
179
|
+
return { spec: '%s', arg: `${varName}.c_str()` };
|
|
180
|
+
case 'unknown':
|
|
181
|
+
default:
|
|
182
|
+
// Cast to double so printf compiles regardless of the real C++ type.
|
|
183
|
+
return { spec: '%g', arg: `static_cast<double>(${varName})` };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -34,9 +34,6 @@ export declare class GenericStrategy implements PlatformStrategy {
|
|
|
34
34
|
enumCastType(enumName: string): string | undefined;
|
|
35
35
|
renderBoardDefinitionAccess(_chain: string[], _boardConstants?: BoardConstants): string | undefined;
|
|
36
36
|
renderThrow(valueExpr: string): string;
|
|
37
|
-
isConsoleCall(callee: string): boolean;
|
|
38
|
-
transformConsoleCall(method: string, renderedArgs: string, forHeader: boolean): string;
|
|
39
|
-
transformConsoleExpression(method: string, _renderedArgs: string): string | undefined;
|
|
40
37
|
objectFieldInitializer(_fieldValue: ExpressionIR, _renderExpr: (e: ExpressionIR) => string): string | undefined;
|
|
41
38
|
overrideClassFieldType(_fieldName: string, _normalizedType: string): string;
|
|
42
39
|
reservedNames(): ReadonlySet<string>;
|
|
@@ -50,7 +47,6 @@ export declare class GenericStrategy implements PlatformStrategy {
|
|
|
50
47
|
needsStdFunction(): boolean;
|
|
51
48
|
mathHeader(): string;
|
|
52
49
|
cstringHeader(): string;
|
|
53
|
-
needsVectorOverload(): boolean;
|
|
54
50
|
needsLargeEnumUnderlying(): boolean;
|
|
55
51
|
renameStructField(fieldName: string): string;
|
|
56
52
|
structFieldInitializer(_fieldValue: ExpressionIR, _compiletimeVarNames: Set<string>, _renderExpr: (e: ExpressionIR) => string): string | undefined;
|
|
@@ -79,8 +75,10 @@ export declare class GenericStrategy implements PlatformStrategy {
|
|
|
79
75
|
variables: Array<{
|
|
80
76
|
name: string;
|
|
81
77
|
isFunction?: boolean;
|
|
78
|
+
cppType?: 'bool' | 'int' | 'long' | 'float' | 'string' | 'unknown';
|
|
82
79
|
}>;
|
|
83
80
|
normalizedCondition?: string;
|
|
81
|
+
breakpointId?: number;
|
|
84
82
|
}): string[];
|
|
85
83
|
generateDebugLogpointCode(params: {
|
|
86
84
|
fileName: string;
|
|
@@ -92,6 +90,7 @@ export declare class GenericStrategy implements PlatformStrategy {
|
|
|
92
90
|
variables: Array<{
|
|
93
91
|
name: string;
|
|
94
92
|
isFunction?: boolean;
|
|
93
|
+
cppType?: 'bool' | 'int' | 'long' | 'float' | 'string' | 'unknown';
|
|
95
94
|
}>;
|
|
96
95
|
}): string[];
|
|
97
96
|
resolveDisplayOp(_op: DisplayHALOp): {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
|
-
// GenericStrategy — standard C++ target (
|
|
2
|
+
// GenericStrategy — standard C++ target (main(), <cmath> …)
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
|
-
import {
|
|
4
|
+
import { generateGenericInitCode, generateGenericBreakpointCode, generateGenericLogpointCode } from "./generic-debug-codegen.js";
|
|
5
5
|
import { DEFAULT_STDLIB_SUPPORT } from "../api/shared/index.js";
|
|
6
6
|
import { parsedIsPointer } from "../api/shared/cpp-type-ir.js";
|
|
7
7
|
import { buildAsyncRuntimePolyfill } from "./async-runtime.js";
|
|
@@ -105,37 +105,6 @@ export class GenericStrategy {
|
|
|
105
105
|
renderThrow(valueExpr) {
|
|
106
106
|
return `throw ${valueExpr};`;
|
|
107
107
|
}
|
|
108
|
-
isConsoleCall(callee) {
|
|
109
|
-
return callee.startsWith("console.");
|
|
110
|
-
}
|
|
111
|
-
transformConsoleCall(method, renderedArgs, forHeader) {
|
|
112
|
-
const semi = forHeader ? "" : ";";
|
|
113
|
-
switch (method) {
|
|
114
|
-
case "log":
|
|
115
|
-
case "info":
|
|
116
|
-
case "debug":
|
|
117
|
-
return `std::cout << ${renderedArgs} << std::endl${semi}`;
|
|
118
|
-
case "error":
|
|
119
|
-
return `std::cerr << "[ERROR] " << ${renderedArgs} << std::endl${semi}`;
|
|
120
|
-
case "warn":
|
|
121
|
-
return `std::cerr << "[WARN] " << ${renderedArgs} << std::endl${semi}`;
|
|
122
|
-
case "readLine":
|
|
123
|
-
case "readCharacter":
|
|
124
|
-
return this.transformConsoleExpression(method, renderedArgs) + semi;
|
|
125
|
-
default:
|
|
126
|
-
return `std::cout << ${renderedArgs} << std::endl${semi}`;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
transformConsoleExpression(method, _renderedArgs) {
|
|
130
|
-
switch (method) {
|
|
131
|
-
case 'readLine':
|
|
132
|
-
return '([]() -> std::string { std::string s; std::getline(std::cin, s); return s; })()';
|
|
133
|
-
case 'readCharacter':
|
|
134
|
-
return '([&]() -> char { std::cout << "> " << std::flush; return std::cin.get(); })()';
|
|
135
|
-
default:
|
|
136
|
-
return undefined;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
108
|
objectFieldInitializer(_fieldValue, _renderExpr) {
|
|
140
109
|
return undefined;
|
|
141
110
|
}
|
|
@@ -163,7 +132,6 @@ export class GenericStrategy {
|
|
|
163
132
|
needsStdFunction() { return true; }
|
|
164
133
|
mathHeader() { return "<cmath>"; }
|
|
165
134
|
cstringHeader() { return "<cstring>"; }
|
|
166
|
-
needsVectorOverload() { return true; }
|
|
167
135
|
// ── Enum underlying type ────────────────────────────────────────────────
|
|
168
136
|
needsLargeEnumUnderlying() { return false; }
|
|
169
137
|
// ── Struct field handling ───────────────────────────────────────────────
|
|
@@ -227,56 +195,13 @@ export class GenericStrategy {
|
|
|
227
195
|
return 'printf';
|
|
228
196
|
}
|
|
229
197
|
generateDebugInitCode() {
|
|
230
|
-
return
|
|
231
|
-
'// === DEBUG: Initialize ===',
|
|
232
|
-
'std::cout << "TypeCAD Debug Mode Active" << std::endl;',
|
|
233
|
-
'// === END DEBUG INIT ===',
|
|
234
|
-
'',
|
|
235
|
-
];
|
|
198
|
+
return generateGenericInitCode();
|
|
236
199
|
}
|
|
237
200
|
generateDebugBreakpointCode(params) {
|
|
238
|
-
|
|
239
|
-
lines.push(` // === BREAKPOINT: ${params.fileName}:${params.lineNum} ===`);
|
|
240
|
-
if (params.normalizedCondition) {
|
|
241
|
-
lines.push(` if (${params.normalizedCondition}) {`);
|
|
242
|
-
}
|
|
243
|
-
lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;`);
|
|
244
|
-
lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << "BREAKPOINT: ${params.fileName}:${params.lineNum}" << std::endl;`);
|
|
245
|
-
lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << " ${params.originalLine.replace(/"/g, '\\"')}" << std::endl;`);
|
|
246
|
-
if (params.variables.length > 0) {
|
|
247
|
-
lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << " Variables:" << std::endl;`);
|
|
248
|
-
for (const v of params.variables) {
|
|
249
|
-
if (v.isFunction) {
|
|
250
|
-
lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << " ${v.name} = [function]" << std::endl;`);
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << " ${v.name} = " << ${v.name} << std::endl;`);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;`);
|
|
258
|
-
if (params.normalizedCondition) {
|
|
259
|
-
lines.push(` }`);
|
|
260
|
-
}
|
|
261
|
-
lines.push(` // === END BREAKPOINT ===`);
|
|
262
|
-
return lines;
|
|
201
|
+
return generateGenericBreakpointCode(params.fileName, params.lineNum, params.originalLine, params.variables, params.normalizedCondition, params.breakpointId);
|
|
263
202
|
}
|
|
264
203
|
generateDebugLogpointCode(params) {
|
|
265
|
-
|
|
266
|
-
lines.push(` // === LOGPOINT: ${params.fileName}:${params.lineNum} ===`);
|
|
267
|
-
const parts = [`"[LOG ${params.fileName}:${params.lineNum}] "`];
|
|
268
|
-
for (const part of params.parts) {
|
|
269
|
-
if (part.type === 'text') {
|
|
270
|
-
parts.push(`"${escapeCppStringLiteral(part.value)}"`);
|
|
271
|
-
}
|
|
272
|
-
else {
|
|
273
|
-
const varExists = params.variables.some(v => v.name === part.value && !v.isFunction);
|
|
274
|
-
parts.push(varExists ? part.value : `"${escapeCppStringLiteral(part.value)}"`);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
lines.push(` std::cout << ${parts.join(' << ')} << std::endl;`);
|
|
278
|
-
lines.push(` // === END LOGPOINT ===`);
|
|
279
|
-
return lines;
|
|
204
|
+
return generateGenericLogpointCode(params.fileName, params.lineNum, params.parts, params.variables);
|
|
280
205
|
}
|
|
281
206
|
// ── Graphics (fallback) ────────────────────────────────────────────────
|
|
282
207
|
resolveDisplayOp(_op) {
|
package/dist/platform/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Platform strategy exports
|
|
3
3
|
//
|
|
4
4
|
// Re-exports platform strategies for use within the CLI and by consumers.
|
|
5
|
-
// Framework-specific strategies (e.g.
|
|
5
|
+
// Framework-specific strategies (e.g. ZephyrStrategy) are provided by their
|
|
6
6
|
// respective framework packages, which register via registerPlatformStrategy().
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
export { GenericStrategy } from './generic-strategy.js';
|
|
@@ -4,9 +4,9 @@ import type { PlatformStrategy } from "../api/shared/index.js";
|
|
|
4
4
|
* their entry point to override the default strategy for a target.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
|
-
* // In @typecad/framework-
|
|
7
|
+
* // In @typecad/framework-zephyr
|
|
8
8
|
* import { registerPlatformStrategy } from "@typecad/cuttlefish/platform/registry";
|
|
9
|
-
* registerPlatformStrategy(new
|
|
9
|
+
* registerPlatformStrategy(new ZephyrStrategy());
|
|
10
10
|
*/
|
|
11
11
|
export declare function registerPlatformStrategy(strategy: PlatformStrategy): void;
|
|
12
12
|
/**
|
|
@@ -15,9 +15,9 @@ const _registry = new Map([
|
|
|
15
15
|
* their entry point to override the default strategy for a target.
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
|
-
* // In @typecad/framework-
|
|
18
|
+
* // In @typecad/framework-zephyr
|
|
19
19
|
* import { registerPlatformStrategy } from "@typecad/cuttlefish/platform/registry";
|
|
20
|
-
* registerPlatformStrategy(new
|
|
20
|
+
* registerPlatformStrategy(new ZephyrStrategy());
|
|
21
21
|
*/
|
|
22
22
|
export function registerPlatformStrategy(strategy) {
|
|
23
23
|
_registry.set(strategy.id, strategy);
|
package/dist/preview/client.js
CHANGED
|
@@ -8,6 +8,9 @@ let pendingPointerFrame = 0;
|
|
|
8
8
|
let debugModes = { boxes: false, clips: false, dirty: false, inspect: false };
|
|
9
9
|
let debugOverlay;
|
|
10
10
|
let debugCtx;
|
|
11
|
+
/** Re-syncs the overlay to the app canvas whenever layout changes its box
|
|
12
|
+
* (aspect-ratio application, max-height, container reflow). */
|
|
13
|
+
let overlayResizeObserver;
|
|
11
14
|
let dirtyFlashAlpha = 0;
|
|
12
15
|
/** CSS px per logical display px — the overlay backing store runs at this
|
|
13
16
|
* resolution so debug strokes are 1 CSS px thin (a 1-logical-px stroke on
|
|
@@ -263,11 +266,22 @@ async function start() {
|
|
|
263
266
|
debugOverlay.height = Math.max(1, Math.round(rect.height * dpr));
|
|
264
267
|
debugScale = (rect.width * dpr) / snapshot.program.width;
|
|
265
268
|
};
|
|
266
|
-
syncOverlayBox();
|
|
267
|
-
window.addEventListener("resize", syncOverlayBox);
|
|
268
269
|
// Set the canvas CSS aspect-ratio to match the display (e.g. 128:64 for
|
|
269
|
-
// OLED, 320:240 for TFT)
|
|
270
|
+
// OLED, 320:240 for TFT) BEFORE syncing the overlay: the canvas is
|
|
271
|
+
// vertically centered (place-items: center), so applying the real aspect
|
|
272
|
+
// after the sync SHRANK it and moved it DOWN — the overlay stayed at the
|
|
273
|
+
// old 4/3-fallback position and every debug box sat that far above its
|
|
274
|
+
// element. A ResizeObserver re-syncs on any later layout-driven size
|
|
275
|
+
// change (max-height kicking in, container reflow), not just window
|
|
276
|
+
// resizes.
|
|
270
277
|
document.documentElement.style.setProperty("--display-aspect", `${snapshot.program.width} / ${snapshot.program.height}`);
|
|
278
|
+
syncOverlayBox();
|
|
279
|
+
window.addEventListener("resize", syncOverlayBox);
|
|
280
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
281
|
+
overlayResizeObserver?.disconnect();
|
|
282
|
+
overlayResizeObserver = new ResizeObserver(() => syncOverlayBox());
|
|
283
|
+
overlayResizeObserver.observe(canvas);
|
|
284
|
+
}
|
|
271
285
|
const status = byId("status");
|
|
272
286
|
status.textContent = `${snapshot.profileName ?? snapshot.program.display?.driver ?? "display"} ${snapshot.program.width}x${snapshot.program.height} ${snapshot.program.colorFormat}`;
|
|
273
287
|
const extraDiagnostics = [];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
/** ASIL level annotations for functions — comment-based.
|
|
3
|
+
*
|
|
4
|
+
* ASIL levels are declared via leading comment annotations rather than
|
|
5
|
+
* TypeScript decorators because:
|
|
6
|
+
* - TS decorators on function declarations produce TS1206 errors in the
|
|
7
|
+
* VS Code language server and @typescript-eslint/parser
|
|
8
|
+
* - Comment annotations work in any editor, any toolchain, without
|
|
9
|
+
* `experimentalDecorators` or special config
|
|
10
|
+
*
|
|
11
|
+
* The cuttlefish IR builder extracts these from leading comments via
|
|
12
|
+
* extractAsilFromComments() in function-builder.ts.
|
|
13
|
+
*
|
|
14
|
+
* Part B's ISO 26262 checkers (analyzeIR) read the resulting `decorators`
|
|
15
|
+
* field on FunctionIR to decide which rules to enforce:
|
|
16
|
+
*
|
|
17
|
+
* // @asilD → all rules enforced (recursion, heap, loops)
|
|
18
|
+
* // @asilC → recursion + loops enforced (heap is ASIL D only)
|
|
19
|
+
* // @asilB → recursion enforced
|
|
20
|
+
* // @asilA → no rules enforced (quality-managed)
|
|
21
|
+
* (no annotation) → no rules enforced (implicit QM)
|
|
22
|
+
*
|
|
23
|
+
* Usage:
|
|
24
|
+
* // @asilD
|
|
25
|
+
* function engageBrake(): void {
|
|
26
|
+
* safe.write(brakePin, 1);
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* These are documentation-only exports — they have no runtime behavior
|
|
30
|
+
* and are never imported by user code. They exist so the ASIL level
|
|
31
|
+
* names appear in type hints and IDE autocomplete.
|
|
32
|
+
*/
|